diff options
author | Chris Robinson <[email protected]> | 2018-12-04 22:31:08 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-12-04 22:31:08 -0800 |
commit | 164a86a381e4f51383c6afbfdf63dadd3ecb3785 (patch) | |
tree | 98287b6d44082e4b905eddeb2e70ebc8cf8bfd0a /Alc | |
parent | 36a8b615c883ccc90705b97402e2e2046058720a (diff) |
Use class methods for the biquad filter
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/alu.cpp | 24 | ||||
-rw-r--r-- | Alc/effects/distortion.cpp | 16 | ||||
-rw-r--r-- | Alc/effects/echo.cpp | 17 | ||||
-rw-r--r-- | Alc/effects/equalizer.cpp | 36 | ||||
-rw-r--r-- | Alc/effects/modulator.cpp | 10 | ||||
-rw-r--r-- | Alc/effects/reverb.cpp | 36 | ||||
-rw-r--r-- | Alc/filters/defs.h | 110 | ||||
-rw-r--r-- | Alc/filters/filter.cpp | 34 | ||||
-rw-r--r-- | Alc/mixvoice.cpp | 16 |
9 files changed, 146 insertions, 153 deletions
diff --git a/Alc/alu.cpp b/Alc/alu.cpp index de46633a..f3fa15ec 100644 --- a/Alc/alu.cpp +++ b/Alc/alu.cpp @@ -964,20 +964,16 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev voice->Direct.FilterType = AF_None; 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.setParams(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.setParams(BiquadType::LowShelf, gainLF, lfScale, calc_rcpQ_from_slope(gainLF, 1.0f) ); for(c = 1;c < num_channels;c++) { - BiquadFilter_copyParams(&voice->Direct.Params[c].LowPass, - &voice->Direct.Params[0].LowPass); - BiquadFilter_copyParams(&voice->Direct.Params[c].HighPass, - &voice->Direct.Params[0].HighPass); + voice->Direct.Params[c].LowPass.copyParamsFrom(voice->Direct.Params[0].LowPass); + voice->Direct.Params[c].HighPass.copyParamsFrom(voice->Direct.Params[0].HighPass); } } for(i = 0;i < NumSends;i++) @@ -990,20 +986,16 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev voice->Send[i].FilterType = AF_None; 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.setParams(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.setParams(BiquadType::LowShelf, gainLF, lfScale, calc_rcpQ_from_slope(gainLF, 1.0f) ); for(c = 1;c < num_channels;c++) { - BiquadFilter_copyParams(&voice->Send[i].Params[c].LowPass, - &voice->Send[i].Params[0].LowPass); - BiquadFilter_copyParams(&voice->Send[i].Params[c].HighPass, - &voice->Send[i].Params[0].HighPass); + voice->Send[i].Params[c].LowPass.copyParamsFrom(voice->Send[i].Params[0].LowPass); + voice->Send[i].Params[c].HighPass.copyParamsFrom(voice->Send[i].Params[0].HighPass); } } } diff --git a/Alc/effects/distortion.cpp b/Alc/effects/distortion.cpp index a2681e3d..b3d339ad 100644 --- a/Alc/effects/distortion.cpp +++ b/Alc/effects/distortion.cpp @@ -53,8 +53,8 @@ struct ALdistortionState final : public EffectState { ALboolean ALdistortionState::deviceUpdate(ALCdevice *UNUSED(device)) { - BiquadFilter_clear(&mLowpass); - BiquadFilter_clear(&mBandpass); + mLowpass.clear(); + mBandpass.clear(); return AL_TRUE; } @@ -78,15 +78,15 @@ void ALdistortionState::update(const ALCcontext *context, const ALeffectslot *sl /* Multiply sampling frequency by the amount of oversampling done during * processing. */ - BiquadFilter_setParams(&mLowpass, BiquadType::LowPass, 1.0f, - cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth) + mLowpass.setParams(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(&mBandpass, BiquadType::BandPass, 1.0f, - cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth) + mBandpass.setParams(BiquadType::BandPass, 1.0f, cutoff / (frequency*4.0f), + calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth) ); CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs); @@ -120,7 +120,7 @@ void ALdistortionState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT Sa * (which is fortunately first step of distortion). So combine three * operations into the one. */ - BiquadFilter_process(&mLowpass, buffer[1], buffer[0], todo); + mLowpass.process(buffer[1], buffer[0], todo); /* Second step, do distortion using waveshaper function to emulate * signal processing during tube overdriving. Three steps of @@ -139,7 +139,7 @@ void ALdistortionState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT Sa } /* Third step, do bandpass filtering of distorted signal. */ - BiquadFilter_process(&mBandpass, buffer[1], buffer[0], todo); + mBandpass.process(buffer[1], buffer[0], todo); todo >>= 2; for(k = 0;k < NumChannels;k++) diff --git a/Alc/effects/echo.cpp b/Alc/effects/echo.cpp index 58728b50..91bdde9a 100644 --- a/Alc/effects/echo.cpp +++ b/Alc/effects/echo.cpp @@ -112,8 +112,8 @@ void ALechoState::update(const ALCcontext *context, const ALeffectslot *slot, co mFeedGain = props->Echo.Feedback; gainhf = maxf(1.0f - props->Echo.Damping, 0.0625f); /* Limit -24dB */ - BiquadFilter_setParams(&mFilter, BiquadType::HighShelf, - gainhf, LOWPASSFREQREF/frequency, calc_rcpQ_from_slope(gainhf, 1.0f) + mFilter.setParams(BiquadType::HighShelf, gainhf, LOWPASSFREQREF/frequency, + calc_rcpQ_from_slope(gainhf, 1.0f) ); /* First tap panning */ @@ -132,12 +132,11 @@ void ALechoState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesI const ALsizei tap2 = mTap[1].delay; ALfloat *RESTRICT delaybuf = mSampleBuffer.data(); ALsizei offset = mOffset; - ALfloat z1, z2, in, out; + ALfloat z1, z2; ALsizei base; ALsizei c, i; - z1 = mFilter.z1; - z2 = mFilter.z2; + std::tie(z1, z2) = mFilter.getComponents(); for(base = 0;base < SamplesToDo;) { alignas(16) ALfloat temps[2][128]; @@ -156,10 +155,7 @@ void ALechoState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesI /* Apply damping to the second tap, then add it to the buffer with * feedback attenuation. */ - in = temps[1][i]; - out = in*mFilter.b0 + z1; - z1 = in*mFilter.b1 - out*mFilter.a1 + z2; - z2 = in*mFilter.b2 - out*mFilter.a2; + float out{mFilter.processOne(temps[1][i], z1, z2)}; delaybuf[offset&mask] += out * mFeedGain; offset++; @@ -171,8 +167,7 @@ void ALechoState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesI base += td; } - mFilter.z1 = z1; - mFilter.z2 = z2; + mFilter.setComponents(z1, z2); mOffset = offset; } diff --git a/Alc/effects/equalizer.cpp b/Alc/effects/equalizer.cpp index 6329ede2..af571930 100644 --- a/Alc/effects/equalizer.cpp +++ b/Alc/effects/equalizer.cpp @@ -101,9 +101,7 @@ ALboolean ALequalizerState::deviceUpdate(ALCdevice *UNUSED(device)) for(auto &e : mChans) { std::for_each(std::begin(e.filter), std::end(e.filter), - [](BiquadFilter &f) -> void - { BiquadFilter_clear(&f); } - ); + std::mem_fun_ref(&BiquadFilter::clear)); std::fill(std::begin(e.CurrentGains), std::end(e.CurrentGains), 0.0f); } return AL_TRUE; @@ -122,35 +120,35 @@ void ALequalizerState::update(const ALCcontext *context, const ALeffectslot *slo */ gain = maxf(sqrtf(props->Equalizer.LowGain), 0.0625f); /* Limit -24dB */ f0norm = props->Equalizer.LowCutoff/frequency; - BiquadFilter_setParams(&mChans[0].filter[0], BiquadType::LowShelf, - gain, f0norm, calc_rcpQ_from_slope(gain, 0.75f) + mChans[0].filter[0].setParams(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(&mChans[0].filter[1], BiquadType::Peaking, - gain, f0norm, calc_rcpQ_from_bandwidth(f0norm, props->Equalizer.Mid1Width) + mChans[0].filter[1].setParams(BiquadType::Peaking, gain, f0norm, + calc_rcpQ_from_bandwidth(f0norm, props->Equalizer.Mid1Width) ); gain = maxf(props->Equalizer.Mid2Gain, 0.0625f); f0norm = props->Equalizer.Mid2Center/frequency; - BiquadFilter_setParams(&mChans[0].filter[2], BiquadType::Peaking, - gain, f0norm, calc_rcpQ_from_bandwidth(f0norm, props->Equalizer.Mid2Width) + mChans[0].filter[2].setParams(BiquadType::Peaking, gain, f0norm, + calc_rcpQ_from_bandwidth(f0norm, props->Equalizer.Mid2Width) ); gain = maxf(sqrtf(props->Equalizer.HighGain), 0.0625f); f0norm = props->Equalizer.HighCutoff/frequency; - BiquadFilter_setParams(&mChans[0].filter[3], BiquadType::HighShelf, - gain, f0norm, calc_rcpQ_from_slope(gain, 0.75f) + mChans[0].filter[3].setParams(BiquadType::HighShelf, gain, f0norm, + calc_rcpQ_from_slope(gain, 0.75f) ); /* Copy the filter coefficients for the other input channels. */ for(i = 1;i < MAX_EFFECT_CHANNELS;i++) { - BiquadFilter_copyParams(&mChans[i].filter[0], &mChans[0].filter[0]); - BiquadFilter_copyParams(&mChans[i].filter[1], &mChans[0].filter[1]); - BiquadFilter_copyParams(&mChans[i].filter[2], &mChans[0].filter[2]); - BiquadFilter_copyParams(&mChans[i].filter[3], &mChans[0].filter[3]); + mChans[i].filter[0].copyParamsFrom(mChans[0].filter[0]); + mChans[i].filter[1].copyParamsFrom(mChans[0].filter[1]); + mChans[i].filter[2].copyParamsFrom(mChans[0].filter[2]); + mChans[i].filter[3].copyParamsFrom(mChans[0].filter[3]); } mOutBuffer = device->FOAOut.Buffer; @@ -167,10 +165,10 @@ void ALequalizerState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT Sam for(c = 0;c < MAX_EFFECT_CHANNELS;c++) { - BiquadFilter_process(&mChans[c].filter[0], temps[0], SamplesIn[c], SamplesToDo); - BiquadFilter_process(&mChans[c].filter[1], temps[1], temps[0], SamplesToDo); - BiquadFilter_process(&mChans[c].filter[2], temps[2], temps[1], SamplesToDo); - BiquadFilter_process(&mChans[c].filter[3], temps[3], temps[2], SamplesToDo); + mChans[c].filter[0].process(temps[0], SamplesIn[c], SamplesToDo); + mChans[c].filter[1].process(temps[1], temps[0], SamplesToDo); + mChans[c].filter[2].process(temps[2], temps[1], SamplesToDo); + mChans[c].filter[3].process(temps[3], temps[2], SamplesToDo); MixSamples(temps[3], NumChannels, SamplesOut, mChans[c].CurrentGains, mChans[c].TargetGains, SamplesToDo, 0, SamplesToDo); diff --git a/Alc/effects/modulator.cpp b/Alc/effects/modulator.cpp index ac71e444..3d41bb65 100644 --- a/Alc/effects/modulator.cpp +++ b/Alc/effects/modulator.cpp @@ -99,7 +99,7 @@ ALboolean ALmodulatorState::deviceUpdate(ALCdevice *UNUSED(device)) { for(auto &e : mChans) { - BiquadFilter_clear(&e.Filter); + e.Filter.clear(); std::fill(std::begin(e.CurrentGains), std::end(e.CurrentGains), 0.0f); } return AL_TRUE; @@ -126,10 +126,10 @@ void ALmodulatorState::update(const ALCcontext *context, const ALeffectslot *slo f0norm = props->Modulator.HighPassCutoff / (ALfloat)device->Frequency; f0norm = clampf(f0norm, 1.0f/512.0f, 0.49f); /* Bandwidth value is constant in octaves. */ - BiquadFilter_setParams(&mChans[0].Filter, BiquadType::HighPass, 1.0f, - f0norm, calc_rcpQ_from_bandwidth(f0norm, 0.75f)); + mChans[0].Filter.setParams(BiquadType::HighPass, 1.0f, f0norm, + calc_rcpQ_from_bandwidth(f0norm, 0.75f)); for(i = 1;i < MAX_EFFECT_CHANNELS;i++) - BiquadFilter_copyParams(&mChans[i].Filter, &mChans[0].Filter); + mChans[i].Filter.copyParamsFrom(mChans[0].Filter); mOutBuffer = device->FOAOut.Buffer; mOutChannels = device->FOAOut.NumChannels; @@ -157,7 +157,7 @@ void ALmodulatorState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT Sam { alignas(16) ALfloat temps[MAX_UPDATE_SAMPLES]; - BiquadFilter_process(&mChans[c].Filter, temps, &SamplesIn[c][base], td); + mChans[c].Filter.process(temps, &SamplesIn[c][base], td); for(i = 0;i < td;i++) temps[i] *= modsamples[i]; diff --git a/Alc/effects/reverb.cpp b/Alc/effects/reverb.cpp index bf2e9a6f..ce7a9946 100644 --- a/Alc/effects/reverb.cpp +++ b/Alc/effects/reverb.cpp @@ -478,8 +478,8 @@ ALboolean ReverbState::deviceUpdate(ALCdevice *Device) */ for(i = 0;i < NUM_LINES;i++) { - BiquadFilter_clear(&mFilter[i].Lp); - BiquadFilter_clear(&mFilter[i].Hp); + mFilter[i].Lp.clear(); + mFilter[i].Hp.clear(); } for(i = 0;i < NUM_LINES;i++) @@ -500,8 +500,8 @@ ALboolean ReverbState::deviceUpdate(ALCdevice *Device) { mLate.T60[i].MidGain[0] = 0.0f; mLate.T60[i].MidGain[1] = 0.0f; - BiquadFilter_clear(&mLate.T60[i].HFFilter); - BiquadFilter_clear(&mLate.T60[i].LFFilter); + mLate.T60[i].HFFilter.clear(); + mLate.T60[i].LFFilter.clear(); } for(i = 0;i < NUM_LINES;i++) @@ -615,10 +615,10 @@ 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, - calc_rcpQ_from_slope(lfGain/mfGain, 1.0f)); - BiquadFilter_setParams(&filter->HFFilter, BiquadType::HighShelf, hfGain/mfGain, hf0norm, - calc_rcpQ_from_slope(hfGain/mfGain, 1.0f)); + filter->LFFilter.setParams(BiquadType::LowShelf, lfGain/mfGain, lf0norm, + calc_rcpQ_from_slope(lfGain/mfGain, 1.0f)); + filter->HFFilter.setParams(BiquadType::HighShelf, hfGain/mfGain, hf0norm, + calc_rcpQ_from_slope(hfGain/mfGain, 1.0f)); } /* Update the offsets for the main effect delay line. */ @@ -851,16 +851,16 @@ void ReverbState::update(const ALCcontext *Context, const ALeffectslot *Slot, co * killing most of the signal. */ gainhf = maxf(props->Reverb.GainHF, 0.001f); - BiquadFilter_setParams(&mFilter[0].Lp, BiquadType::HighShelf, gainhf, hf0norm, - calc_rcpQ_from_slope(gainhf, 1.0f)); + mFilter[0].Lp.setParams(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(&mFilter[0].Hp, BiquadType::LowShelf, gainlf, lf0norm, - calc_rcpQ_from_slope(gainlf, 1.0f)); + mFilter[0].Hp.setParams(BiquadType::LowShelf, gainlf, lf0norm, + calc_rcpQ_from_slope(gainlf, 1.0f)); for(i = 1;i < NUM_LINES;i++) { - BiquadFilter_copyParams(&mFilter[i].Lp, &mFilter[0].Lp); - BiquadFilter_copyParams(&mFilter[i].Hp, &mFilter[0].Hp); + mFilter[i].Lp.copyParamsFrom(mFilter[0].Lp); + mFilter[i].Hp.copyParamsFrom(mFilter[0].Hp); } /* Update the main effect delay and associated taps. */ @@ -1245,8 +1245,8 @@ static void EarlyReflection_Faded(ReverbState *State, ALsizei offset, const ALsi static inline void LateT60Filter(ALfloat *RESTRICT samples, const ALsizei todo, T60Filter *filter) { ALfloat temp[MAX_UPDATE_SAMPLES]; - BiquadFilter_process(&filter->HFFilter, temp, samples, todo); - BiquadFilter_process(&filter->LFFilter, samples, temp, todo); + filter->HFFilter.process(temp, samples, todo); + filter->LFFilter.process(samples, temp, todo); } /* This generates the reverb tail using a modified feed-back delay network @@ -1389,8 +1389,8 @@ void ReverbState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesI for(c = 0;c < NUM_LINES;c++) { /* Band-pass the incoming samples. */ - BiquadFilter_process(&mFilter[c].Lp, samples[0], afmt[c], todo); - BiquadFilter_process(&mFilter[c].Hp, samples[1], samples[0], todo); + mFilter[c].Lp.process(samples[0], afmt[c], todo); + mFilter[c].Hp.process(samples[1], samples[0], todo); /* Feed the initial delay line. */ DelayLineIn(&mDelay, offset, c, samples[1], todo); diff --git a/Alc/filters/defs.h b/Alc/filters/defs.h index fb8c9312..b7628153 100644 --- a/Alc/filters/defs.h +++ b/Alc/filters/defs.h @@ -33,16 +33,72 @@ enum class BiquadType { BandPass, }; -struct BiquadFilter { +class BiquadFilter { /* Last two delayed components for direct form II. */ float z1{0.0f}, z2{0.0f}; /* Transfer function coefficients "b" (numerator) */ float b0{1.0f}, b1{0.0f}, b2{0.0f}; /* Transfer function coefficients "a" (denominator; a0 is pre-applied). */ float a1{0.0f}, a2{0.0f}; + +public: + void clear() noexcept { z1 = z2 = 0.0f; } + + /** + * Sets the filter state for the specified filter type and its parameters. + * + * \param type The type of filter to apply. + * \param gain The gain for the reference frequency response. Only used by + * the Shelf and Peaking filter types. + * \param f0norm The reference frequency normal (ref_freq / sample_rate). + * This is the center point for the Shelf, Peaking, and + * BandPass filter types, or the cutoff frequency for the + * LowPass and HighPass filter types. + * \param rcpQ The reciprocal of the Q coefficient for the filter's + * transition band. Can be generated from calc_rcpQ_from_slope + * or calc_rcpQ_from_bandwidth as needed. + */ + void setParams(BiquadType type, float gain, float f0norm, float rcpQ); + + void copyParamsFrom(const BiquadFilter &other) + { + b0 = other.b0; + b1 = other.b1; + b2 = other.b2; + a1 = other.a1; + a2 = other.a2; + } + + + void process(float *RESTRICT dst, const float *RESTRICT src, int numsamples); + + void passthru(int numsamples) noexcept + { + if(LIKELY(numsamples >= 2)) + { + z1 = 0.0f; + z2 = 0.0f; + } + else if(numsamples == 1) + { + z1 = z2; + z2 = 0.0f; + } + } + + /* Rather hacky. It's just here to support "manual" processing. */ + std::pair<float,float> getComponents() const noexcept + { return {z1, z2}; } + void setComponents(float z1_, float z2_) noexcept + { z1 = z1_; z2 = z2_; } + float processOne(const float in, float &z1_, float &z2_) const noexcept + { + float out{in*b0 + z1_}; + z1_ = in*b1 - out*a1 + z2_; + z2_ = in*b2 - out*a2; + return out; + } }; -/* Currently only a C-based filter process method is implemented. */ -#define BiquadFilter_process BiquadFilter_processC /** * Calculates the rcpQ (i.e. 1/Q) coefficient for shelving filters, using the @@ -66,52 +122,4 @@ inline ALfloat calc_rcpQ_from_bandwidth(float f0norm, float bandwidth) return 2.0f*std::sinh(std::log(2.0f)/2.0f*bandwidth*w0/std::sin(w0)); } -inline void BiquadFilter_clear(BiquadFilter *filter) -{ - filter->z1 = 0.0f; - filter->z2 = 0.0f; -} - -/** - * Sets up the filter state for the specified filter type and its parameters. - * - * \param filter The filter object to prepare. - * \param type The type of filter for the object to apply. - * \param gain The gain for the reference frequency response. Only used by the - * Shelf and Peaking filter types. - * \param f0norm The normalized reference frequency (ref_freq / sample_rate). - * This is the center point for the Shelf, Peaking, and BandPass - * filter types, or the cutoff frequency for the LowPass and - * HighPass filter types. - * \param rcpQ The reciprocal of the Q coefficient for the filter's transition - * band. Can be generated from calc_rcpQ_from_slope or - * calc_rcpQ_from_bandwidth depending on the available data. - */ -void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, float gain, float f0norm, float rcpQ); - -inline void BiquadFilter_copyParams(BiquadFilter *RESTRICT dst, const BiquadFilter *RESTRICT src) -{ - dst->b0 = src->b0; - dst->b1 = src->b1; - dst->b2 = src->b2; - dst->a1 = src->a1; - dst->a2 = src->a2; -} - -void BiquadFilter_processC(BiquadFilter *filter, float *RESTRICT dst, const float *RESTRICT src, int numsamples); - -inline void BiquadFilter_passthru(BiquadFilter *filter, int numsamples) -{ - if(LIKELY(numsamples >= 2)) - { - filter->z1 = 0.0f; - filter->z2 = 0.0f; - } - else if(numsamples == 1) - { - filter->z1 = filter->z2; - filter->z2 = 0.0f; - } -} - #endif /* ALC_FILTER_H */ diff --git a/Alc/filters/filter.cpp b/Alc/filters/filter.cpp index 980841c0..c9e7c9fe 100644 --- a/Alc/filters/filter.cpp +++ b/Alc/filters/filter.cpp @@ -10,7 +10,7 @@ #include "defs.h" -void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, float gain, float f0norm, float rcpQ) +void BiquadFilter::setParams(BiquadType type, float gain, float f0norm, float rcpQ) { float alpha, sqrtgain_alpha_2; float w0, sin_w0, cos_w0; @@ -82,25 +82,25 @@ void BiquadFilter_setParams(BiquadFilter *filter, BiquadType type, float gain, f break; } - filter->a1 = a[1] / a[0]; - filter->a2 = a[2] / a[0]; - filter->b0 = b[0] / a[0]; - filter->b1 = b[1] / a[0]; - filter->b2 = b[2] / a[0]; + a1 = a[1] / a[0]; + a2 = a[2] / a[0]; + b0 = b[0] / a[0]; + b1 = b[1] / a[0]; + b2 = b[2] / a[0]; } -void BiquadFilter_processC(BiquadFilter *filter, float *RESTRICT dst, const float *RESTRICT src, int numsamples) +void BiquadFilter::process(float *RESTRICT dst, const float *RESTRICT src, int numsamples) { ASSUME(numsamples > 0); - const float b0{filter->b0}; - const float b1{filter->b1}; - const float b2{filter->b2}; - const float a1{filter->a1}; - const float a2{filter->a2}; - float z1{filter->z1}; - float z2{filter->z2}; + const float b0{this->b0}; + const float b1{this->b1}; + const float b2{this->b2}; + const float a1{this->a1}; + const float a2{this->a2}; + float z1{this->z1}; + float z2{this->z2}; /* Processing loop is Transposed Direct Form II. This requires less storage * compared to Direct Form I (only two delay components, instead of a four- @@ -117,8 +117,8 @@ void BiquadFilter_processC(BiquadFilter *filter, float *RESTRICT dst, const floa z2 = input*b2 - output*a2; return output; }; - std::transform<const float*RESTRICT>(src, src+numsamples, dst, proc_sample); + std::transform(src, src+numsamples, dst, proc_sample); - filter->z1 = z1; - filter->z2 = z2; + this->z1 = z1; + this->z2 = z2; } diff --git a/Alc/mixvoice.cpp b/Alc/mixvoice.cpp index 04bb1130..91c48daf 100644 --- a/Alc/mixvoice.cpp +++ b/Alc/mixvoice.cpp @@ -250,17 +250,17 @@ const ALfloat *DoFilters(BiquadFilter *lpfilter, BiquadFilter *hpfilter, switch(type) { case AF_None: - BiquadFilter_passthru(lpfilter, numsamples); - BiquadFilter_passthru(hpfilter, numsamples); + lpfilter->passthru(numsamples); + hpfilter->passthru(numsamples); break; case AF_LowPass: - BiquadFilter_process(lpfilter, dst, src, numsamples); - BiquadFilter_passthru(hpfilter, numsamples); + lpfilter->process(dst, src, numsamples); + hpfilter->passthru(numsamples); return dst; case AF_HighPass: - BiquadFilter_passthru(lpfilter, numsamples); - BiquadFilter_process(hpfilter, dst, src, numsamples); + lpfilter->passthru(numsamples); + hpfilter->process(dst, src, numsamples); return dst; case AF_BandPass: @@ -269,8 +269,8 @@ const ALfloat *DoFilters(BiquadFilter *lpfilter, BiquadFilter *hpfilter, ALfloat temp[256]; ALsizei todo = mini(256, numsamples-i); - BiquadFilter_process(lpfilter, temp, src+i, todo); - BiquadFilter_process(hpfilter, dst+i, temp, todo); + lpfilter->process(temp, src+i, todo); + hpfilter->process(dst+i, temp, todo); i += todo; } return dst; |