mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-02-21 11:21:24 +00:00
Add support for channel balance control (CC 8)
This commit is contained in:
parent
f3903d1a2f
commit
8f9b89588a
9 changed files with 81 additions and 11 deletions
|
@ -99,6 +99,7 @@ enum fluid_gen_type {
|
|||
* is used, however, as the destination for the default pitch wheel
|
||||
* modulator. */
|
||||
GEN_PITCH, /**< Pitch @note Not a real SoundFont generator */
|
||||
GEN_BALANCE, /**< Balance @note Not a real SoundFont generator */
|
||||
#ifndef __DOXYGEN__
|
||||
GEN_LAST /**< @internal Value defines the count of generators (#fluid_gen_type) @warning This symbol is not part of the public API and ABI stability guarantee and may change at any time! */
|
||||
#endif
|
||||
|
|
|
@ -118,7 +118,9 @@ fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off)
|
|||
continue;
|
||||
}
|
||||
if (i == BANK_SELECT_MSB || i == BANK_SELECT_LSB || i == VOLUME_MSB ||
|
||||
i == VOLUME_LSB || i == PAN_MSB || i == PAN_LSB) {
|
||||
i == VOLUME_LSB || i == PAN_MSB || i == PAN_LSB ||
|
||||
i == BALANCE_MSB || i == BALANCE_LSB
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -165,6 +167,10 @@ fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off)
|
|||
fluid_channel_set_cc (chan, PAN_MSB, 64);
|
||||
fluid_channel_set_cc (chan, PAN_LSB, 0);
|
||||
|
||||
/* Balance (MSB & LSB) */
|
||||
fluid_channel_set_cc (chan, BALANCE_MSB, 64);
|
||||
fluid_channel_set_cc (chan, BALANCE_LSB, 0);
|
||||
|
||||
/* Reverb */
|
||||
/* fluid_channel_set_cc (chan, EFFECTS_DEPTH1, 40); */
|
||||
/* Note: although XG standard specifies the default amount of reverb to
|
||||
|
|
|
@ -85,7 +85,8 @@ static const fluid_gen_info_t fluid_gen_info[] = {
|
|||
{ GEN_SCALETUNE, 0, 1, 0.0f, 1200.0f, 100.0f },
|
||||
{ GEN_EXCLUSIVECLASS, 0, 0, 0.0f, 0.0f, 0.0f },
|
||||
{ GEN_OVERRIDEROOTKEY, 1, 0, 0.0f, 127.0f, -1.0f },
|
||||
{ GEN_PITCH, 1, 0, 0.0f, 127.0f, 0.0f }
|
||||
{ GEN_PITCH, 1, 0, 0.0f, 127.0f, 0.0f },
|
||||
{ GEN_BALANCE, 1, 0, -1000.0f, 1000.0f, 0.0f }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -497,6 +497,7 @@ void fluid_dump_modulator(fluid_mod_t * mod){
|
|||
case GEN_CHORUSSEND: printf("Chorus send"); break;
|
||||
case GEN_REVERBSEND: printf("Reverb send"); break;
|
||||
case GEN_PAN: printf("pan"); break;
|
||||
case GEN_BALANCE: printf("balance"); break;
|
||||
case GEN_ATTENUATION: printf("att"); break;
|
||||
default: printf("dest %i",dest);
|
||||
}; /* switch dest */
|
||||
|
|
|
@ -138,6 +138,7 @@ static fluid_mod_t default_expr_mod; /* SF2.01 section 8.4.7 */
|
|||
static fluid_mod_t default_reverb_mod; /* SF2.01 section 8.4.8 */
|
||||
static fluid_mod_t default_chorus_mod; /* SF2.01 section 8.4.9 */
|
||||
static fluid_mod_t default_pitch_bend_mod; /* SF2.01 section 8.4.10 */
|
||||
static fluid_mod_t default_balance_mod; /* Non-standard modulator */
|
||||
|
||||
/* reverb presets */
|
||||
static const fluid_revmodel_presets_t revmodel_preset[] = {
|
||||
|
@ -408,6 +409,18 @@ fluid_synth_init(void)
|
|||
);
|
||||
fluid_mod_set_dest(&default_pitch_bend_mod, GEN_PITCH); /* Destination: Initial pitch */
|
||||
fluid_mod_set_amount(&default_pitch_bend_mod, 12700.0); /* Amount: 12700 cents */
|
||||
|
||||
|
||||
/* Non-standard MIDI continuous controller 8 to channel stereo balance */
|
||||
fluid_mod_set_source1(&default_balance_mod, BALANCE_MSB, /* Index=8 */
|
||||
FLUID_MOD_CC /* CC=1 */
|
||||
| FLUID_MOD_LINEAR /* type=0 */
|
||||
| FLUID_MOD_BIPOLAR /* P=1 */
|
||||
| FLUID_MOD_POSITIVE /* D=0 */
|
||||
);
|
||||
fluid_mod_set_source2(&default_balance_mod, 0, 0);
|
||||
fluid_mod_set_dest(&default_balance_mod, GEN_BALANCE); /* Destination: stereo balance */
|
||||
fluid_mod_set_amount(&default_balance_mod, 1000.0); /* Amount: 1000 tens of a percent */
|
||||
}
|
||||
|
||||
static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t* synth)
|
||||
|
@ -694,7 +707,7 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
fluid_synth_add_default_mod(synth, &default_reverb_mod, FLUID_SYNTH_ADD);
|
||||
fluid_synth_add_default_mod(synth, &default_chorus_mod, FLUID_SYNTH_ADD);
|
||||
fluid_synth_add_default_mod(synth, &default_pitch_bend_mod, FLUID_SYNTH_ADD);
|
||||
|
||||
fluid_synth_add_default_mod(synth, &default_balance_mod, FLUID_SYNTH_ADD);
|
||||
|
||||
/* Create and initialize the Fx unit.*/
|
||||
fluid_settings_getint(settings, "synth.ladspa.active", &with_ladspa);
|
||||
|
|
|
@ -537,7 +537,8 @@ fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
|
|||
/* GEN_COARSETUNE [1] #51 */
|
||||
/* GEN_FINETUNE [1] #52 */
|
||||
GEN_OVERRIDEROOTKEY, /* #58 */
|
||||
GEN_PITCH /* --- */
|
||||
GEN_PITCH, /* --- */
|
||||
GEN_BALANCE /* --- */
|
||||
};
|
||||
|
||||
/* When the voice is made ready for the synthesis process, a lot of
|
||||
|
@ -691,14 +692,20 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen)
|
|||
switch (gen) {
|
||||
|
||||
case GEN_PAN:
|
||||
/* range checking is done in the fluid_pan function */
|
||||
voice->pan = x;
|
||||
|
||||
case GEN_BALANCE:
|
||||
/* range checking is done in the fluid_pan and fluid_balance functions */
|
||||
voice->pan = fluid_voice_gen_value(voice, GEN_PAN);
|
||||
voice->balance = fluid_voice_gen_value(voice, GEN_BALANCE);
|
||||
|
||||
/* left amp */
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0, fluid_voice_calculate_gain_amplitude(voice, fluid_pan(x, 1)));
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 0,
|
||||
fluid_voice_calculate_gain_amplitude(voice,
|
||||
fluid_pan(voice->pan, 1) * fluid_balance(voice->balance, 1)));
|
||||
|
||||
/* right amp */
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1, fluid_voice_calculate_gain_amplitude(voice, fluid_pan(x, 0)));
|
||||
UPDATE_RVOICE_BUFFERS2(fluid_rvoice_buffers_set_amp, 1,
|
||||
fluid_voice_calculate_gain_amplitude(voice,
|
||||
fluid_pan(voice->pan, 0) * fluid_balance(voice->balance, 0)));
|
||||
break;
|
||||
|
||||
case GEN_ATTENUATION:
|
||||
|
@ -1605,8 +1612,10 @@ int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain)
|
|||
}
|
||||
|
||||
voice->synth_gain = gain;
|
||||
left = fluid_voice_calculate_gain_amplitude(voice, fluid_pan(voice->pan, 1));
|
||||
right = fluid_voice_calculate_gain_amplitude(voice, fluid_pan(voice->pan, 0));
|
||||
left = fluid_voice_calculate_gain_amplitude(voice,
|
||||
fluid_pan(voice->pan, 1) * fluid_balance(voice->balance, 1));
|
||||
right = fluid_voice_calculate_gain_amplitude(voice,
|
||||
fluid_pan(voice->pan, 0) * fluid_balance(voice->balance, 0));
|
||||
reverb = fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send);
|
||||
chorus = fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send);
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ struct _fluid_voice_t
|
|||
/* pan */
|
||||
fluid_real_t pan;
|
||||
|
||||
/* balance */
|
||||
fluid_real_t balance;
|
||||
|
||||
/* reverb */
|
||||
fluid_real_t reverb_send;
|
||||
|
||||
|
|
|
@ -301,6 +301,41 @@ fluid_pan(fluid_real_t c, int left)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the amount of attenuation based on the balance for the specified
|
||||
* channel. If balance is negative (turned toward left channel, only the right
|
||||
* channel is attenuated. If balance is positive, only the left channel is
|
||||
* attenuated.
|
||||
*
|
||||
* @params balance left/right balance, range [-1000;1000] in tens of percent
|
||||
* @return amount of attenuation [0.0;1.0]
|
||||
*/
|
||||
fluid_real_t fluid_balance(fluid_real_t balance, int left)
|
||||
{
|
||||
/* This is the most common case */
|
||||
if (balance == 0)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if ((left && balance < 0) || (!left && balance > 0))
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if (balance < 0)
|
||||
{
|
||||
balance = -balance;
|
||||
}
|
||||
|
||||
if (balance >= 1000)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return 1.0f - balance * 0.001f;
|
||||
}
|
||||
|
||||
/*
|
||||
* fluid_concave
|
||||
*/
|
||||
|
|
|
@ -46,6 +46,7 @@ fluid_real_t fluid_tc2sec_release(fluid_real_t tc);
|
|||
fluid_real_t fluid_act2hz(fluid_real_t c);
|
||||
fluid_real_t fluid_hz2ct(fluid_real_t c);
|
||||
fluid_real_t fluid_pan(fluid_real_t c, int left);
|
||||
fluid_real_t fluid_balance(fluid_real_t balance, int left);
|
||||
fluid_real_t fluid_concave(fluid_real_t val);
|
||||
fluid_real_t fluid_convex(fluid_real_t val);
|
||||
|
||||
|
|
Loading…
Reference in a new issue