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;
|
||||
|
||||
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);
|
||||
|
||||
/* 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){
|
||||
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 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_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
|
||||
for seamless volume transition. */
|
||||
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 */
|
||||
fluid_clip (env_value, 0.0, 1.0);
|
||||
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
|
||||
|
||||
|
||||
enum fluid_loop {
|
||||
FLUID_UNLOOPED = 0,
|
||||
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_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 */
|
||||
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_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_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_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_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) */
|
||||
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)
|
||||
|
|
|
@ -71,7 +71,7 @@ fluid_conversion_config(void)
|
|||
implemented according to the pictures on SF2.01 page 73. */
|
||||
|
||||
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_concave_tab[(FLUID_VEL_CB_SIZE-1) - i] = (fluid_real_t) x;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,37 @@
|
|||
|
||||
#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);
|
||||
|
||||
fluid_real_t fluid_ct2hz_real(fluid_real_t cents);
|
||||
|
|
Loading…
Reference in a new issue