diff --git a/fluidsynth/src/synth/fluid_synth.c b/fluidsynth/src/synth/fluid_synth.c index a81a0dda..c44baf88 100644 --- a/fluidsynth/src/synth/fluid_synth.c +++ b/fluidsynth/src/synth/fluid_synth.c @@ -797,8 +797,18 @@ delete_fluid_synth(fluid_synth_t* synth) continue; fluid_voice_unlock_rvoice(voice); fluid_voice_overflow_rvoice_finished(voice); - if (fluid_voice_is_playing(voice)) - fluid_voice_off(voice); + if (fluid_voice_is_playing(voice)) { + fluid_voice_off(voice); + /* If we only use fluid_voice_off(voice) it will trigger a delayed + * fluid_voice_stop(voice) via fluid_synth_check_finished_voices(). + * But here, we are deleting the fluid_synth_t instance so + * fluid_voice_stop() will be never triggered resulting in + * SoundFont data never unloaded (i.e a serious memory leak). + * So, fluid_voice_stop() must be explicitly called to insure + * unloading SoundFont data + */ + fluid_voice_stop(voice); + } } } @@ -2896,7 +2906,7 @@ fluid_synth_check_finished_voices(fluid_synth_t* synth) for (j=0; j < synth->polyphony; j++) { if (synth->voice[j]->rvoice == fv) { fluid_voice_unlock_rvoice(synth->voice[j]); - fluid_voice_off(synth->voice[j]); + fluid_voice_stop(synth->voice[j]); break; } else if (synth->voice[j]->overflow_rvoice == fv) { diff --git a/fluidsynth/src/synth/fluid_voice.c b/fluidsynth/src/synth/fluid_voice.c index 58c74abe..625b376d 100644 --- a/fluidsynth/src/synth/fluid_voice.c +++ b/fluidsynth/src/synth/fluid_voice.c @@ -1292,21 +1292,30 @@ void fluid_voice_overflow_rvoice_finished(fluid_voice_t* voice) fluid_sample_null_ptr(&voice->overflow_rvoice->dsp.sample); } - /* * fluid_voice_off + * + * Force the voice into finished stage. Useful anywhere a voice + * needs to be cancelled from MIDI API. + */ +void fluid_voice_off(fluid_voice_t* voice) +{ + UPDATE_RVOICE0(fluid_rvoice_voiceoff); /* request to finish the voice */ +} + +/* + * fluid_voice_stop * * Purpose: - * Turns off a voice, meaning that it is not processed - * anymore by the DSP loop. + * Turns off a voice, meaning that it is not processed anymore by the + * DSP loop, i.e. contrary part to fluid_voice_start(). */ -int -fluid_voice_off(fluid_voice_t* voice) +void +fluid_voice_stop(fluid_voice_t* voice) { fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref); voice->chan = NO_CHANNEL; - UPDATE_RVOICE0(fluid_rvoice_voiceoff); if (voice->can_access_rvoice) fluid_sample_null_ptr(&voice->rvoice->dsp.sample); @@ -1319,8 +1328,6 @@ fluid_voice_off(fluid_voice_t* voice) /* Decrement voice count */ voice->channel->synth->active_voice_count--; - - return FLUID_OK; } /** diff --git a/fluidsynth/src/synth/fluid_voice.h b/fluidsynth/src/synth/fluid_voice.h index a909f47c..81fd91c3 100644 --- a/fluidsynth/src/synth/fluid_voice.h +++ b/fluidsynth/src/synth/fluid_voice.h @@ -143,15 +143,10 @@ int fluid_voice_set_output_rate(fluid_voice_t* voice, fluid_real_t value); function.*/ void fluid_voice_update_param(fluid_voice_t* voice, int gen); -/** fluid_voice_release - Force the voice into release stage. Usefuf anywhere a voice - needs to be damped even if pedals (sustain sostenuto) are depressed. - See fluid_synth_damp_voices_LOCAL(), fluid_synth_damp_voices_by_sostenuto_LOCAL, - fluid_voice_noteoff(), fluid_synth_stop_LOCAL(). -*/ void fluid_voice_release(fluid_voice_t* voice); int fluid_voice_noteoff(fluid_voice_t* voice); -int fluid_voice_off(fluid_voice_t* voice); +void fluid_voice_off(fluid_voice_t* voice); +void fluid_voice_stop(fluid_voice_t* voice); void fluid_voice_overflow_rvoice_finished(fluid_voice_t* voice); void fluid_voice_mix (fluid_voice_t *voice, int count, fluid_real_t* dsp_buf, fluid_real_t* left_buf, fluid_real_t* right_buf,