aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/filters
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/filters
parent36a8b615c883ccc90705b97402e2e2046058720a (diff)
Use class methods for the biquad filter
Diffstat (limited to 'Alc/filters')
-rw-r--r--Alc/filters/defs.h110
-rw-r--r--Alc/filters/filter.cpp34
2 files changed, 76 insertions, 68 deletions
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;
}