Cleanup floating-point arithmetics (#543)

* avoid unnecessary floating-point promotion to double when compiled `WITH_FLOAT==1`
* remove redundant calculations and reorder floating-point constants to allow better constant folding
This commit is contained in:
Carlo Bramini 2019-06-27 17:20:13 +02:00 committed by Tom M
parent ef2c256e9e
commit 0b17a84ced
7 changed files with 102 additions and 98 deletions

View File

@ -73,7 +73,7 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
/* filter (implement the voice filter according to SoundFont standard) */
/* Check for denormal number (too close to zero). */
if(fabs(dsp_hist1) < 1e-20)
if(fabs(dsp_hist1) < 1e-20f)
{
dsp_hist1 = 0.0f; /* FIXME JMG - Is this even needed? */
}
@ -109,7 +109,7 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
dsp_b1 += dsp_b1_incr;
/* Compensate history to avoid the filter going havoc with large frequency changes */
if(iir_filter->compensate_incr && fabs(dsp_b02) > 0.001)
if(iir_filter->compensate_incr && fabs(dsp_b02) > 0.001f)
{
fluid_real_t compensate = old_b02 / dsp_b02;
dsp_hist1 *= compensate;
@ -352,10 +352,10 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter,
iir_filter->b02_incr = (b02_temp - iir_filter->b02) / transition_samples;
iir_filter->b1_incr = (b1_temp - iir_filter->b1) / transition_samples;
if(fabs(iir_filter->b02) > 0.0001)
if(fabs(iir_filter->b02) > 0.0001f)
{
fluid_real_t quota = b02_temp / iir_filter->b02;
iir_filter->compensate_incr = quota < 0.5 || quota > 2;
iir_filter->compensate_incr = quota < 0.5f || quota > 2.f;
}
/* Have to add the increments filter_coeff_incr_count times. */
@ -393,13 +393,13 @@ void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
{
fres = 0.45f * output_rate;
}
else if(fres < 5)
else if(fres < 5.f)
{
fres = 5;
fres = 5.f;
}
/* if filter enabled and there is a significant frequency change.. */
if(iir_filter->type != FLUID_IIR_DISABLED && fabs(fres - iir_filter->last_fres) > 0.01)
if(iir_filter->type != FLUID_IIR_DISABLED && fabs(fres - iir_filter->last_fres) > 0.01f)
{
/* The filter coefficients have to be recalculated (filter
* parameters have changed). Recalculation for various reasons is

View File

@ -193,9 +193,9 @@
#define DENORMALISING
#ifdef DENORMALISING
#define DC_OFFSET 1e-8
#define DC_OFFSET 1e-8f
#else
#define DC_OFFSET 0.0
#define DC_OFFSET 0.0f
#endif
/*----------------------------------------------------------------------------
@ -272,7 +272,7 @@ a flatter response on comb filter. So the input gain is set to 0.1 rather 1.0. *
#define INTERP_SAMPLES_NBR 1
/* phase offset between modulators waveform */
#define MOD_PHASE (360.0/(float) NBR_DELAYS)
#define MOD_PHASE (360.0f/(float) NBR_DELAYS)
#if (NBR_DELAYS == 8)
#define DELAY_L0 601
@ -453,15 +453,15 @@ static FLUID_INLINE fluid_real_t get_mod_sinus(sinus_modulator *mod)
out = mod->a1 * mod->buffer1 - mod->buffer2;
mod->buffer2 = mod->buffer1;
if(out >= 1.0) /* reset in case of instability near PI/2 */
if(out >= 1.0f) /* reset in case of instability near PI/2 */
{
out = 1.0; /* forces output to the right value */
out = 1.0f; /* forces output to the right value */
mod->buffer2 = mod->reset_buffer2;
}
if(out <= -1.0) /* reset in case of instability near -PI/2 */
if(out <= -1.0f) /* reset in case of instability near -PI/2 */
{
out = -1.0; /* forces output to the right value */
out = -1.0f; /* forces output to the right value */
mod->buffer2 = - mod->reset_buffer2;
}
@ -736,7 +736,7 @@ static void update_rev_time_damping(fluid_late *late,
fluid_real_t sample_period = 1 / late->samplerate; /* Sampling period */
fluid_real_t dc_rev_time; /* Reverb time at 0 Hz (in seconds) */
fluid_real_t alpha;
fluid_real_t alpha, alpha2;
/*--------------------------------------------
Computes dc_rev_time and alpha
@ -753,7 +753,7 @@ static void update_rev_time_damping(fluid_late *late,
------------------------------------------*/
dc_rev_time = GET_DC_REV_TIME(roomsize);
/* computes gi_tmp from dc_rev_time using relation E2 */
gi_tmp = (fluid_real_t) pow(10, -3 * delay_length[NBR_DELAYS - 1] *
gi_tmp = (fluid_real_t) pow(10.f, -3 * delay_length[NBR_DELAYS - 1] *
sample_period / dc_rev_time); /* E2 */
#else
/* roomsize parameters have the same response that Freeverb, that is:
@ -766,14 +766,14 @@ static void update_rev_time_damping(fluid_late *late,
fluid_real_t gi_min, gi_max;
/* values gi_min et gi_max are computed using E2 for the line with
maximum delay */
gi_max = (fluid_real_t)pow(10, -3 * delay_length[NBR_DELAYS - 1] *
gi_max = (fluid_real_t)pow(10.f, -3 * delay_length[NBR_DELAYS - 1] *
sample_period / MAX_DC_REV_TIME); /* E2 */
gi_min = (fluid_real_t)pow(10, -3 * delay_length[NBR_DELAYS - 1] *
gi_min = (fluid_real_t)pow(10.f, -3 * delay_length[NBR_DELAYS - 1] *
sample_period / MIN_DC_REV_TIME); /* E2 */
/* gi = f(roomsize, gi_max, gi_min) */
gi_tmp = gi_min + roomsize * (gi_max - gi_min);
/* Computes T60DC from gi using inverse of relation E2.*/
dc_rev_time = -3 * delay_length[NBR_DELAYS - 1] * sample_period / log10(gi_tmp);
dc_rev_time = -3 * M_LN10 * delay_length[NBR_DELAYS - 1] * sample_period / log(gi_tmp);
}
#endif /* ROOMSIZE_RESPONSE_LINEAR */
/*--------------------------------------------
@ -781,8 +781,12 @@ static void update_rev_time_damping(fluid_late *late,
----------------------------------------------*/
/* Computes alpha from damp,ai_tmp,gi_tmp using relation R */
/* - damp (0 to 1) controls concave reverb time for fs/2 frequency (T60DC to 0) */
ai_tmp = 1.0 * damp;
alpha = sqrt(1 / (1 - ai_tmp / (20 * log10(gi_tmp) * log(10) / 80))); /* R */
ai_tmp = 1.0f * damp;
/* Preserve the square of R */
alpha2 = 1.f / (1.f - ai_tmp / ((20.f / 80.f) * log(gi_tmp)));
alpha = sqrt(alpha2); /* R */
}
/* updates tone corrector coefficients b1,b2 from alpha */
@ -802,15 +806,15 @@ static void update_rev_time_damping(fluid_late *late,
for(i = 0; i < NBR_DELAYS; i++)
{
/* iir low pass filter gain */
fluid_real_t gi = (fluid_real_t)pow(10, -3 * delay_length[i] *
fluid_real_t gi = (fluid_real_t)pow(10.f, -3 * delay_length[i] *
sample_period / dc_rev_time);
/* iir low pass filter feedback gain */
fluid_real_t ai = (fluid_real_t)(20 * log10(gi) * log(10) / 80 *
(1 - 1 / pow(alpha, 2)));
fluid_real_t ai = (fluid_real_t)((20.f / 80.f) * log(gi) *
(1.f - 1.f / alpha2));
/* b0 = gi * (1 - ai), a1 = - ai */
set_fdn_delay_lpf(&late->mod_delay_lines[i].dl.damping,
gi * (1 - ai), -ai);
gi * (1.f - ai), -ai);
}
}

View File

@ -599,8 +599,8 @@ fluid_rvoice_noteoff_LOCAL(fluid_rvoice_t *voice, unsigned int min_ticks)
{
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 / M_LN10) * log(amp) - lfo) / FLUID_PEAK_ATTENUATION - 1);
fluid_clip(env_value, 0.0, 1.0);
fluid_real_t env_value = - (((-200.f / M_LN10) * log(amp) - lfo) / FLUID_PEAK_ATTENUATION - 1);
fluid_clip(env_value, 0.0f, 1.0f);
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
}
}
@ -712,7 +712,7 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack)
Here we need the inverse of fluid_convex() function defined as:
new_value = pow(10, (1 - current_val) . FLUID_PEAK_ATTENUATION / -200 . 2.0)
For performance reason we use fluid_cb2amp(Val) = pow(10, val/-200) with
val = (1 current_val) . FLUID_PEAK_ATTENUATION / 2.0
val = (1 - current_val) . FLUID_PEAK_ATTENUATION / 2.0
*/
fluid_real_t new_value; /* new modenv value */
new_value = fluid_cb2amp((1.0f - fluid_adsr_env_get_val(&voice->envlfo.modenv))

View File

@ -334,21 +334,21 @@ fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, cons
* is close enough.
*/
case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* custom sin(x) */
val = sin(M_PI / 2 * val_norm * 0.87);
val = sin((M_PI / 2.0f * 0.87f) * val_norm);
break;
case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* custom */
val = sin(M_PI / 2 * (1.0f - val_norm) * 0.87);
val = sin((M_PI / 2.0f * 0.87f) * (1.0f - val_norm));
break;
case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* custom */
val = (val_norm > 0.5f) ? sin(M_PI / 2 * 2 * (val_norm - 0.5f))
: -sin(M_PI / 2 * 2 * (0.5f - val_norm));
val = (val_norm > 0.5f) ? sin(M_PI * (val_norm - 0.5f))
: -sin(M_PI * (0.5f - val_norm));
break;
case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* custom */
val = (val_norm > 0.5f) ? -sin(M_PI / 2 * 2 * (val_norm - 0.5f))
: sin(M_PI / 2 * 2 * (0.5f - val_norm));
val = (val_norm > 0.5f) ? -sin(M_PI * (val_norm - 0.5f))
: sin(M_PI * (0.5f - val_norm));
break;
default:

View File

@ -1732,7 +1732,7 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */
fluid_synth_set_gen_LOCAL(synth, channum, GEN_FINETUNE,
(data - 8192) / 8192.0 * 100.0);
(float)(data - 8192) * (100.0f / 8192.0f));
break;
case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */
@ -5349,8 +5349,8 @@ fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double
int
fluid_synth_get_chorus_nr(fluid_synth_t *synth)
{
double result;
fluid_return_val_if_fail(synth != NULL, 0.0);
int result;
fluid_return_val_if_fail(synth != NULL, 0);
fluid_synth_api_enter(synth);
result = synth->chorus_nr;
@ -5413,8 +5413,8 @@ fluid_synth_get_chorus_depth(fluid_synth_t *synth)
int
fluid_synth_get_chorus_type(fluid_synth_t *synth)
{
double result;
fluid_return_val_if_fail(synth != NULL, 0.0);
int result;
fluid_return_val_if_fail(synth != NULL, 0);
fluid_synth_api_enter(synth);
result = synth->chorus_type;

View File

@ -344,9 +344,9 @@ fluid_voice_init(fluid_voice_t *voice, fluid_sample_t *sample,
voice->synth_gain = gain;
/* avoid division by zero later*/
if(voice->synth_gain < 0.0000001)
if(voice->synth_gain < 0.0000001f)
{
voice->synth_gain = 0.0000001;
voice->synth_gain = 0.0000001f;
}
UPDATE_RVOICE_R1(fluid_rvoice_set_synth_gain, voice->synth_gain);
@ -680,32 +680,32 @@ calculate_hold_decay_buffers(fluid_voice_t *voice, int gen_base,
if(is_decay)
{
/* SF 2.01 section 8.1.3 # 28, 36 */
if(timecents > 8000.0)
if(timecents > 8000.f)
{
timecents = 8000.0;
timecents = 8000.f;
}
}
else
{
/* SF 2.01 section 8.1.3 # 27, 35 */
if(timecents > 5000)
if(timecents > 5000.f)
{
timecents = 5000.0;
timecents = 5000.f;
}
/* SF 2.01 section 8.1.2 # 27, 35:
* The most negative number indicates no hold time
*/
if(timecents <= -32768.)
if(timecents <= -32768.f)
{
return 0;
}
}
/* SF 2.01 section 8.1.3 # 27, 28, 35, 36 */
if(timecents < -12000.0)
if(timecents < -12000.f)
{
timecents = -12000.0;
timecents = -12000.f;
}
seconds = fluid_tc2sec(timecents);
@ -714,7 +714,7 @@ calculate_hold_decay_buffers(fluid_voice_t *voice, int gen_base,
/* round to next full number of buffers */
buffers = (int)(((fluid_real_t)voice->output_rate * seconds)
/ (fluid_real_t)FLUID_BUFSIZE
+ 0.5);
+ 0.5f);
return buffers;
}
@ -774,7 +774,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
/* Range: SF2.01 section 8.1.3 # 48
* Motivation for range checking:
* OHPiano.SF2 sets initial attenuation to a whooping -96 dB */
fluid_clip(voice->attenuation, 0.0, 1440.0);
fluid_clip(voice->attenuation, 0.f, 1440.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_attenuation, voice->attenuation);
break;
@ -794,14 +794,14 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
case GEN_REVERBSEND:
/* The generator unit is 'tenths of a percent'. */
voice->reverb_send = x / 1000.0f;
fluid_clip(voice->reverb_send, 0.0, 1.0);
fluid_clip(voice->reverb_send, 0.f, 1.f);
UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 2, fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send));
break;
case GEN_CHORUSSEND:
/* The generator unit is 'tenths of a percent'. */
voice->chorus_send = x / 1000.0f;
fluid_clip(voice->chorus_send, 0.0, 1.0);
fluid_clip(voice->chorus_send, 0.f, 1.f);
UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 3, fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send));
break;
@ -870,17 +870,17 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
break;
case GEN_MODLFOTOPITCH:
fluid_clip(x, -12000.0, 12000.0);
fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_pitch, x);
break;
case GEN_MODLFOTOVOL:
fluid_clip(x, -960.0, 960.0);
fluid_clip(x, -960.f, 960.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_vol, x);
break;
case GEN_MODLFOTOFILTERFC:
fluid_clip(x, -12000, 12000);
fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_fc, x);
break;
@ -917,7 +917,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
break;
case GEN_VIBLFOTOPITCH:
fluid_clip(x, -12000.0, 12000.0);
fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_viblfo_to_pitch, x);
break;
@ -970,7 +970,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
break;
case GEN_MODENVTOPITCH:
fluid_clip(x, -12000.0, 12000.0);
fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modenv_to_pitch, x);
break;
@ -979,7 +979,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
* Motivation for range checking:
* Filter is reported to make funny noises now and then
*/
fluid_clip(x, -12000.0, 12000.0);
fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modenv_to_fc, x);
break;
@ -1271,7 +1271,7 @@ void fluid_voice_update_portamento(fluid_voice_t *voice, int fromkey, int tokey)
unsigned int countinc = (unsigned int)(((fluid_real_t)voice->output_rate *
0.001f *
(fluid_real_t)fluid_channel_portamentotime(channel)) /
(fluid_real_t)FLUID_BUFSIZE + 0.5);
(fluid_real_t)FLUID_BUFSIZE + 0.5f);
/* Send portamento parameters to the voice dsp */
UPDATE_RVOICE_GENERIC_IR(fluid_rvoice_set_portamento, voice->rvoice, countinc, pitchoffset);
@ -1745,7 +1745,7 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t *voice)
|| (mod->flags2 & FLUID_MOD_BIPOLAR)
|| (mod->amount < 0))
{
min_val *= -1.0; /* min_val = - |amount|*/
min_val = -min_val; /* min_val = - |amount|*/
}
else
{
@ -1792,9 +1792,9 @@ int fluid_voice_set_gain(fluid_voice_t *voice, fluid_real_t gain)
fluid_real_t left, right, reverb, chorus;
/* avoid division by zero*/
if(gain < 0.0000001)
if(gain < 0.0000001f)
{
gain = 0.0000001;
gain = 0.0000001f;
}
voice->synth_gain = gain;
@ -1964,9 +1964,9 @@ fluid_voice_get_overflow_prio(fluid_voice_t *voice,
// FIXME: Should take into account where on the envelope we are...?
}
if(a < 0.1)
if(a < 0.1f)
{
a = 0.1; // Avoid div by zero
a = 0.1f; // Avoid div by zero
}
this_voice_prio += score->volume / a;

View File

@ -150,7 +150,7 @@ fluid_tc2sec_delay(fluid_real_t tc)
return (fluid_real_t) 0.0f;
};
if(tc < -12000.)
if(tc < -12000.f)
{
tc = (fluid_real_t) -12000.0f;
}
@ -160,7 +160,7 @@ fluid_tc2sec_delay(fluid_real_t tc)
tc = (fluid_real_t) 5000.0f;
}
return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
return (fluid_real_t) pow(2.f, tc / 1200.f);
}
/*
@ -173,22 +173,22 @@ fluid_tc2sec_attack(fluid_real_t tc)
* SF2.01 section 8.1.3 items 26, 34
* The most negative number indicates a delay of 0
* Range is limited from -12000 to 8000 */
if(tc <= -32768.)
if(tc <= -32768.f)
{
return (fluid_real_t) 0.0;
return (fluid_real_t) 0.f;
};
if(tc < -12000.)
if(tc < -12000.f)
{
tc = (fluid_real_t) -12000.0;
tc = (fluid_real_t) -12000.f;
};
if(tc > 8000.)
if(tc > 8000.f)
{
tc = (fluid_real_t) 8000.0;
tc = (fluid_real_t) 8000.f;
};
return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
return (fluid_real_t) pow(2.f, tc / 1200.f);
}
/*
@ -198,7 +198,7 @@ fluid_real_t
fluid_tc2sec(fluid_real_t tc)
{
/* No range checking here! */
return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
return (fluid_real_t) pow(2.f, tc / 1200.f);
}
/*
@ -211,22 +211,22 @@ fluid_tc2sec_release(fluid_real_t tc)
* SF2.01 section 8.1.3 items 30, 38
* No 'most negative number' rule here!
* Range is limited from -12000 to 8000 */
if(tc <= -32768.)
if(tc <= -32768.f)
{
return (fluid_real_t) 0.0;
return (fluid_real_t) 0.f;
};
if(tc < -12000.)
if(tc < -12000.f)
{
tc = (fluid_real_t) -12000.0;
tc = (fluid_real_t) -12000.f;
};
if(tc > 8000.)
if(tc > 8000.f)
{
tc = (fluid_real_t) 8000.0;
tc = (fluid_real_t) 8000.f;
};
return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
return (fluid_real_t) pow(2.f, tc / 1200.f);
}
/*
@ -244,7 +244,7 @@ fluid_hz2ct(fluid_real_t f)
fluid_real_t
fluid_act2hz(fluid_real_t c)
{
return (fluid_real_t)(8.176 * pow(2.0, (double) c / 1200.0));
return (fluid_real_t)(8.176f * pow(2.f, c / 1200.f));
}
/*
@ -258,17 +258,17 @@ fluid_pan(fluid_real_t c, int left)
c = -c;
}
if(c <= -500)
if(c <= -500.f)
{
return (fluid_real_t) 0.0;
return (fluid_real_t) 0.f;
}
else if(c >= 500)
else if(c >= 500.f)
{
return (fluid_real_t) 1.0;
return (fluid_real_t) 1.f;
}
else
{
return fluid_pan_tab[(int)(c + 500)];
return fluid_pan_tab[(int)(c) + 500];
}
}
@ -284,17 +284,17 @@ fluid_pan(fluid_real_t c, int left)
fluid_real_t fluid_balance(fluid_real_t balance, int left)
{
/* This is the most common case */
if(balance == 0)
if(balance == 0.f)
{
return 1.0f;
}
if((left && balance < 0) || (!left && balance > 0))
if((left && balance < 0.f) || (!left && balance > 0.f))
{
return 1.0f;
}
if(balance < 0)
if(balance < 0.f)
{
balance = -balance;
}
@ -308,13 +308,13 @@ fluid_real_t fluid_balance(fluid_real_t balance, int left)
fluid_real_t
fluid_concave(fluid_real_t val)
{
if(val < 0)
if(val < 0.f)
{
return 0;
return 0.f;
}
else if(val >= FLUID_VEL_CB_SIZE)
else if(val >= (fluid_real_t)FLUID_VEL_CB_SIZE)
{
return 1;
return 1.f;
}
return fluid_concave_tab[(int) val];
@ -326,13 +326,13 @@ fluid_concave(fluid_real_t val)
fluid_real_t
fluid_convex(fluid_real_t val)
{
if(val < 0)
if(val < 0.f)
{
return 0;
return 0.f;
}
else if(val >= FLUID_VEL_CB_SIZE)
else if(val >= (fluid_real_t)FLUID_VEL_CB_SIZE)
{
return 1;
return 1.f;
}
return fluid_convex_tab[(int) val];