From 45e7d340acac4bf0673d21e5ee975f6334bc74ee Mon Sep 17 00:00:00 2001 From: derselbst Date: Thu, 31 Aug 2023 20:41:34 +0200 Subject: [PATCH 1/2] Try implementing sustain stuff --- src/synth/fluid_voice.c | 12 +++++++++++- src/synth/fluid_voice.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index f605832e0..2601f8b59 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -321,6 +321,7 @@ fluid_voice_init(fluid_voice_t *voice, fluid_sample_t *sample, voice->mod_count = 0; voice->start_time = start_time; voice->has_noteoff = 0; + voice->ignore_sustain = 0; UPDATE_RVOICE0(fluid_rvoice_reset); /* @@ -612,6 +613,15 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t *voice) int dest_gen_index = mod->dest; fluid_gen_t *dest_gen = &voice->gen[dest_gen_index]; dest_gen->mod += modval; + + // issue blablabla: If a modulator is in use, which responds to CC64 and intended to manipulate the release envelope, this voice should not be sustained, + // to allow the modulator to achieve its desired behavior while the sustain switch is being depressed. + if((mod->src1 == SUSTAIN_SWITCH && mod->flags1 & (FLUID_MOD_CC | FLUID_MOD_SWITCH)) + || (mod->src2 == SUSTAIN_SWITCH && mod->flags2 & (FLUID_MOD_CC | FLUID_MOD_SWITCH)) + && (mod->dest == GEN_VOLENVRELEASE)) + { + voice->ignore_sustain = 1; + } /* fluid_dump_modulator(mod); */ } @@ -1364,7 +1374,7 @@ fluid_voice_noteoff(fluid_voice_t *voice) voice->status = FLUID_VOICE_HELD_BY_SOSTENUTO; } /* Or sustain a note under Sustain pedal */ - else if(fluid_channel_sustained(channel)) + else if(fluid_channel_sustained(channel) && !voice->ignore_sustain) { voice->status = FLUID_VOICE_SUSTAINED; } diff --git a/src/synth/fluid_voice.h b/src/synth/fluid_voice.h index 4ce6c2b7a..bd8f38070 100644 --- a/src/synth/fluid_voice.h +++ b/src/synth/fluid_voice.h @@ -105,6 +105,7 @@ struct _fluid_voice_t /* rvoice control */ fluid_rvoice_t *rvoice; fluid_rvoice_t *overflow_rvoice; /* Used temporarily and only in overflow situations */ + char ignore_sustain; char can_access_rvoice; /* False if rvoice is being rendered in separate thread */ char can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */ char has_noteoff; /* Flag set when noteoff has been sent */ From dc0b391cac74ec68301eeba66fecc0078d21b5c8 Mon Sep 17 00:00:00 2001 From: Tom M Date: Sun, 19 Nov 2023 18:41:25 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: RobsonFBP <142550370+RobsonFBP@users.noreply.github.com> --- src/synth/fluid_voice.c | 40 ++++++++++++++++++++++++++++------------ src/synth/fluid_voice.h | 2 +- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index 2601f8b59..11a3deba1 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -321,7 +321,7 @@ fluid_voice_init(fluid_voice_t *voice, fluid_sample_t *sample, voice->mod_count = 0; voice->start_time = start_time; voice->has_noteoff = 0; - voice->ignore_sustain = 0; + voice->note_off_sustain= 0; UPDATE_RVOICE0(fluid_rvoice_reset); /* @@ -613,15 +613,24 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t *voice) int dest_gen_index = mod->dest; fluid_gen_t *dest_gen = &voice->gen[dest_gen_index]; dest_gen->mod += modval; - - // issue blablabla: If a modulator is in use, which responds to CC64 and intended to manipulate the release envelope, this voice should not be sustained, - // to allow the modulator to achieve its desired behavior while the sustain switch is being depressed. - if((mod->src1 == SUSTAIN_SWITCH && mod->flags1 & (FLUID_MOD_CC | FLUID_MOD_SWITCH)) - || (mod->src2 == SUSTAIN_SWITCH && mod->flags2 & (FLUID_MOD_CC | FLUID_MOD_SWITCH)) - && (mod->dest == GEN_VOLENVRELEASE)) - { - voice->ignore_sustain = 1; - } + + // Issue #1276: Using Sustain Pedal like Soft Pedal + // + // If a modulator is in use that responds + // to the CC64 and intends to manipulate the release envelope, + // It's voice should change the volume envelope during the sustain fase. + // to allow the modulator to achieve the desired behavior + // it uses this modulator amount in new decay value and set attenuation, + // creating smooth release. + // + + if(mod->src1 == SUSTAIN_SWITCH && + (mod->flags1 & FLUID_MOD_CC) && + mod->dest == GEN_VOLENVRELEASE) + { + voice->note_off_sustain = mod->amount; + } + /* fluid_dump_modulator(mod); */ } @@ -1374,9 +1383,16 @@ fluid_voice_noteoff(fluid_voice_t *voice) voice->status = FLUID_VOICE_HELD_BY_SOSTENUTO; } /* Or sustain a note under Sustain pedal */ - else if(fluid_channel_sustained(channel) && !voice->ignore_sustain) + else if(fluid_channel_sustained(channel)) { - voice->status = FLUID_VOICE_SUSTAINED; + voice->status = FLUID_VOICE_SUSTAINED; + // Here it changes the envelope to simulate ignore_sustain + if(voice->note_off_sustain) + { + fluid_voice_gen_set(voice, GEN_VOLENVDECAY, voice->note_off_sustain); + fluid_voice_gen_set(voice, GEN_VOLENVSUSTAIN, 960); + fluid_voice_update_param(voice, GEN_VOLENVSUSTAIN); + } } /* Or force the voice to release stage */ else diff --git a/src/synth/fluid_voice.h b/src/synth/fluid_voice.h index bd8f38070..11d06ad67 100644 --- a/src/synth/fluid_voice.h +++ b/src/synth/fluid_voice.h @@ -105,7 +105,7 @@ struct _fluid_voice_t /* rvoice control */ fluid_rvoice_t *rvoice; fluid_rvoice_t *overflow_rvoice; /* Used temporarily and only in overflow situations */ - char ignore_sustain; + double note_off_sustain; /* for create smooth sustain #1276 */ char can_access_rvoice; /* False if rvoice is being rendered in separate thread */ char can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */ char has_noteoff; /* Flag set when noteoff has been sent */