mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 23:11:41 +00:00
Merge pull request #194 from FluidSynth/mod_refactor
refactor modulator handling
This commit is contained in:
commit
b08021b030
2 changed files with 159 additions and 171 deletions
|
@ -151,9 +151,141 @@ fluid_mod_get_dest(fluid_mod_t* mod)
|
|||
double
|
||||
fluid_mod_get_amount(fluid_mod_t* mod)
|
||||
{
|
||||
return (fluid_real_t) mod->amount;
|
||||
return (double) mod->amount;
|
||||
}
|
||||
|
||||
/*
|
||||
* retrieves the initial value from the given source of the modulator
|
||||
*/
|
||||
static fluid_real_t
|
||||
fluid_mod_get_source_value(const unsigned char mod_src,
|
||||
const unsigned char mod_flags,
|
||||
fluid_real_t* range,
|
||||
const fluid_channel_t* chan,
|
||||
const fluid_voice_t* voice
|
||||
)
|
||||
{
|
||||
fluid_real_t val;
|
||||
|
||||
if (mod_flags & FLUID_MOD_CC)
|
||||
{
|
||||
val = fluid_channel_get_cc(chan, mod_src);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (mod_src)
|
||||
{
|
||||
case FLUID_MOD_NONE: /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
|
||||
val = *range;
|
||||
break;
|
||||
case FLUID_MOD_VELOCITY:
|
||||
val = voice->vel;
|
||||
break;
|
||||
case FLUID_MOD_KEY:
|
||||
val = voice->key;
|
||||
break;
|
||||
case FLUID_MOD_KEYPRESSURE:
|
||||
val = fluid_channel_get_key_pressure (chan);
|
||||
break;
|
||||
case FLUID_MOD_CHANNELPRESSURE:
|
||||
val = fluid_channel_get_channel_pressure (chan);
|
||||
break;
|
||||
case FLUID_MOD_PITCHWHEEL:
|
||||
val = fluid_channel_get_pitch_bend (chan);
|
||||
*range = 0x4000;
|
||||
break;
|
||||
case FLUID_MOD_PITCHWHEELSENS:
|
||||
val = fluid_channel_get_pitch_wheel_sensitivity (chan);
|
||||
break;
|
||||
default:
|
||||
FLUID_LOG(FLUID_ERR, "Unknown modulator source '%d', disabling modulator.", mod_src);
|
||||
val = 0.0;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* transforms the initial value retrieved by \c fluid_mod_get_source_value into [0.0;1.0]
|
||||
*/
|
||||
static fluid_real_t
|
||||
fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, const fluid_real_t range)
|
||||
{
|
||||
/* normalized value, i.e. usually in the range [0;1]
|
||||
*
|
||||
* if val was retrieved from pitch_bend then [-0.5;0.5]
|
||||
*/
|
||||
const fluid_real_t val_norm = val / range;
|
||||
|
||||
/* we could also only switch case the lower nibble of mod_flags, however
|
||||
* this would keep us from adding further mod types in the future
|
||||
*
|
||||
* instead just remove the flag(s) we already took care of
|
||||
*/
|
||||
mod_flags &= ~FLUID_MOD_CC;
|
||||
|
||||
switch (mod_flags/* & 0x0f*/)
|
||||
{
|
||||
case FLUID_MOD_LINEAR | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =0 */
|
||||
val = val_norm;
|
||||
break;
|
||||
case FLUID_MOD_LINEAR | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =1 */
|
||||
val = 1.0f - val_norm;
|
||||
break;
|
||||
case FLUID_MOD_LINEAR | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =2 */
|
||||
val = -1.0f + 2.0f * val_norm;
|
||||
break;
|
||||
case FLUID_MOD_LINEAR | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =3 */
|
||||
val = 1.0f - 2.0f * val_norm;
|
||||
break;
|
||||
case FLUID_MOD_CONCAVE | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =4 */
|
||||
val = fluid_concave(127 * (val_norm));
|
||||
break;
|
||||
case FLUID_MOD_CONCAVE | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =5 */
|
||||
val = fluid_concave(127 * (1.0f - val_norm));
|
||||
break;
|
||||
case FLUID_MOD_CONCAVE | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =6 */
|
||||
val = (val_norm > 0.5f) ? fluid_concave(127 * 2 * (val_norm - 0.5f))
|
||||
: -fluid_concave(127 * 2 * (0.5f - val_norm));
|
||||
break;
|
||||
case FLUID_MOD_CONCAVE | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =7 */
|
||||
val = (val_norm > 0.5f) ? -fluid_concave(127 * 2 * (val_norm - 0.5f))
|
||||
: fluid_concave(127 * 2 * (0.5f - val_norm));
|
||||
break;
|
||||
case FLUID_MOD_CONVEX | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =8 */
|
||||
val = fluid_convex(127 * (val_norm));
|
||||
break;
|
||||
case FLUID_MOD_CONVEX | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =9 */
|
||||
val = fluid_convex(127 * (1.0f - val_norm));
|
||||
break;
|
||||
case FLUID_MOD_CONVEX | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =10 */
|
||||
val = (val_norm > 0.5f) ? fluid_convex(127 * 2 * (val_norm - 0.5f))
|
||||
: -fluid_convex(127 * 2 * (0.5f - val_norm));
|
||||
break;
|
||||
case FLUID_MOD_CONVEX | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =11 */
|
||||
val = (val_norm > 0.5f) ? -fluid_convex(127 * 2 * (val_norm - 0.5f))
|
||||
: fluid_convex(127 * 2 * (0.5f - val_norm));
|
||||
break;
|
||||
case FLUID_MOD_SWITCH | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =12 */
|
||||
val = (val_norm >= 0.5f)? 1.0f : 0.0f;
|
||||
break;
|
||||
case FLUID_MOD_SWITCH | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =13 */
|
||||
val = (val_norm >= 0.5f)? 0.0f : 1.0f;
|
||||
break;
|
||||
case FLUID_MOD_SWITCH | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =14 */
|
||||
val = (val_norm >= 0.5f)? 1.0f : -1.0f;
|
||||
break;
|
||||
case FLUID_MOD_SWITCH | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =15 */
|
||||
val = (val_norm >= 0.5f)? -1.0f : 1.0f;
|
||||
break;
|
||||
default:
|
||||
FLUID_LOG(FLUID_ERR, "Unknown modulator type '%d', disabling modulator.", mod_flags);
|
||||
val = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_mod_get_value
|
||||
|
@ -209,90 +341,15 @@ fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voic
|
|||
// end S. Christian Collins' mod
|
||||
|
||||
/* get the initial value of the first source */
|
||||
if (mod->src1 > 0) {
|
||||
if (mod->flags1 & FLUID_MOD_CC) {
|
||||
v1 = fluid_channel_get_cc(chan, mod->src1);
|
||||
} else { /* source 1 is one of the direct controllers */
|
||||
switch (mod->src1) {
|
||||
case FLUID_MOD_NONE: /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
|
||||
v1 = range1;
|
||||
break;
|
||||
case FLUID_MOD_VELOCITY:
|
||||
v1 = voice->vel;
|
||||
break;
|
||||
case FLUID_MOD_KEY:
|
||||
v1 = voice->key;
|
||||
break;
|
||||
case FLUID_MOD_KEYPRESSURE:
|
||||
v1 = fluid_channel_get_key_pressure (chan);
|
||||
break;
|
||||
case FLUID_MOD_CHANNELPRESSURE:
|
||||
v1 = fluid_channel_get_channel_pressure (chan);
|
||||
break;
|
||||
case FLUID_MOD_PITCHWHEEL:
|
||||
v1 = fluid_channel_get_pitch_bend (chan);
|
||||
range1 = 0x4000;
|
||||
break;
|
||||
case FLUID_MOD_PITCHWHEELSENS:
|
||||
v1 = fluid_channel_get_pitch_wheel_sensitivity (chan);
|
||||
break;
|
||||
default:
|
||||
v1 = 0.0;
|
||||
}
|
||||
}
|
||||
if (mod->src1 > 0)
|
||||
{
|
||||
v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, chan, voice);
|
||||
|
||||
/* transform the input value */
|
||||
switch (mod->flags1 & 0x0f) {
|
||||
case 0: /* linear, unipolar, positive */
|
||||
v1 /= range1;
|
||||
break;
|
||||
case 1: /* linear, unipolar, negative */
|
||||
v1 = 1.0f - v1 / range1;
|
||||
break;
|
||||
case 2: /* linear, bipolar, positive */
|
||||
v1 = -1.0f + 2.0f * v1 / range1;
|
||||
break;
|
||||
case 3: /* linear, bipolar, negative */
|
||||
v1 = 1.0f - 2.0f * v1 / range1;
|
||||
break;
|
||||
case 4: /* concave, unipolar, positive */
|
||||
v1 = fluid_concave(v1);
|
||||
break;
|
||||
case 5: /* concave, unipolar, negative */
|
||||
v1 = fluid_concave(127 - v1);
|
||||
break;
|
||||
case 6: /* concave, bipolar, positive */
|
||||
v1 = (v1 > 64)? fluid_concave(2 * (v1 - 64)) : -fluid_concave(2 * (64 - v1));
|
||||
break;
|
||||
case 7: /* concave, bipolar, negative */
|
||||
v1 = (v1 > 64)? -fluid_concave(2 * (v1 - 64)) : fluid_concave(2 * (64 - v1));
|
||||
break;
|
||||
case 8: /* convex, unipolar, positive */
|
||||
v1 = fluid_convex(v1);
|
||||
break;
|
||||
case 9: /* convex, unipolar, negative */
|
||||
v1 = fluid_convex(127 - v1);
|
||||
break;
|
||||
case 10: /* convex, bipolar, positive */
|
||||
v1 = (v1 > 64)? fluid_convex(2 * (v1 - 64)) : -fluid_convex(2 * (64 - v1));
|
||||
break;
|
||||
case 11: /* convex, bipolar, negative */
|
||||
v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
|
||||
break;
|
||||
case 12: /* switch, unipolar, positive */
|
||||
v1 = (v1 >= 64)? 1.0f : 0.0f;
|
||||
break;
|
||||
case 13: /* switch, unipolar, negative */
|
||||
v1 = (v1 >= 64)? 0.0f : 1.0f;
|
||||
break;
|
||||
case 14: /* switch, bipolar, positive */
|
||||
v1 = (v1 >= 64)? 1.0f : -1.0f;
|
||||
break;
|
||||
case 15: /* switch, bipolar, negative */
|
||||
v1 = (v1 >= 64)? -1.0f : 1.0f;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
v1 = fluid_mod_transform_source_value(v1, mod->flags1, range1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
@ -302,89 +359,15 @@ fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voic
|
|||
}
|
||||
|
||||
/* get the second input source */
|
||||
if (mod->src2 > 0) {
|
||||
if (mod->flags2 & FLUID_MOD_CC) {
|
||||
v2 = fluid_channel_get_cc(chan, mod->src2);
|
||||
} else {
|
||||
switch (mod->src2) {
|
||||
case FLUID_MOD_NONE: /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
|
||||
v2 = range2;
|
||||
break;
|
||||
case FLUID_MOD_VELOCITY:
|
||||
v2 = voice->vel;
|
||||
break;
|
||||
case FLUID_MOD_KEY:
|
||||
v2 = voice->key;
|
||||
break;
|
||||
case FLUID_MOD_KEYPRESSURE:
|
||||
v2 = fluid_channel_get_key_pressure (chan);
|
||||
break;
|
||||
case FLUID_MOD_CHANNELPRESSURE:
|
||||
v2 = fluid_channel_get_channel_pressure (chan);
|
||||
break;
|
||||
case FLUID_MOD_PITCHWHEEL:
|
||||
v2 = fluid_channel_get_pitch_bend (chan);
|
||||
break;
|
||||
case FLUID_MOD_PITCHWHEELSENS:
|
||||
v2 = fluid_channel_get_pitch_wheel_sensitivity (chan);
|
||||
break;
|
||||
default:
|
||||
v1 = 0.0f;
|
||||
}
|
||||
}
|
||||
if (mod->src2 > 0)
|
||||
{
|
||||
v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, chan, voice);
|
||||
|
||||
/* transform the second input value */
|
||||
switch (mod->flags2 & 0x0f) {
|
||||
case 0: /* linear, unipolar, positive */
|
||||
v2 /= range2;
|
||||
break;
|
||||
case 1: /* linear, unipolar, negative */
|
||||
v2 = 1.0f - v2 / range2;
|
||||
break;
|
||||
case 2: /* linear, bipolar, positive */
|
||||
v2 = -1.0f + 2.0f * v2 / range2;
|
||||
break;
|
||||
case 3: /* linear, bipolar, negative */
|
||||
v2 = -1.0f + 2.0f * v2 / range2;
|
||||
break;
|
||||
case 4: /* concave, unipolar, positive */
|
||||
v2 = fluid_concave(v2);
|
||||
break;
|
||||
case 5: /* concave, unipolar, negative */
|
||||
v2 = fluid_concave(127 - v2);
|
||||
break;
|
||||
case 6: /* concave, bipolar, positive */
|
||||
v2 = (v2 > 64)? fluid_concave(2 * (v2 - 64)) : -fluid_concave(2 * (64 - v2));
|
||||
break;
|
||||
case 7: /* concave, bipolar, negative */
|
||||
v2 = (v2 > 64)? -fluid_concave(2 * (v2 - 64)) : fluid_concave(2 * (64 - v2));
|
||||
break;
|
||||
case 8: /* convex, unipolar, positive */
|
||||
v2 = fluid_convex(v2);
|
||||
break;
|
||||
case 9: /* convex, unipolar, negative */
|
||||
v2 = 1.0f - fluid_convex(v2);
|
||||
break;
|
||||
case 10: /* convex, bipolar, positive */
|
||||
v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
|
||||
break;
|
||||
case 11: /* convex, bipolar, negative */
|
||||
v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
|
||||
break;
|
||||
case 12: /* switch, unipolar, positive */
|
||||
v2 = (v2 >= 64)? 1.0f : 0.0f;
|
||||
break;
|
||||
case 13: /* switch, unipolar, negative */
|
||||
v2 = (v2 >= 64)? 0.0f : 1.0f;
|
||||
break;
|
||||
case 14: /* switch, bipolar, positive */
|
||||
v2 = (v2 >= 64)? 1.0f : -1.0f;
|
||||
break;
|
||||
case 15: /* switch, bipolar, negative */
|
||||
v2 = (v2 >= 64)? -1.0f : 1.0f;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
v2 = fluid_mod_transform_source_value(v2, mod->flags2, range2);
|
||||
}
|
||||
else
|
||||
{
|
||||
v2 = 1.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -1330,13 +1330,14 @@ fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode)
|
|||
*/
|
||||
|
||||
if (((mod->flags1 & FLUID_MOD_CC) == 0)
|
||||
&& ((mod->src1 != 0) /* SF2.01 section 8.2.1: Constant value */
|
||||
&& (mod->src1 != 2) /* Note-on velocity */
|
||||
&& (mod->src1 != 3) /* Note-on key number */
|
||||
&& (mod->src1 != 10) /* Poly pressure */
|
||||
&& (mod->src1 != 13) /* Channel pressure */
|
||||
&& (mod->src1 != 14) /* Pitch wheel */
|
||||
&& (mod->src1 != 16))) { /* Pitch wheel sensitivity */
|
||||
&& ((mod->src1 != FLUID_MOD_NONE) /* SF2.01 section 8.2.1: Constant value */
|
||||
&& (mod->src1 != FLUID_MOD_VELOCITY) /* Note-on velocity */
|
||||
&& (mod->src1 != FLUID_MOD_KEY) /* Note-on key number */
|
||||
&& (mod->src1 != FLUID_MOD_KEYPRESSURE) /* Poly pressure */
|
||||
&& (mod->src1 != FLUID_MOD_CHANNELPRESSURE) /* Channel pressure */
|
||||
&& (mod->src1 != FLUID_MOD_PITCHWHEEL) /* Pitch wheel */
|
||||
&& (mod->src1 != FLUID_MOD_PITCHWHEELSENS)))/* Pitch wheel sensitivity */
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN, "Ignoring invalid controller, using non-CC source %i.", mod->src1);
|
||||
return;
|
||||
}
|
||||
|
@ -1370,6 +1371,10 @@ fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode)
|
|||
if (voice->mod_count < FLUID_NUM_MOD) {
|
||||
fluid_mod_clone(&voice->mod[voice->mod_count++], mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
FLUID_LOG(FLUID_WARN, "Voice %i has more modulators than supported, ignoring.", voice->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue