diff options
author | Chris Robinson <[email protected]> | 2020-04-23 22:13:52 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-04-23 22:13:52 -0700 |
commit | 873983377052594b418bfa6cd505df7c604792ea (patch) | |
tree | 8b500bb483a079107dfd9feb368e8751f14ce44e /alc/filters | |
parent | e89978195f3910693958b8faebbd88b4643f8d57 (diff) |
Add a method to process two biquads at once
Diffstat (limited to 'alc/filters')
-rw-r--r-- | alc/filters/biquad.cpp | 39 | ||||
-rw-r--r-- | alc/filters/biquad.h | 12 |
2 files changed, 50 insertions, 1 deletions
diff --git a/alc/filters/biquad.cpp b/alc/filters/biquad.cpp index 271ca696..fefdc8e1 100644 --- a/alc/filters/biquad.cpp +++ b/alc/filters/biquad.cpp @@ -120,5 +120,44 @@ void BiquadFilterR<Real>::process(const al::span<const Real> src, Real *dst) mZ2 = z2; } +template<typename Real> +void BiquadFilterR<Real>::dualProcess(BiquadFilterR &other, const al::span<const Real> src, + Real *dst) +{ + const Real b00{mB0}; + const Real b01{mB1}; + const Real b02{mB2}; + const Real a01{mA1}; + const Real a02{mA2}; + const Real b10{other.mB0}; + const Real b11{other.mB1}; + const Real b12{other.mB2}; + const Real a11{other.mA1}; + const Real a12{other.mA2}; + Real z01{mZ1}; + Real z02{mZ2}; + Real z11{other.mZ1}; + Real z12{other.mZ2}; + + auto proc_sample = [b00,b01,b02,a01,a02,b10,b11,b12,a11,a12,&z01,&z02,&z11,&z12](Real input) noexcept -> Real + { + const Real tmpout{input*b00 + z01}; + z01 = input*b01 - tmpout*a01 + z02; + z02 = input*b02 - tmpout*a02; + input = tmpout; + + const Real output{input*b10 + z11}; + z11 = input*b11 - output*a11 + z12; + z12 = input*b12 - output*a12; + return output; + }; + std::transform(src.cbegin(), src.cend(), dst, proc_sample); + + mZ1 = z01; + mZ2 = z02; + other.mZ1 = z11; + other.mZ2 = z12; +} + template class BiquadFilterR<float>; template class BiquadFilterR<double>; diff --git a/alc/filters/biquad.h b/alc/filters/biquad.h index 30eed57d..3ce70cb3 100644 --- a/alc/filters/biquad.h +++ b/alc/filters/biquad.h @@ -114,8 +114,9 @@ public: mA2 = other.mA2; } - void process(const al::span<const Real> src, Real *dst); + /** Processes this filter and the other at the same time. */ + void dualProcess(BiquadFilterR &other, const al::span<const Real> src, Real *dst); /* Rather hacky. It's just here to support "manual" processing. */ std::pair<Real,Real> getComponents() const noexcept { return {mZ1, mZ2}; } @@ -129,6 +130,15 @@ public: } }; +template<typename Real> +struct DualBiquadR { + BiquadFilterR<Real> &f0, &f1; + + void process(const al::span<const Real> src, Real *dst) + { f0.dualProcess(f1, src, dst); } +}; + using BiquadFilter = BiquadFilterR<float>; +using DualBiquad = DualBiquadR<float>; #endif /* FILTERS_BIQUAD_H */ |