Skip to content

Commit

Permalink
Fluidsynth: Turn off all sound when the music changes
Browse files Browse the repository at this point in the history
Solves an issue that old notes finish fading out when using BGM Stop followed by a BGM Play later.

Fix #3135
  • Loading branch information
Ghabry committed Nov 2, 2023
1 parent f686945 commit 50035a0
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/audio_decoder_midi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ void AudioDecoderMidi::reset() {
midi_msg = midimsg_make(midi_event_control_change, channel, midi_set_reg_param_lower, 0);
mididec->SendMidiMessage(midi_msg);
}

mididec->Reset();
}

void AudioDecoderMidi::reset_tempos_after_loop() {
Expand Down
2 changes: 1 addition & 1 deletion src/audio_midi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ std::unique_ptr<AudioDecoderBase> MidiDecoder::CreateFmMidi(bool resample) {
return mididec;
}

void MidiDecoder::Reset() {
void MidiDecoder::ResetGlobalState() {
works.fluidsynth = true;
works.wildmidi = true;

Expand Down
10 changes: 8 additions & 2 deletions src/audio_midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class MidiDecoder {
*
* The library must implement the following commands:
* - SendMidiMessage
* - SendSysExMessage (nice to have)
* - SendSysExMessage
*
* When Midi messages are not supported (library uses own sequencer)
* - Open
Expand Down Expand Up @@ -166,6 +166,12 @@ class MidiDecoder {
return -1;
};

/**
* Called when the device is reset due to a Midi file change.
* Can be used when the normal reset sequence (GM reset etc.) is not sufficient.
*/
virtual void Reset() {};

/**
* Returns the unique name of the Midi decoder.
*
Expand Down Expand Up @@ -197,7 +203,7 @@ class MidiDecoder {
/**
* Resets the global state of the midi libraries.
*/
static void Reset();
static void ResetGlobalState();

protected:
int frequency = EP_MIDI_FREQ;
Expand Down
9 changes: 9 additions & 0 deletions src/decoder_fluidsynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,15 @@ void FluidSynthDecoder::SendSysExMessage(const uint8_t* data, std::size_t size)
nullptr, nullptr, nullptr, 0);
}

void FluidSynthDecoder::Reset() {
// Prevent that old notes resume playing when BGM is stopped and resumed later
auto* instance_synth = GetSynthInstance();

for (int channel = 0; channel < 16; channel++) {
fluid_synth_all_sounds_off(GetSynthInstance(), channel);
}
}

fluid_synth_t *FluidSynthDecoder::GetSynthInstance() {
if (use_global_synth) {
return global_synth.get();
Expand Down
2 changes: 2 additions & 0 deletions src/decoder_fluidsynth.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class FluidSynthDecoder : public MidiDecoder {

void SendSysExMessage(const uint8_t* data, size_t size) override;

void Reset() override;

std::string GetName() override {
#if defined(HAVE_FLUIDSYNTH)
return "FluidSynth";
Expand Down
2 changes: 1 addition & 1 deletion src/scene_gamebrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void Scene_GameBrowser::Continue(SceneType /* prev_scene */) {

Cache::ClearAll();
AudioSeCache::Clear();
MidiDecoder::Reset();
MidiDecoder::ResetGlobalState();
lcf::Data::Clear();
Main_Data::Cleanup();

Expand Down

0 comments on commit 50035a0

Please sign in to comment.