mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 06:51:54 +00:00
Add support for C99 math functions, if available (#545)
This commit is contained in:
parent
2be598b8e9
commit
a02f1379d8
8 changed files with 158 additions and 49 deletions
|
@ -666,6 +666,44 @@ endif()
|
|||
set(TEST_SOUNDFONT "${CMAKE_SOURCE_DIR}/sf2/VintageDreamsWaves-v2.sf2")
|
||||
set(TEST_SOUNDFONT_SF3 "${CMAKE_SOURCE_DIR}/sf2/VintageDreamsWaves-v2.sf3")
|
||||
|
||||
# Check for C99 float math
|
||||
|
||||
unset ( HAVE_SINF CACHE )
|
||||
CHECK_FUNCTION_EXISTS ( "sinf" HAVE_SINF )
|
||||
if ( HAVE_SINF )
|
||||
set ( HAVE_SINF 1 )
|
||||
endif ( HAVE_SINF )
|
||||
|
||||
unset ( HAVE_COSF CACHE )
|
||||
CHECK_FUNCTION_EXISTS ( "cosf" HAVE_COSF )
|
||||
if ( HAVE_COSF )
|
||||
set ( HAVE_COSF 1 )
|
||||
endif ( HAVE_COSF )
|
||||
|
||||
unset ( HAVE_FABSF CACHE )
|
||||
CHECK_FUNCTION_EXISTS ( "fabsf" HAVE_FABSF )
|
||||
if ( HAVE_FABSF )
|
||||
set ( HAVE_FABSF 1 )
|
||||
endif ( HAVE_FABSF )
|
||||
|
||||
unset ( HAVE_POWF CACHE )
|
||||
CHECK_FUNCTION_EXISTS ( "powf" HAVE_POWF )
|
||||
if ( HAVE_POWF )
|
||||
set ( HAVE_POWF 1 )
|
||||
endif ( HAVE_POWF )
|
||||
|
||||
unset ( HAVE_SQRTF CACHE )
|
||||
CHECK_FUNCTION_EXISTS ( "sqrtf" HAVE_SQRTF )
|
||||
if ( HAVE_SQRTF )
|
||||
set ( HAVE_SQRTF 1 )
|
||||
endif ( HAVE_SQRTF )
|
||||
|
||||
unset ( HAVE_LOGF CACHE )
|
||||
CHECK_FUNCTION_EXISTS ( "logf" HAVE_LOGF )
|
||||
if ( HAVE_LOGF )
|
||||
set ( HAVE_LOGF 1 )
|
||||
endif ( HAVE_LOGF )
|
||||
|
||||
# General configuration file
|
||||
configure_file ( ${CMAKE_SOURCE_DIR}/src/config.cmake
|
||||
${CMAKE_BINARY_DIR}/config.h )
|
||||
|
|
|
@ -251,4 +251,22 @@
|
|||
#cmakedefine inline @INLINE_KEYWORD@
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the sinf() function. */
|
||||
#cmakedefine HAVE_SINF @HAVE_SINF@
|
||||
|
||||
/* Define to 1 if you have the cosf() function. */
|
||||
#cmakedefine HAVE_COSF @HAVE_COSF@
|
||||
|
||||
/* Define to 1 if you have the fabsf() function. */
|
||||
#cmakedefine HAVE_FABSF @HAVE_FABSF@
|
||||
|
||||
/* Define to 1 if you have the powf() function. */
|
||||
#cmakedefine HAVE_POWF @HAVE_POWF@
|
||||
|
||||
/* Define to 1 if you have the sqrtf() function. */
|
||||
#cmakedefine HAVE_SQRTF @HAVE_SQRTF@
|
||||
|
||||
/* Define to 1 if you have the logf() function. */
|
||||
#cmakedefine HAVE_LOGF @HAVE_LOGF@
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
|
|
@ -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-20f)
|
||||
if(FLUID_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.001f)
|
||||
if(iir_filter->compensate_incr && FLUID_FABS(dsp_b02) > 0.001f)
|
||||
{
|
||||
fluid_real_t compensate = old_b02 / dsp_b02;
|
||||
dsp_hist1 *= compensate;
|
||||
|
@ -205,7 +205,7 @@ static fluid_real_t fluid_iir_filter_q_from_dB(fluid_real_t q_dB)
|
|||
|
||||
/* The 'sound font' Q is defined in dB. The filter needs a linear
|
||||
q. Convert. */
|
||||
return pow(10.0f, q_dB / 20.0f);
|
||||
return FLUID_POW(10.0f, q_dB / 20.0f);
|
||||
}
|
||||
|
||||
DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q)
|
||||
|
@ -247,7 +247,7 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q)
|
|||
* (numerator of the filter equation). This gain factor depends
|
||||
* only on Q, so this is the right place to calculate it.
|
||||
*/
|
||||
iir_filter->filter_gain /= sqrt(q);
|
||||
iir_filter->filter_gain /= FLUID_SQRT(q);
|
||||
}
|
||||
|
||||
/* The synthesis loop will have to recalculate the filter coefficients. */
|
||||
|
@ -277,8 +277,8 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter,
|
|||
|
||||
fluid_real_t omega = (fluid_real_t)(2.0 * M_PI) *
|
||||
(iir_filter->last_fres / output_rate);
|
||||
fluid_real_t sin_coeff = (fluid_real_t) sin(omega);
|
||||
fluid_real_t cos_coeff = (fluid_real_t) cos(omega);
|
||||
fluid_real_t sin_coeff = FLUID_SIN(omega);
|
||||
fluid_real_t cos_coeff = FLUID_COS(omega);
|
||||
fluid_real_t alpha_coeff = sin_coeff / (2.0f * iir_filter->q_lin);
|
||||
fluid_real_t a0_inv = 1.0f / (1.0f + alpha_coeff);
|
||||
|
||||
|
@ -352,7 +352,7 @@ 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.0001f)
|
||||
if(FLUID_FABS(iir_filter->b02) > 0.0001f)
|
||||
{
|
||||
fluid_real_t quota = b02_temp / iir_filter->b02;
|
||||
iir_filter->compensate_incr = quota < 0.5f || quota > 2.f;
|
||||
|
@ -399,7 +399,7 @@ void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
|
|||
}
|
||||
|
||||
/* if filter enabled and there is a significant frequency change.. */
|
||||
if(iir_filter->type != FLUID_IIR_DISABLED && fabs(fres - iir_filter->last_fres) > 0.01f)
|
||||
if(iir_filter->type != FLUID_IIR_DISABLED && FLUID_FABS(fres - iir_filter->last_fres) > 0.01f)
|
||||
{
|
||||
/* The filter coefficients have to be recalculated (filter
|
||||
* parameters have changed). Recalculation for various reasons is
|
||||
|
|
|
@ -431,12 +431,16 @@ typedef struct
|
|||
static void set_mod_frequency(sinus_modulator *mod,
|
||||
float freq, float sample_rate, float phase)
|
||||
{
|
||||
fluid_real_t w = 2 * M_PI * freq / sample_rate; /* intial angle */
|
||||
fluid_real_t w = 2 * FLUID_M_PI * freq / sample_rate; /* intial angle */
|
||||
fluid_real_t a;
|
||||
|
||||
mod->a1 = 2 * cos(w);
|
||||
mod->buffer2 = sin(2 * M_PI * phase / 360 - w); /* y(n-1) = sin(-intial angle) */
|
||||
mod->buffer1 = sin(2 * M_PI * phase / 360); /* y(n) = sin(initial phase) */
|
||||
mod->reset_buffer2 = sin(M_PI / 2.0 - w); /* reset value for PI/2 */
|
||||
mod->a1 = 2 * FLUID_COS(w);
|
||||
|
||||
a = (2 * FLUID_M_PI / 360) * phase;
|
||||
|
||||
mod->buffer2 = FLUID_SIN(a - w); /* y(n-1) = sin(-intial angle) */
|
||||
mod->buffer1 = FLUID_SIN(a); /* y(n) = sin(initial phase) */
|
||||
mod->reset_buffer2 = FLUID_SIN(FLUID_M_PI / 2 - w); /* reset value for PI/2 */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
@ -753,8 +757,8 @@ 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.f, -3 * delay_length[NBR_DELAYS - 1] *
|
||||
sample_period / dc_rev_time); /* E2 */
|
||||
gi_tmp = FLUID_POW(10, -3 * delay_length[NBR_DELAYS - 1] *
|
||||
sample_period / dc_rev_time); /* E2 */
|
||||
#else
|
||||
/* roomsize parameters have the same response that Freeverb, that is:
|
||||
* - roomsize (0 to 1) controls concave reverb time (0.7 to 10 s).
|
||||
|
@ -766,14 +770,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.f, -3 * delay_length[NBR_DELAYS - 1] *
|
||||
gi_max = FLUID_POW(10, -3 * delay_length[NBR_DELAYS - 1] *
|
||||
sample_period / MAX_DC_REV_TIME); /* E2 */
|
||||
gi_min = (fluid_real_t)pow(10.f, -3 * delay_length[NBR_DELAYS - 1] *
|
||||
gi_min = FLUID_POW(10, -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 * M_LN10 * delay_length[NBR_DELAYS - 1] * sample_period / log(gi_tmp);
|
||||
dc_rev_time = -3 * FLUID_M_LN10 * delay_length[NBR_DELAYS - 1] * sample_period / FLUID_LOGF(gi_tmp);
|
||||
}
|
||||
#endif /* ROOMSIZE_RESPONSE_LINEAR */
|
||||
/*--------------------------------------------
|
||||
|
@ -784,9 +788,9 @@ static void update_rev_time_damping(fluid_late *late,
|
|||
ai_tmp = 1.0f * damp;
|
||||
|
||||
/* Preserve the square of R */
|
||||
alpha2 = 1.f / (1.f - ai_tmp / ((20.f / 80.f) * log(gi_tmp)));
|
||||
alpha2 = 1.f / (1.f - ai_tmp / ((20.f / 80.f) * FLUID_LOGF(gi_tmp)));
|
||||
|
||||
alpha = sqrt(alpha2); /* R */
|
||||
alpha = FLUID_SQRT(alpha2); /* R */
|
||||
}
|
||||
|
||||
/* updates tone corrector coefficients b1,b2 from alpha */
|
||||
|
@ -806,12 +810,12 @@ 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.f, -3 * delay_length[i] *
|
||||
sample_period / dc_rev_time);
|
||||
fluid_real_t gi = FLUID_POW(10, -3 * delay_length[i] *
|
||||
sample_period / dc_rev_time);
|
||||
|
||||
/* iir low pass filter feedback gain */
|
||||
fluid_real_t ai = (fluid_real_t)((20.f / 80.f) * log(gi) *
|
||||
(1.f - 1.f / alpha2));
|
||||
fluid_real_t ai = (20.f / 80.f) * FLUID_LOGF(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.f - ai), -ai);
|
||||
|
|
|
@ -599,7 +599,7 @@ 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.f / M_LN10) * log(amp) - lfo) / FLUID_PEAK_ATTENUATION - 1);
|
||||
fluid_real_t env_value = - (((-200.f / FLUID_M_LN10) * FLUID_LOGF(amp) - lfo) / FLUID_PEAK_ATTENUATION - 1);
|
||||
fluid_clip(env_value, 0.0f, 1.0f);
|
||||
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
|
||||
}
|
||||
|
|
|
@ -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.0f * 0.87f) * val_norm);
|
||||
val = FLUID_SIN((FLUID_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.0f * 0.87f) * (1.0f - val_norm));
|
||||
val = FLUID_SIN((FLUID_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 * (val_norm - 0.5f))
|
||||
: -sin(M_PI * (0.5f - val_norm));
|
||||
val = (val_norm > 0.5f) ? FLUID_SIN(FLUID_M_PI * (val_norm - 0.5f))
|
||||
: -FLUID_SIN(FLUID_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 * (val_norm - 0.5f))
|
||||
: sin(M_PI * (0.5f - val_norm));
|
||||
val = (val_norm > 0.5f) ? -FLUID_SIN(FLUID_M_PI * (val_norm - 0.5f))
|
||||
: FLUID_SIN(FLUID_M_PI * (0.5f - val_norm));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -160,7 +160,7 @@ fluid_tc2sec_delay(fluid_real_t tc)
|
|||
tc = (fluid_real_t) 5000.0f;
|
||||
}
|
||||
|
||||
return (fluid_real_t) pow(2.f, tc / 1200.f);
|
||||
return FLUID_POW(2.f, tc / 1200.f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -188,7 +188,7 @@ fluid_tc2sec_attack(fluid_real_t tc)
|
|||
tc = (fluid_real_t) 8000.f;
|
||||
};
|
||||
|
||||
return (fluid_real_t) pow(2.f, tc / 1200.f);
|
||||
return FLUID_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.f, tc / 1200.f);
|
||||
return FLUID_POW(2.f, tc / 1200.f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -226,7 +226,7 @@ fluid_tc2sec_release(fluid_real_t tc)
|
|||
tc = (fluid_real_t) 8000.f;
|
||||
};
|
||||
|
||||
return (fluid_real_t) pow(2.f, tc / 1200.f);
|
||||
return FLUID_POW(2.f, tc / 1200.f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -238,13 +238,13 @@ fluid_tc2sec_release(fluid_real_t tc)
|
|||
*
|
||||
fluid_hz2ct(fluid_real_t f)
|
||||
{
|
||||
return (fluid_real_t)(6900 + (1200 / M_LN2) * log(f / 440.0));
|
||||
return 6900.f + (1200.f / FLUID_M_LN2) * FLUID_LOGF(f / 440.0f));
|
||||
}
|
||||
*/
|
||||
fluid_real_t
|
||||
fluid_act2hz(fluid_real_t c)
|
||||
{
|
||||
return (fluid_real_t)(8.176f * pow(2.f, c / 1200.f));
|
||||
return 8.176f * FLUID_POW(2.f, c / 1200.f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -126,19 +126,80 @@ typedef void (*fluid_rvoice_function_t)(void *obj, const fluid_rvoice_param_t pa
|
|||
* SYSTEM INTERFACE
|
||||
*/
|
||||
|
||||
/* Math constants */
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530941723212145818
|
||||
#endif
|
||||
|
||||
#ifndef M_LN10
|
||||
#define M_LN10 2.3025850929940456840179914546844
|
||||
#endif
|
||||
|
||||
#define FLUID_M_PI ((fluid_real_t)M_PI)
|
||||
#define FLUID_M_LN2 ((fluid_real_t)M_LN2)
|
||||
#define FLUID_M_LN10 ((fluid_real_t)M_LN10)
|
||||
|
||||
/* Math functions */
|
||||
#if defined WITH_FLOAT && defined HAVE_SINF
|
||||
#define FLUID_SIN sinf
|
||||
#else
|
||||
#define FLUID_SIN (fluid_real_t)sin
|
||||
#endif
|
||||
|
||||
#if defined WITH_FLOAT && defined HAVE_COSF
|
||||
#define FLUID_COS cosf
|
||||
#else
|
||||
#define FLUID_COS (fluid_real_t)cos
|
||||
#endif
|
||||
|
||||
#if defined WITH_FLOAT && defined HAVE_FABSF
|
||||
#define FLUID_FABS fabsf
|
||||
#else
|
||||
#define FLUID_FABS (fluid_real_t)fabs
|
||||
#endif
|
||||
|
||||
#if defined WITH_FLOAT && defined HAVE_POWF
|
||||
#define FLUID_POW powf
|
||||
#else
|
||||
#define FLUID_POW (fluid_real_t)pow
|
||||
#endif
|
||||
|
||||
#if defined WITH_FLOAT && defined HAVE_SQRTF
|
||||
#define FLUID_SQRT sqrtf
|
||||
#else
|
||||
#define FLUID_SQRT (fluid_real_t)sqrt
|
||||
#endif
|
||||
|
||||
#if defined WITH_FLOAT && defined HAVE_LOGF
|
||||
#define FLUID_LOGF logf
|
||||
#else
|
||||
#define FLUID_LOGF (fluid_real_t)log
|
||||
#endif
|
||||
|
||||
/* Memory allocation */
|
||||
#define FLUID_MALLOC(_n) malloc(_n)
|
||||
#define FLUID_REALLOC(_p,_n) realloc(_p,_n)
|
||||
#define FLUID_NEW(_t) (_t*)malloc(sizeof(_t))
|
||||
#define FLUID_ARRAY_ALIGNED(_t,_n,_a) (_t*)malloc((_n)*sizeof(_t) + ((unsigned int)_a - 1u))
|
||||
#define FLUID_ARRAY(_t,_n) FLUID_ARRAY_ALIGNED(_t,_n,1u)
|
||||
#define FLUID_FREE(_p) free(_p)
|
||||
|
||||
/* File access */
|
||||
#define FLUID_FOPEN(_f,_m) fopen(_f,_m)
|
||||
#define FLUID_FCLOSE(_f) fclose(_f)
|
||||
#define FLUID_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f)
|
||||
#define FLUID_FSEEK(_f,_n,_set) fseek(_f,_n,_set)
|
||||
#define FLUID_FTELL(_f) ftell(_f)
|
||||
|
||||
/* Memory functions */
|
||||
#define FLUID_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n)
|
||||
#define FLUID_MEMSET(_s,_c,_n) memset(_s,_c,_n)
|
||||
|
||||
/* String functions */
|
||||
#define FLUID_STRLEN(_s) strlen(_s)
|
||||
#define FLUID_STRCMP(_s,_t) strcmp(_s,_t)
|
||||
#define FLUID_STRNCMP(_s,_t,_n) strncmp(_s,_t,_n)
|
||||
|
@ -212,18 +273,6 @@ do { strncpy(_dst,_src,_n); \
|
|||
#define FLUID_LOG fluid_log
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530941723212145818
|
||||
#endif
|
||||
|
||||
#ifndef M_LN10
|
||||
#define M_LN10 2.3025850929940456840179914546844
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define FLUID_ASSERT(a) g_assert(a)
|
||||
#else
|
||||
|
|
Loading…
Reference in a new issue