diff --git a/include/sdsp/casc2orderIIR.h b/include/sdsp/casc2orderIIR.h index d2b00eb..853d8e4 100644 --- a/include/sdsp/casc2orderIIR.h +++ b/include/sdsp/casc2orderIIR.h @@ -10,6 +10,8 @@ class casc2orderIIR { private: int pos{ 0 }; + double gain{ 1.0 }; + std::array, M + 1> mem{ 0 }; std::array, M> bCoeff{ 0 }; @@ -39,7 +41,7 @@ class casc2orderIIR { std::array, M> a = aCoeff; while (begin < end) { - y.at(0).at(p) = *begin; + y.at(0).at(p) = *begin * gain; int d1{ p - j1 }; if (d1 < 0) @@ -69,8 +71,9 @@ class casc2orderIIR { mem = y; } - void SetBPCoeff(double f0, double fs, double Q) + void SetBPCoeff(double f0, double fs, double Q, double gainIn = 1.0) { + gain = gainIn; double q2{ 2 * Q }; fType = FilterType::BandPass; @@ -124,8 +127,9 @@ class casc2orderIIR { } } - void SetHPCoeff(double f0, double fs) + void SetHPCoeff(double f0, double fs, double gainIn = 1.0) { + gain = gainIn; fType = FilterType::HighPass; double e0{ 2 * M_PI * f0 / fs }; @@ -149,8 +153,9 @@ class casc2orderIIR { } } - void SetLPCoeff(double f0, double fs) + void SetLPCoeff(double f0, double fs, double gainIn = 1.0) { + gain = gainIn; fType = FilterType::LowPass; double e0{ 2 * M_PI * f0 / fs }; diff --git a/test/testIIR.cpp b/test/testIIR.cpp index 6134e5b..a49476c 100644 --- a/test/testIIR.cpp +++ b/test/testIIR.cpp @@ -76,6 +76,100 @@ TEST_CASE("Filter test") } } + SECTION("Test the LP filter gain") + { + constexpr double fs{ 100e3 }; + constexpr double f0{ 10e3 }; + + std::array impulse1{ 0 }; + impulse1.at(0) = 1.0; + std::array impulse2{ 0 }; + impulse2.at(0) = 1.0; + + sdsp::casc2orderIIR<4> df; + df.SetLPCoeff(f0, fs); + + sdsp::casc2orderIIR<4> df2; + df2.SetLPCoeff(f0, fs, 2.0); + + df.Process(impulse1.begin(), impulse1.end()); + df2.Process(impulse2.begin(), impulse2.end()); + + auto times_two = [](double &n) { n = 2.0 * n; }; + std::for_each(impulse1.begin(), impulse1.end(), times_two); + + std::array error{ 0 }; + + for (size_t i = 0; i < error.size(); i++) { + error.at(i) = std::abs(impulse1.at(i) - impulse2.at(i)); + } + double maxError = *std::max_element(error.begin(), error.end()); + REQUIRE(maxError < 1e-12); + } + + SECTION("Test the HP filter gain") + { + constexpr double fs{ 100e3 }; + constexpr double f0{ 10e3 }; + + std::array impulse1{ 0 }; + impulse1.at(0) = 1.0; + std::array impulse2{ 0 }; + impulse2.at(0) = 1.0; + + sdsp::casc2orderIIR<4> df; + df.SetHPCoeff(f0, fs); + + sdsp::casc2orderIIR<4> df2; + df2.SetHPCoeff(f0, fs, 2.0); + + df.Process(impulse1.begin(), impulse1.end()); + df2.Process(impulse2.begin(), impulse2.end()); + + auto times_two = [](double &n) { n = 2.0 * n; }; + std::for_each(impulse1.begin(), impulse1.end(), times_two); + + std::array error{ 0 }; + + for (size_t i = 0; i < error.size(); i++) { + error.at(i) = std::abs(impulse1.at(i) - impulse2.at(i)); + } + double maxError = *std::max_element(error.begin(), error.end()); + REQUIRE(maxError < 1e-12); + } + + SECTION("Test the BP filter gain") + { + constexpr double fs{ 100e3 }; + constexpr double f0{ 10e3 }; + constexpr double Q{ 1.1 }; + + std::array impulse1{ 0 }; + impulse1.at(0) = 1.0; + std::array impulse2{ 0 }; + impulse2.at(0) = 1.0; + + sdsp::casc2orderIIR<4> df; + df.SetBPCoeff(f0, fs, Q); + + sdsp::casc2orderIIR<4> df2; + df2.SetBPCoeff(f0, fs, Q, 2.0); + + df.Process(impulse1.begin(), impulse1.end()); + df2.Process(impulse2.begin(), impulse2.end()); + + auto times_two = [](double &n) { n = 2.0 * n; }; + std::for_each(impulse1.begin(), impulse1.end(), times_two); + + std::array error{ 0 }; + + for (size_t i = 0; i < error.size(); i++) { + error.at(i) = std::abs(impulse1.at(i) - impulse2.at(i)); + } + double maxError = *std::max_element(error.begin(), error.end()); + REQUIRE(maxError < 1e-12); + } + SECTION("Test filter preload") { constexpr double fs{ 100e3 };