mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-01 00:21:14 +00:00
introducing FLUID_PEAK_ATTENUATION macro. (#397)
avoids hard-coding the magic 96 dB everywhere in the code
This commit is contained in:
parent
18917840b7
commit
0921ccc4c0
5 changed files with 42 additions and 11 deletions
|
@ -51,7 +51,7 @@ fluid_rvoice_calc_amp(fluid_rvoice_t* voice)
|
||||||
fluid_real_t amp_max;
|
fluid_real_t amp_max;
|
||||||
|
|
||||||
target_amp = fluid_cb2amp (voice->dsp.attenuation)
|
target_amp = fluid_cb2amp (voice->dsp.attenuation)
|
||||||
* fluid_cb2amp (960.0f * (1.0f - fluid_adsr_env_get_val(&voice->envlfo.volenv))
|
* fluid_cb2amp (FLUID_PEAK_ATTENUATION * (1.0f - fluid_adsr_env_get_val(&voice->envlfo.volenv))
|
||||||
+ fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol);
|
+ fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol);
|
||||||
|
|
||||||
/* We turn off a voice, if the volume has dropped low enough. */
|
/* We turn off a voice, if the volume has dropped low enough. */
|
||||||
|
@ -507,7 +507,7 @@ fluid_rvoice_noteoff_LOCAL(fluid_rvoice_t* voice, unsigned int min_ticks)
|
||||||
if (fluid_adsr_env_get_val(&voice->envlfo.volenv) > 0){
|
if (fluid_adsr_env_get_val(&voice->envlfo.volenv) > 0){
|
||||||
fluid_real_t lfo = fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol;
|
fluid_real_t lfo = fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol;
|
||||||
fluid_real_t amp = fluid_adsr_env_get_val(&voice->envlfo.volenv) * fluid_cb2amp(lfo);
|
fluid_real_t amp = fluid_adsr_env_get_val(&voice->envlfo.volenv) * fluid_cb2amp(lfo);
|
||||||
fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1);
|
fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / FLUID_PEAK_ATTENUATION - 1);
|
||||||
fluid_clip (env_value, 0.0, 1.0);
|
fluid_clip (env_value, 0.0, 1.0);
|
||||||
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
|
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
|
||||||
}
|
}
|
||||||
|
@ -569,7 +569,8 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack)
|
||||||
volenv_val to achieve equivalent amplitude during the attack phase
|
volenv_val to achieve equivalent amplitude during the attack phase
|
||||||
for seamless volume transition. */
|
for seamless volume transition. */
|
||||||
fluid_real_t amp_cb, env_value;
|
fluid_real_t amp_cb, env_value;
|
||||||
amp_cb = 960.0f * (1.0f - fluid_adsr_env_get_val(&voice->envlfo.volenv));
|
amp_cb = FLUID_PEAK_ATTENUATION *
|
||||||
|
(1.0f - fluid_adsr_env_get_val(&voice->envlfo.volenv));
|
||||||
env_value = fluid_cb2amp(amp_cb); /* a bit of optimization */
|
env_value = fluid_cb2amp(amp_cb); /* a bit of optimization */
|
||||||
fluid_clip (env_value, 0.0, 1.0);
|
fluid_clip (env_value, 0.0, 1.0);
|
||||||
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
|
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
|
||||||
|
|
|
@ -41,7 +41,6 @@ typedef struct _fluid_rvoice_t fluid_rvoice_t;
|
||||||
*/
|
*/
|
||||||
#define FLUID_NOISE_FLOOR 2.e-7
|
#define FLUID_NOISE_FLOOR 2.e-7
|
||||||
|
|
||||||
|
|
||||||
enum fluid_loop {
|
enum fluid_loop {
|
||||||
FLUID_UNLOOPED = 0,
|
FLUID_UNLOOPED = 0,
|
||||||
FLUID_LOOP_DURING_RELEASE = 1,
|
FLUID_LOOP_DURING_RELEASE = 1,
|
||||||
|
|
|
@ -305,7 +305,7 @@ fluid_synth_init(void)
|
||||||
);
|
);
|
||||||
fluid_mod_set_source2(&custom_breath2att_mod, 0, 0); /* No 2nd source */
|
fluid_mod_set_source2(&custom_breath2att_mod, 0, 0); /* No 2nd source */
|
||||||
fluid_mod_set_dest(&custom_breath2att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
fluid_mod_set_dest(&custom_breath2att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
||||||
fluid_mod_set_amount(&custom_breath2att_mod, 960.0); /* Modulation amount: 960 */
|
fluid_mod_set_amount(&custom_breath2att_mod, FLUID_PEAK_ATTENUATION); /* Modulation amount: 960 */
|
||||||
|
|
||||||
/* SF2.01 page 53 section 8.4.1: MIDI Note-On Velocity to Initial Attenuation */
|
/* SF2.01 page 53 section 8.4.1: MIDI Note-On Velocity to Initial Attenuation */
|
||||||
fluid_mod_set_source1(&default_vel2att_mod, /* The modulator we are programming here */
|
fluid_mod_set_source1(&default_vel2att_mod, /* The modulator we are programming here */
|
||||||
|
@ -317,7 +317,7 @@ fluid_synth_init(void)
|
||||||
);
|
);
|
||||||
fluid_mod_set_source2(&default_vel2att_mod, 0, 0); /* No 2nd source */
|
fluid_mod_set_source2(&default_vel2att_mod, 0, 0); /* No 2nd source */
|
||||||
fluid_mod_set_dest(&default_vel2att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
fluid_mod_set_dest(&default_vel2att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
||||||
fluid_mod_set_amount(&default_vel2att_mod, 960.0); /* Modulation amount: 960 */
|
fluid_mod_set_amount(&default_vel2att_mod, FLUID_PEAK_ATTENUATION); /* Modulation amount: 960 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ fluid_synth_init(void)
|
||||||
);
|
);
|
||||||
fluid_mod_set_source2(&default_att_mod, 0, 0); /* No second source */
|
fluid_mod_set_source2(&default_att_mod, 0, 0); /* No second source */
|
||||||
fluid_mod_set_dest(&default_att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
fluid_mod_set_dest(&default_att_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
||||||
fluid_mod_set_amount(&default_att_mod, 960.0); /* Amount: 960 */
|
fluid_mod_set_amount(&default_att_mod, FLUID_PEAK_ATTENUATION); /* Amount: 960 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ fluid_synth_init(void)
|
||||||
);
|
);
|
||||||
fluid_mod_set_source2(&default_expr_mod, 0, 0); /* No second source */
|
fluid_mod_set_source2(&default_expr_mod, 0, 0); /* No second source */
|
||||||
fluid_mod_set_dest(&default_expr_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
fluid_mod_set_dest(&default_expr_mod, GEN_ATTENUATION); /* Target: Initial attenuation */
|
||||||
fluid_mod_set_amount(&default_expr_mod, 960.0); /* Amount: 960 */
|
fluid_mod_set_amount(&default_expr_mod, FLUID_PEAK_ATTENUATION); /* Amount: 960 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,9 +464,9 @@ fluid_synth_init(void)
|
||||||
| FLUID_MOD_POSITIVE /* D=0 */
|
| FLUID_MOD_POSITIVE /* D=0 */
|
||||||
);
|
);
|
||||||
fluid_mod_set_source2(&custom_balance_mod, 0, 0);
|
fluid_mod_set_source2(&custom_balance_mod, 0, 0);
|
||||||
fluid_mod_set_dest(&custom_balance_mod, GEN_CUSTOM_BALANCE); /* Destination: stereo balance */
|
fluid_mod_set_dest(&custom_balance_mod, GEN_CUSTOM_BALANCE); /* Destination: stereo balance */
|
||||||
/* Amount: 96 dB of attenuation (on the opposite channel) */
|
/* Amount: 96 dB of attenuation (on the opposite channel) */
|
||||||
fluid_mod_set_amount(&custom_balance_mod, 960.0);
|
fluid_mod_set_amount(&custom_balance_mod, FLUID_PEAK_ATTENUATION); /* Amount: 960 */
|
||||||
}
|
}
|
||||||
|
|
||||||
static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t* synth)
|
static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t* synth)
|
||||||
|
|
|
@ -71,7 +71,7 @@ fluid_conversion_config(void)
|
||||||
implemented according to the pictures on SF2.01 page 73. */
|
implemented according to the pictures on SF2.01 page 73. */
|
||||||
|
|
||||||
for (i = 1; i < FLUID_VEL_CB_SIZE - 1; i++) {
|
for (i = 1; i < FLUID_VEL_CB_SIZE - 1; i++) {
|
||||||
x = -20.0 / 96.0 * log((i * i) / (fluid_real_t)((FLUID_VEL_CB_SIZE-1) * (FLUID_VEL_CB_SIZE-1))) / M_LN10;
|
x = (-200.0 / FLUID_PEAK_ATTENUATION) * log((i * i) / (fluid_real_t)((FLUID_VEL_CB_SIZE-1) * (FLUID_VEL_CB_SIZE-1))) / M_LN10;
|
||||||
fluid_convex_tab[i] = (fluid_real_t) (1.0 - x);
|
fluid_convex_tab[i] = (fluid_real_t) (1.0 - x);
|
||||||
fluid_concave_tab[(FLUID_VEL_CB_SIZE-1) - i] = (fluid_real_t) x;
|
fluid_concave_tab[(FLUID_VEL_CB_SIZE-1) - i] = (fluid_real_t) x;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,37 @@
|
||||||
|
|
||||||
#include "fluidsynth_priv.h"
|
#include "fluidsynth_priv.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Attenuation range in centibels.
|
||||||
|
Attenuation range is the dynamic range of the volume envelope generator
|
||||||
|
from 0 to the end of attack segment.
|
||||||
|
fluidsynth is a 24 bit synth, it could (should??) be 144 dB of attenuation.
|
||||||
|
However the spec makes no distinction between 16 or 24 bit synths, so use
|
||||||
|
96 dB here.
|
||||||
|
|
||||||
|
Note about usefulness of 24 bits:
|
||||||
|
1)Even fluidsynth is a 24 bit synth, this format is only relevant if
|
||||||
|
the sample format coming from the soundfont is 24 bits and the audio sample format
|
||||||
|
choosen by the application (audio.sample.format) is not 16 bits.
|
||||||
|
|
||||||
|
2)When the sample soundfont is 16 bits, the internal 24 bits number have
|
||||||
|
16 bits msb and lsb to 0. Consequently, at the DAC output, the dynamic range of
|
||||||
|
this 24 bit sample is reduced to the the dynamic of a 16 bits sample (ie 90 db)
|
||||||
|
even if this sample is produced by the audio driver using an audio sample format
|
||||||
|
compatible for a 24 bit DAC.
|
||||||
|
|
||||||
|
3)When the audio sample format settings is 16 bits (audio.sample.format), the
|
||||||
|
audio driver will make use of a 16 bit DAC, and the dynamic will be reduced to 96 dB
|
||||||
|
even if the initial sample comes from a 24 bits soundfont.
|
||||||
|
|
||||||
|
In both cases (2) or (3), the real dynamic range is only 96 dB.
|
||||||
|
|
||||||
|
Other consideration for FLUID_NOISE_FLOOR related to case (1),(2,3):
|
||||||
|
- for case (1), FLUID_NOISE_FLOOR should be the noise floor for 24 bits (i.e -138 dB).
|
||||||
|
- for case (2) or (3), FLUID_NOISE_FLOOR should be the noise floor for 16 bits (i.e -90 dB).
|
||||||
|
*/
|
||||||
|
#define FLUID_PEAK_ATTENUATION 960.0f
|
||||||
|
|
||||||
void fluid_conversion_config(void);
|
void fluid_conversion_config(void);
|
||||||
|
|
||||||
fluid_real_t fluid_ct2hz_real(fluid_real_t cents);
|
fluid_real_t fluid_ct2hz_real(fluid_real_t cents);
|
||||||
|
|
Loading…
Reference in a new issue