Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs in modulator handling #1392

Merged
merged 8 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading