aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-01-06 04:45:35 -0800
committerChris Robinson <[email protected]>2019-01-06 04:45:35 -0800
commitd2e34e509bfc3d99c8db03dccf43806c5957bc23 (patch)
tree676b9c3f22fae8863a2a28e94201b59cf46a114c
parentda3a916042a7ba9426af1d6f03e689dbd7760191 (diff)
Make the band-splitter and splitter-allpass filters templated
With float and double explicit instantiations
-rw-r--r--Alc/filters/splitter.cpp53
-rw-r--r--Alc/filters/splitter.h28
2 files changed, 47 insertions, 34 deletions
diff --git a/Alc/filters/splitter.cpp b/Alc/filters/splitter.cpp
index 0f099661..9e13c188 100644
--- a/Alc/filters/splitter.cpp
+++ b/Alc/filters/splitter.cpp
@@ -9,11 +9,11 @@
#include "math_defs.h"
-
-void BandSplitter::init(float f0norm)
+template<typename Real>
+void BandSplitterR<Real>::init(Real f0norm)
{
- float w = f0norm * al::MathDefs<float>::Tau();
- float cw = std::cos(w);
+ const Real w{f0norm * al::MathDefs<Real>::Tau()};
+ const Real cw{std::cos(w)};
if(cw > std::numeric_limits<float>::epsilon())
coeff = (std::sin(w) - 1.0f) / cw;
else
@@ -24,20 +24,21 @@ void BandSplitter::init(float f0norm)
ap_z1 = 0.0f;
}
-void BandSplitter::process(float *RESTRICT hpout, float *RESTRICT lpout, const float *input, int count)
+template<typename Real>
+void BandSplitterR<Real>::process(Real *RESTRICT hpout, Real *RESTRICT lpout, const Real *input, int count)
{
ASSUME(count > 0);
- const float ap_coeff{this->coeff};
- const float lp_coeff{this->coeff*0.5f + 0.5f};
- float lp_z1{this->lp_z1};
- float lp_z2{this->lp_z2};
- float ap_z1{this->ap_z1};
- auto proc_sample = [ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1,&lpout](const float in) noexcept -> float
+ const Real ap_coeff{this->coeff};
+ const Real lp_coeff{this->coeff*0.5f + 0.5f};
+ Real lp_z1{this->lp_z1};
+ Real lp_z2{this->lp_z2};
+ Real ap_z1{this->ap_z1};
+ auto proc_sample = [ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1,&lpout](const Real in) noexcept -> Real
{
/* Low-pass sample processing. */
- float d{(in - lp_z1) * lp_coeff};
- float lp_y{lp_z1 + d};
+ Real d{(in - lp_z1) * lp_coeff};
+ Real lp_y{lp_z1 + d};
lp_z1 = lp_y + d;
d = (lp_y - lp_z2) * lp_coeff;
@@ -47,7 +48,7 @@ void BandSplitter::process(float *RESTRICT hpout, float *RESTRICT lpout, const f
*(lpout++) = lp_y;
/* All-pass sample processing. */
- float ap_y{in*ap_coeff + ap_z1};
+ Real ap_y{in*ap_coeff + ap_z1};
ap_z1 = in - ap_y*ap_coeff;
/* High-pass generated from removing low-passed output. */
@@ -59,11 +60,15 @@ void BandSplitter::process(float *RESTRICT hpout, float *RESTRICT lpout, const f
this->ap_z1 = ap_z1;
}
+template class BandSplitterR<float>;
+template class BandSplitterR<double>;
+
-void SplitterAllpass::init(float f0norm)
+template<typename Real>
+void SplitterAllpassR<Real>::init(Real f0norm)
{
- float w = f0norm * al::MathDefs<float>::Tau();
- float cw = std::cos(w);
+ const Real w{f0norm * al::MathDefs<Real>::Tau()};
+ const Real cw{std::cos(w)};
if(cw > std::numeric_limits<float>::epsilon())
coeff = (std::sin(w) - 1.0f) / cw;
else
@@ -72,18 +77,22 @@ void SplitterAllpass::init(float f0norm)
z1 = 0.0f;
}
-void SplitterAllpass::process(float *RESTRICT samples, int count)
+template<typename Real>
+void SplitterAllpassR<Real>::process(Real *RESTRICT samples, int count)
{
ASSUME(count > 0);
- const float coeff{this->coeff};
- float z1{this->z1};
- auto proc_sample = [coeff,&z1](const float in) noexcept -> float
+ const Real coeff{this->coeff};
+ Real z1{this->z1};
+ auto proc_sample = [coeff,&z1](const Real in) noexcept -> Real
{
- float out{in*coeff + z1};
+ Real out{in*coeff + z1};
z1 = in - out*coeff;
return out;
};
std::transform(samples, samples+count, samples, proc_sample);
this->z1 = z1;
}
+
+template class SplitterAllpassR<float>;
+template class SplitterAllpassR<double>;
diff --git a/Alc/filters/splitter.h b/Alc/filters/splitter.h
index b39c3491..e1122577 100644
--- a/Alc/filters/splitter.h
+++ b/Alc/filters/splitter.h
@@ -6,30 +6,34 @@
/* Band splitter. Splits a signal into two phase-matching frequency bands. */
-class BandSplitter {
- float coeff{0.0f};
- float lp_z1{0.0f};
- float lp_z2{0.0f};
- float ap_z1{0.0f};
+template<typename Real>
+class BandSplitterR {
+ Real coeff{0.0f};
+ Real lp_z1{0.0f};
+ Real lp_z2{0.0f};
+ Real ap_z1{0.0f};
public:
- void init(float f0norm);
+ void init(Real f0norm);
void clear() noexcept { lp_z1 = lp_z2 = ap_z1 = 0.0f; }
- void process(float *RESTRICT hpout, float *RESTRICT lpout, const float *input, int count);
+ void process(Real *RESTRICT hpout, Real *RESTRICT lpout, const Real *input, int count);
};
+using BandSplitter = BandSplitterR<float>;
/* The all-pass portion of the band splitter. Applies the same phase shift
* without splitting the signal.
*/
-class SplitterAllpass {
- float coeff{0.0f};
- float z1{0.0f};
+template<typename Real>
+class SplitterAllpassR {
+ Real coeff{0.0f};
+ Real z1{0.0f};
public:
- void init(float f0norm);
+ void init(Real f0norm);
void clear() noexcept { z1 = 0.0f; }
- void process(float *RESTRICT samples, int count);
+ void process(Real *RESTRICT samples, int count);
};
+using SplitterAllpass = SplitterAllpassR<float>;
struct FrontStablizer {