diff options
author | Chris Robinson <[email protected]> | 2018-11-19 09:10:36 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-11-19 09:10:36 -0800 |
commit | 387a34ca002bdc25cc31fb8514c0fa2e44af6e1b (patch) | |
tree | 268ac0fff88d694d90502072e6fce2b38c831e10 | |
parent | 07386e79de93988faccc98166a036b6234ff9fe1 (diff) |
Clean up the biquad filter a bit
-rw-r--r-- | Alc/alu.cpp | 8 | ||||
-rw-r--r-- | Alc/effects/distortion.cpp | 4 | ||||
-rw-r--r-- | Alc/effects/echo.cpp | 2 | ||||
-rw-r--r-- | Alc/effects/equalizer.cpp | 8 | ||||
-rw-r--r-- | Alc/effects/modulator.cpp | 2 | ||||
-rw-r--r-- | Alc/effects/reverb.cpp | 8 | ||||
-rw-r--r-- | Alc/filters/defs.h | 43 | ||||
-rw-r--r-- | Alc/filters/filter.cpp | 24 |
8 files changed, 49 insertions, 50 deletions
diff --git a/Alc/alu.cpp b/Alc/alu.cpp index b4b34e5f..e30f6a2e 100644 --- a/Alc/alu.cpp +++ b/Alc/alu.cpp @@ -973,11 +973,11 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALflo if(gainHF != 1.0f) voice->Direct.FilterType |= AF_LowPass; if(gainLF != 1.0f) voice->Direct.FilterType |= AF_HighPass; BiquadFilter_setParams( - &voice->Direct.Params[0].LowPass, BiquadType_HighShelf, + &voice->Direct.Params[0].LowPass, BiquadType::HighShelf, gainHF, hfScale, calc_rcpQ_from_slope(gainHF, 1.0f) ); BiquadFilter_setParams( - &voice->Direct.Params[0].HighPass, BiquadType_LowShelf, + &voice->Direct.Params[0].HighPass, BiquadType::LowShelf, gainLF, lfScale, calc_rcpQ_from_slope(gainLF, 1.0f) ); for(c = 1;c < num_channels;c++) @@ -999,11 +999,11 @@ static void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALflo if(gainHF != 1.0f) voice->Send[i].FilterType |= AF_LowPass; if(gainLF != 1.0f) voice->Send[i].FilterType |= AF_HighPass; BiquadFilter_setParams( - &voice->Send[i].Params[0].LowPass, BiquadType_HighShelf, + &voice->Send[i].Params[0].LowPass, BiquadType::HighShelf, gainHF, hfScale, calc_rcpQ_from_slope(gainHF, 1.0f) ); BiquadFilter_setParams( - &voice->Send[i].Params[0].HighPass, BiquadType_LowShelf, + &voice->Send[i].Params[0].HighPass, BiquadType::LowShelf, gainLF, lfScale, calc_rcpQ_from_slope(gainLF, 1.0f) ); for(c = 1;c < num_channels;c++) diff --git a/Alc/effects/distortion.cpp b/Alc/effects/distortion.cpp index 31f07de3..69603db9 100644 --- a/Alc/effects/distortion.cpp +++ b/Alc/effects/distortion.cpp @@ -93,14 +93,14 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCcontex /* Multiply sampling frequency by the amount of oversampling done during * processing. */ - BiquadFilter_setParams(&state->lowpass, BiquadType_LowPass, 1.0f, + BiquadFilter_setParams(&state->lowpass, BiquadType::LowPass, 1.0f, cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth) ); cutoff = props->Distortion.EQCenter; /* Convert bandwidth in Hz to octaves. */ bandwidth = props->Distortion.EQBandwidth / (cutoff * 0.67f); - BiquadFilter_setParams(&state->bandpass, BiquadType_BandPass, 1.0f, + BiquadFilter_setParams(&state->bandpass, BiquadType::BandPass, 1.0f, cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth) ); diff --git a/Alc/effects/echo.cpp b/Alc/effects/echo.cpp index 47d21e6c..946c07b4 100644 --- a/Alc/effects/echo.cpp +++ b/Alc/effects/echo.cpp @@ -136,7 +136,7 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCcontext *context, state->FeedGain = props->Echo.Feedback; gainhf = maxf(1.0f - props->Echo.Damping, 0.0625f); /* Limit -24dB */ - BiquadFilter_setParams(&state->Filter, BiquadType_HighShelf, + BiquadFilter_setParams(&state->Filter, BiquadType::HighShelf, gainhf, LOWPASSFREQREF/frequency, calc_rcpQ_from_slope(gainhf, 1.0f) ); diff --git a/Alc/effects/equalizer.cpp b/Alc/effects/equalizer.cpp index 17eee5b4..ad101a7e 100644 --- a/Alc/effects/equalizer.cpp +++ b/Alc/effects/equalizer.cpp @@ -136,13 +136,13 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext */ gain = maxf(sqrtf(props->Equalizer.LowGain), 0.0625f); /* Limit -24dB */ f0norm = props->Equalizer.LowCutoff/frequency; - BiquadFilter_setParams(&state->Chans[0].filter[0], BiquadType_LowShelf, + BiquadFilter_setParams(&state->Chans[0].filter[0], BiquadType::LowShelf, gain, f0norm, calc_rcpQ_from_slope(gain, 0.75f) ); gain = maxf(props->Equalizer.Mid1Gain, 0.0625f); f0norm = props->Equalizer.Mid1Center/frequency; - BiquadFilter_setParams(&state->Chans[0].filter[1], BiquadType_Peaking, + BiquadFilter_setParams(&state->Chans[0].filter[1], BiquadType::Peaking, gain, f0norm, calc_rcpQ_from_bandwidth( f0norm, props->Equalizer.Mid1Width ) @@ -150,7 +150,7 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext gain = maxf(props->Equalizer.Mid2Gain, 0.0625f); f0norm = props->Equalizer.Mid2Center/frequency; - BiquadFilter_setParams(&state->Chans[0].filter[2], BiquadType_Peaking, + BiquadFilter_setParams(&state->Chans[0].filter[2], BiquadType::Peaking, gain, f0norm, calc_rcpQ_from_bandwidth( f0norm, props->Equalizer.Mid2Width ) @@ -158,7 +158,7 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCcontext gain = maxf(sqrtf(props->Equalizer.HighGain), 0.0625f); f0norm = props->Equalizer.HighCutoff/frequency; - BiquadFilter_setParams(&state->Chans[0].filter[3], BiquadType_HighShelf, + BiquadFilter_setParams(&state->Chans[0].filter[3], BiquadType::HighShelf, gain, f0norm, calc_rcpQ_from_slope(gain, 0.75f) ); diff --git a/Alc/effects/modulator.cpp b/Alc/effects/modulator.cpp index e96859f7..b7ee97d9 100644 --- a/Alc/effects/modulator.cpp +++ b/Alc/effects/modulator.cpp @@ -152,7 +152,7 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCcontext f0norm = props->Modulator.HighPassCutoff / (ALfloat)device->Frequency; f0norm = clampf(f0norm, 1.0f/512.0f, 0.49f); /* Bandwidth value is constant in octaves. */ - BiquadFilter_setParams(&state->Chans[0].Filter, BiquadType_HighPass, 1.0f, + BiquadFilter_setParams(&state->Chans[0].Filter, BiquadType::HighPass, 1.0f, f0norm, calc_rcpQ_from_bandwidth(f0norm, 0.75f)); for(i = 1;i < MAX_EFFECT_CHANNELS;i++) BiquadFilter_copyParams(&state->Chans[i].Filter, &state->Chans[0].Filter); diff --git a/Alc/effects/reverb.cpp b/Alc/effects/reverb.cpp index d486e8b4..68c76337 100644 --- a/Alc/effects/reverb.cpp +++ b/Alc/effects/reverb.cpp @@ -728,9 +728,9 @@ static void CalcT60DampingCoeffs(const ALfloat length, const ALfloat lfDecayTime ALfloat hfGain = CalcDecayCoeff(length, hfDecayTime); filter->MidGain[1] = mfGain; - BiquadFilter_setParams(&filter->LFFilter, BiquadType_LowShelf, lfGain/mfGain, lf0norm, + BiquadFilter_setParams(&filter->LFFilter, BiquadType::LowShelf, lfGain/mfGain, lf0norm, calc_rcpQ_from_slope(lfGain/mfGain, 1.0f)); - BiquadFilter_setParams(&filter->HFFilter, BiquadType_HighShelf, hfGain/mfGain, hf0norm, + BiquadFilter_setParams(&filter->HFFilter, BiquadType::HighShelf, hfGain/mfGain, hf0norm, calc_rcpQ_from_slope(hfGain/mfGain, 1.0f)); } @@ -964,11 +964,11 @@ static void ReverbState_update(ReverbState *State, const ALCcontext *Context, co * killing most of the signal. */ gainhf = maxf(props->Reverb.GainHF, 0.001f); - BiquadFilter_setParams(&State->Filter[0].Lp, BiquadType_HighShelf, gainhf, hf0norm, + BiquadFilter_setParams(&State->Filter[0].Lp, BiquadType::HighShelf, gainhf, hf0norm, calc_rcpQ_from_slope(gainhf, 1.0f)); lf0norm = minf(props->Reverb.LFReference / frequency, 0.49f); gainlf = maxf(props->Reverb.GainLF, 0.001f); - BiquadFilter_setParams(&State->Filter[0].Hp, BiquadType_LowShelf, gainlf, lf0norm, + BiquadFilter_setParams(&State->Filter[0].Hp, BiquadType::LowShelf, gainlf, lf0norm, calc_rcpQ_from_slope(gainlf, 1.0f)); for(i = 1;i < NUM_LINES;i++) { diff --git a/Alc/filters/defs.h b/Alc/filters/defs.h index 58b7cc0a..19514b62 100644 --- a/Alc/filters/defs.h +++ b/Alc/filters/defs.h @@ -1,12 +1,11 @@ #ifndef ALC_FILTER_H #define ALC_FILTER_H +#include <cmath> + #include "AL/al.h" #include "math_defs.h" -#ifdef __cplusplus -extern "C" { -#endif /* Filters implementation is based on the "Cookbook formulae for audio * EQ biquad filter coefficients" by Robert Bristow-Johnson @@ -18,28 +17,30 @@ extern "C" { * the square root of the desired linear gain (or halve the dB gain). */ -typedef enum BiquadType { +enum class BiquadType { /** EFX-style low-pass filter, specifying a gain and reference frequency. */ - BiquadType_HighShelf, + HighShelf, /** EFX-style high-pass filter, specifying a gain and reference frequency. */ - BiquadType_LowShelf, + LowShelf, /** Peaking filter, specifying a gain and reference frequency. */ - BiquadType_Peaking, + Peaking, /** Low-pass cut-off filter, specifying a cut-off frequency. */ - BiquadType_LowPass, + LowPass, /** High-pass cut-off filter, specifying a cut-off frequency. */ - BiquadType_HighPass, + HighPass, /** Band-pass filter, specifying a center frequency. */ - BiquadType_BandPass, -} BiquadType; + BandPass, +}; -typedef struct BiquadFilter { - ALfloat z1, z2; /* Last two delayed components for direct form II. */ - ALfloat b0, b1, b2; /* Transfer function coefficients "b" (numerator) */ - ALfloat a1, a2; /* Transfer function coefficients "a" (denominator; a0 is - * pre-applied). */ -} BiquadFilter; +struct BiquadFilter { + /* Last two delayed components for direct form II. */ + ALfloat z1{0.0f}, z2{0.0f}; + /* Transfer function coefficients "b" (numerator) */ + ALfloat b0{1.0f}, b1{0.0f}, b2{0.0f}; + /* Transfer function coefficients "a" (denominator; a0 is pre-applied). */ + ALfloat a1{0.0f}, a2{0.0f}; +}; /* Currently only a C-based filter process method is implemented. */ #define BiquadFilter_process BiquadFilter_processC @@ -51,7 +52,7 @@ typedef struct BiquadFilter { */ inline ALfloat calc_rcpQ_from_slope(ALfloat gain, ALfloat slope) { - return sqrtf((gain + 1.0f/gain)*(1.0f/slope - 1.0f) + 2.0f); + return std::sqrt((gain + 1.0f/gain)*(1.0f/slope - 1.0f) + 2.0f); } /** * Calculates the rcpQ (i.e. 1/Q) coefficient for filters, using the normalized @@ -62,7 +63,7 @@ inline ALfloat calc_rcpQ_from_slope(ALfloat gain, ALfloat slope) inline ALfloat calc_rcpQ_from_bandwidth(ALfloat f0norm, ALfloat bandwidth) { ALfloat w0 = F_TAU * f0norm; - return 2.0f*sinhf(logf(2.0f)/2.0f*bandwidth*w0/sinf(w0)); + return 2.0f*std::sinh(std::log(2.0f)/2.0f*bandwidth*w0/std::sin(w0)); } inline void BiquadFilter_clear(BiquadFilter *filter) @@ -113,8 +114,4 @@ inline void BiquadFilter_passthru(BiquadFilter *filter, ALsizei numsamples) } } -#ifdef __cplusplus -} // extern "C" -#endif - #endif /* ALC_FILTER_H */ diff --git a/Alc/filters/filter.cpp b/Alc/filters/filter.cpp index 838a9a5d..6099cf13 100644 --- a/Alc/filters/filter.cpp +++ b/Alc/filters/filter.cpp @@ -1,6 +1,8 @@ #include "config.h" +#include <cmath> + #include "AL/alc.h" #include "AL/al.h" @@ -19,15 +21,15 @@ void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, ALfloat gain, assert(gain > 0.00001f); w0 = F_TAU * f0norm; - sin_w0 = sinf(w0); - cos_w0 = cosf(w0); + sin_w0 = std::sin(w0); + cos_w0 = std::cos(w0); alpha = sin_w0/2.0f * rcpQ; /* Calculate filter coefficients depending on filter type */ switch(type) { - case BiquadType_HighShelf: - sqrtgain_alpha_2 = 2.0f * sqrtf(gain) * alpha; + case BiquadType::HighShelf: + sqrtgain_alpha_2 = 2.0f * std::sqrt(gain) * alpha; b[0] = gain*((gain+1.0f) + (gain-1.0f)*cos_w0 + sqrtgain_alpha_2); b[1] = -2.0f*gain*((gain-1.0f) + (gain+1.0f)*cos_w0 ); b[2] = gain*((gain+1.0f) + (gain-1.0f)*cos_w0 - sqrtgain_alpha_2); @@ -35,8 +37,8 @@ void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, ALfloat gain, a[1] = 2.0f* ((gain-1.0f) - (gain+1.0f)*cos_w0 ); a[2] = (gain+1.0f) - (gain-1.0f)*cos_w0 - sqrtgain_alpha_2; break; - case BiquadType_LowShelf: - sqrtgain_alpha_2 = 2.0f * sqrtf(gain) * alpha; + case BiquadType::LowShelf: + sqrtgain_alpha_2 = 2.0f * std::sqrt(gain) * alpha; b[0] = gain*((gain+1.0f) - (gain-1.0f)*cos_w0 + sqrtgain_alpha_2); b[1] = 2.0f*gain*((gain-1.0f) - (gain+1.0f)*cos_w0 ); b[2] = gain*((gain+1.0f) - (gain-1.0f)*cos_w0 - sqrtgain_alpha_2); @@ -44,8 +46,8 @@ void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, ALfloat gain, a[1] = -2.0f* ((gain-1.0f) + (gain+1.0f)*cos_w0 ); a[2] = (gain+1.0f) + (gain-1.0f)*cos_w0 - sqrtgain_alpha_2; break; - case BiquadType_Peaking: - gain = sqrtf(gain); + case BiquadType::Peaking: + gain = std::sqrt(gain); b[0] = 1.0f + alpha * gain; b[1] = -2.0f * cos_w0; b[2] = 1.0f - alpha * gain; @@ -54,7 +56,7 @@ void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, ALfloat gain, a[2] = 1.0f - alpha / gain; break; - case BiquadType_LowPass: + case BiquadType::LowPass: b[0] = (1.0f - cos_w0) / 2.0f; b[1] = 1.0f - cos_w0; b[2] = (1.0f - cos_w0) / 2.0f; @@ -62,7 +64,7 @@ void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, ALfloat gain, a[1] = -2.0f * cos_w0; a[2] = 1.0f - alpha; break; - case BiquadType_HighPass: + case BiquadType::HighPass: b[0] = (1.0f + cos_w0) / 2.0f; b[1] = -(1.0f + cos_w0); b[2] = (1.0f + cos_w0) / 2.0f; @@ -70,7 +72,7 @@ void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, ALfloat gain, a[1] = -2.0f * cos_w0; a[2] = 1.0f - alpha; break; - case BiquadType_BandPass: + case BiquadType::BandPass: b[0] = alpha; b[1] = 0; b[2] = -alpha; |