Skip to content

Commit

Permalink
Fix bugs in modulator handling (#1392)
Browse files Browse the repository at this point in the history
  • Loading branch information
derselbst authored Oct 31, 2024
1 parent ed5f7e6 commit c43f4da
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 71 deletions.
23 changes: 0 additions & 23 deletions src/sfloader/fluid_defsfont.c
Original file line number Diff line number Diff line change
Expand Up @@ -1616,18 +1616,6 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
/* This shouldn't happen - unknown type!
* Deactivate the modulator by setting the amount to 0. */
mod_dest->amount = 0;
}

/* Note: When primary source input (src1) is set to General Controller 'No Controller',
output will be forced to 0.0 at synthesis time (see fluid_mod_get_value()).
That means that the minimum value of the modulator will be always 0.0.
We need to force amount value to 0 to ensure a correct evaluation of the minimum
value later (see fluid_voice_get_lower_boundary_for_attenuation()).
*/
if(((mod_dest->flags1 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
(mod_dest->src1 == FLUID_MOD_NONE))
{
mod_dest->amount = 0;
}

/* *** Dest *** */
Expand All @@ -1639,17 +1627,6 @@ fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
/* This shouldn't happen - unknown type!
* 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 flag to ensure a correct evaluation of the minimum
value later (see fluid_voice_get_lower_boundary_for_attenuation()).
*/
if(((mod_dest->flags2 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
(mod_dest->src2 == FLUID_MOD_NONE))
{
mod_dest->flags2 &= ~FLUID_MOD_BIPOLAR;
}

/**
Expand Down
64 changes: 17 additions & 47 deletions src/synth/fluid_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ fluid_mod_get_source_value(const unsigned char mod_src,

if(mod_src == PORTAMENTO_CTRL)
{
// an invalid portamento fromkey should be treated as 0 when it's actually used for moulating
// an invalid portamento fromkey should be treated as 0 when it's actually used for modulating
if(!fluid_channel_is_valid_note(val))
{
val = 0;
Expand Down Expand Up @@ -396,23 +396,17 @@ fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, cons
*
* Output = Transform(Amount * Map(primary source input) * Map(secondary source input))
*
* Notes:
* 1)fluid_mod_get_value, ignores the Transform operator. The result is:
* Note:
* 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)
{
extern fluid_mod_t default_vel2filter_mod;

fluid_real_t v1 = 0.0, v2 = 1.0;
fluid_real_t v1, v2;
fluid_real_t final_value;
/* The wording of the default modulators refers to a range of 127/128.
* And the table in section 9.5.3 suggests, that this mapping should be applied
Expand Down Expand Up @@ -451,56 +445,32 @@ fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice)
* */
if(fluid_mod_test_identity(mod, &default_vel2filter_mod))
{
// S. Christian Collins' mod, to stop forcing velocity based filtering
/*
if (voice->vel < 64){
return (fluid_real_t) mod->amount / 2.0;
} else {
return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
}
return (fluid_real_t) mod->amount / 2.0;
*/
return 0; // (fluid_real_t) mod->amount / 2.0;
// S. Christian Collins' mod, to stop forcing velocity based filtering
return 0;
}

// end S. Christian Collins' mod

/* get the initial value of the first source */
if(mod->src1 > 0)
{
v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, 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;
}
/* Get the initial value of the first source.
*
* Even if the src is FLUID_MOD_NONE, the value has to be transformed, see #1389
*/
v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, voice);

/* no need to go further */
if(v1 == 0.0f)
{
return 0.0f;
}
/* transform the input value */
v1 = fluid_mod_transform_source_value(v1, mod->flags1, range1);

/* get the second input source */
if(mod->src2 > 0)
{
v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, voice);
v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, 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;
}
/* transform the second input value */
v2 = fluid_mod_transform_source_value(v2, mod->flags2, range2);

/* it indeed is as simple as that: */
final_value = (fluid_real_t) mod->amount * v1 * v2;
Expand Down
2 changes: 1 addition & 1 deletion src/synth/fluid_voice.c
Original file line number Diff line number Diff line change
Expand Up @@ -1791,7 +1791,7 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t *voice)
3)absolute value of amount.
When at least one source mapping is bipolar:
min_val is -|amount| regardless the sign of amount.
min_val is -|amount| regardless the sign of amount.
When both sources mapping are unipolar:
min_val is -|amount|, if amount is negative.
min_val is 0, if amount is positive
Expand Down

0 comments on commit c43f4da

Please sign in to comment.