From b659fd82a5037b2b0e49d7c2a59e86252fe16c39 Mon Sep 17 00:00:00 2001 From: jjceresa Date: Wed, 19 Dec 2018 18:12:09 +0100 Subject: [PATCH] Import modulator source src2 correctly. - When secondary source input (src2) is set to General Controller 'No Controller', output will be forced to +1.0 at synthesis time (see fluid_mod_get_value()). That means that this source will behave unipolar only. We need to force the unipolar flags to ensure the modulator will behave correctly later in fluid_voice_get_lower_boundary_for_attenuation(). --- src/sfloader/fluid_defsfont.c | 10 ++++++++++ src/synth/fluid_mod.c | 23 ++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 1931d4ee..9a8f3245 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -1364,6 +1364,16 @@ fluid_zone_mod_import_sfont(fluid_mod_t **mod, SFZone *sfzone) * Deactivate the modulator by setting the amount to 0. */ mod_dest->amount = 0; } + /* Note: When secondary source input (src2) is set to General Controller 'No Controller', + output will be forced to +1.0 at synthesis time (see fluid_mod_get_value()). + That means that this source will behave unipolar only. We need to force the + unipolar flags to ensure the modulator will behave correctly later. + */ + if(((mod_dest->flags2 & FLUID_MOD_CC) == FLUID_MOD_GC) && + (mod_dest->src2 == FLUID_MOD_NONE)) + { + mod_dest->flags2 &= ~FLUID_MOD_BIPOLAR; + } /* *** Transform *** */ /* SF2.01 only uses the 'linear' transform (0). diff --git a/src/synth/fluid_mod.c b/src/synth/fluid_mod.c index 9a48ed45..db59642b 100644 --- a/src/synth/fluid_mod.c +++ b/src/synth/fluid_mod.c @@ -364,7 +364,22 @@ fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, cons } /* - * fluid_mod_get_value + * fluid_mod_get_value. + * Computes and return modulator output following SF2.01 + * (See SoundFont Modulator Controller Model Chapter 9.5). + * + * Output = Transform(Amount * Map(primary source input) * Map(secondary source input)) + * + * Notes: + * 1)fluid_mod_get_value, ignores the Transform operator. The result is: + * + * Output = Amount * Map(primary source input) * Map(secondary source input) + * + * 2)When primary source input (src1) is set to General Controller 'No Controller', + * output is forced to 0. + * + * 3)When secondary source input (src2) is set to General Controller 'No Controller', + * output is forced to +1.0 */ fluid_real_t fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice) @@ -418,6 +433,9 @@ fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice) /* transform the input value */ v1 = fluid_mod_transform_source_value(v1, mod->flags1, range1); } + /* When primary source input (src1) is set to General Controller 'No Controller', + output is forced to 0.0 + */ else { return 0.0; @@ -437,6 +455,9 @@ fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice) /* transform the second input value */ v2 = fluid_mod_transform_source_value(v2, mod->flags2, range2); } + /* When secondary source input (src2) is set to General Controller 'No Controller', + output is forced to +1.0 + */ else { v2 = 1.0f;