aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-12-04 22:31:08 -0800
committerChris Robinson <[email protected]>2018-12-04 22:31:08 -0800
commit164a86a381e4f51383c6afbfdf63dadd3ecb3785 (patch)
tree98287b6d44082e4b905eddeb2e70ebc8cf8bfd0a /Alc
parent36a8b615c883ccc90705b97402e2e2046058720a (diff)
Use class methods for the biquad filter
Diffstat (limited to 'Alc')
-rw-r--r--Alc/alu.cpp24
-rw-r--r--Alc/effects/distortion.cpp16
-rw-r--r--Alc/effects/echo.cpp17
-rw-r--r--Alc/effects/equalizer.cpp36
-rw-r--r--Alc/effects/modulator.cpp10
-rw-r--r--Alc/effects/reverb.cpp36
-rw-r--r--Alc/filters/defs.h110
-rw-r--r--Alc/filters/filter.cpp34
-rw-r--r--Alc/mixvoice.cpp16
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;