| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | /* | |||
| 2 | * @file biquad.cpp | |||
| 3 | * | |||
| 4 | * @date Sep 10, 2016 | |||
| 5 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
| 6 | */ | |||
| 7 | ||||
| 8 | #include "pch.h" | |||
| 9 | ||||
| 10 | #include "biquad.h" | |||
| 11 | ||||
| 12 | 721 | Biquad::Biquad() { | ||
| 13 | // Default to passthru | |||
| 14 | 721 | a0 = 1; | ||
| 15 | 721 | a1 = a2 = b1 = b2 = 0; | ||
| 16 | ||||
| 17 | 721 | reset(); | ||
| 18 | 721 | } | ||
| 19 | ||||
| 20 | 721 | void Biquad::reset() { | ||
| 21 | 721 | z1 = z2 = 0; | ||
| 22 | 721 | } | ||
| 23 | ||||
| 24 | 602 | static float getK(float samplingFrequency, float cutoff) { | ||
| 25 | 602 | return tanf_taylor(CONST_PI * cutoff / samplingFrequency); | ||
| 26 | } | |||
| 27 | ||||
| 28 | 602 | static float getNorm(float K, float Q) { | ||
| 29 | 602 | return 1 / (1 + K / Q + K * K); | ||
| 30 | } | |||
| 31 | ||||
| 32 | ✗ | void Biquad::configureBandpass(float samplingFrequency, float centerFrequency, float Q) { | ||
| 33 | ✗ | if (samplingFrequency < 2.5f * centerFrequency) { | ||
| 34 | ✗ | criticalError("Invalid biquad parameters samplingFrequency=%f centerFrequency=%f", samplingFrequency, centerFrequency); | ||
| 35 | ✗ | return; | ||
| 36 | } | |||
| 37 | ||||
| 38 | ✗ | float K = getK(samplingFrequency, centerFrequency); | ||
| 39 | ✗ | float norm = getNorm(K, Q); | ||
| 40 | ||||
| 41 | ✗ | a0 = K / Q * norm; | ||
| 42 | ✗ | a1 = 0; | ||
| 43 | ✗ | a2 = -a0; | ||
| 44 | ✗ | b1 = 2 * (K * K - 1) * norm; | ||
| 45 | ✗ | b2 = (1 - K / Q + K * K) * norm; | ||
| 46 | } | |||
| 47 | ||||
| 48 | 13 | void Biquad::configureLowpass(float samplingFrequency, float cutoffFrequency, float Q) { | ||
| 49 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | criticalAssertVoid(samplingFrequency >= 2.5f * cutoffFrequency, "Invalid biquad parameters"); | |
| 50 | ||||
| 51 | 13 | float K = getK(samplingFrequency, cutoffFrequency); | ||
| 52 | 13 | float norm = getNorm(K, Q); | ||
| 53 | ||||
| 54 | 13 | a0 = K * K * norm; | ||
| 55 | 13 | a1 = 2 * a0; | ||
| 56 | 13 | a2 = a0; | ||
| 57 | 13 | b1 = 2 * (K * K - 1) * norm; | ||
| 58 | 13 | b2 = (1 - K / Q + K * K) * norm; | ||
| 59 | } | |||
| 60 | ||||
| 61 | 589 | void Biquad::configureHighpass(float samplingFrequency, float cutoffFrequency, float Q) { | ||
| 62 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 589 times.
|
589 | criticalAssertVoid(samplingFrequency >= 2.5f * cutoffFrequency, "Invalid biquad parameters"); | |
| 63 | ||||
| 64 | 589 | float K = getK(samplingFrequency, cutoffFrequency); | ||
| 65 | 589 | float norm = getNorm(K, Q); | ||
| 66 | ||||
| 67 | 589 | a0 = 1 * norm; | ||
| 68 | 589 | a1 = -2 * a0; | ||
| 69 | 589 | a2 = a0; | ||
| 70 | 589 | b1 = 2 * (K * K - 1) * norm; | ||
| 71 | 589 | b2 = (1 - K / Q + K * K) * norm; | ||
| 72 | } | |||
| 73 | ||||
| 74 | 13007 | float Biquad::filter(float input) { | ||
| 75 | 13007 | float result = input * a0 + z1; | ||
| 76 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13007 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 13007 times.
|
13007 | if (engineConfiguration->verboseQuad) { |
| 77 | ✗ | efiPrintf("input %f, a0 %f, z1 %f, result %f", input, a0, z1, result); | ||
| 78 | } | |||
| 79 | 13007 | z1 = input * a1 + z2 - b1 * result; | ||
| 80 | 13007 | z2 = input * a2 - b2 * result; | ||
| 81 | 13007 | return result; | ||
| 82 | } | |||
| 83 | ||||
| 84 | 3 | void Biquad::cookSteadyState(float steadyStateInput) { | ||
| 85 | 3 | float Y = steadyStateInput * (a0 + a1 + a2) / (1 + b1 + b2); | ||
| 86 | ||||
| 87 | 3 | float steady_z2 = steadyStateInput * a2 - Y * b2; | ||
| 88 | 3 | float steady_z1 = steady_z2 + steadyStateInput * a1 - Y * b1; | ||
| 89 | ||||
| 90 | 3 | this->z1 = steady_z1; | ||
| 91 | 3 | this->z2 = steady_z2; | ||
| 92 | 3 | } | ||
| 93 |