Arduino Filters master
Filter library for Arduino
BiQuad.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <AH/STL/cmath>
6
9
11template <class T = float>
13
15
18
19// Direct Form 1 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
20
38template <class T>
40 public:
42
43 NormalizingBiQuadFilterDF1(const AH::Array<T, 3> &b,
44 const AH::Array<T, 3> &a)
45 : b(b / a[0]), a(-a.template slice<1, 2>() / a[0]) {}
46
48 : NormalizingBiQuadFilterDF1{coefficients.b, coefficients.a} {}
49
50 NormalizingBiQuadFilterDF1(const AH::Array<T, 3> &b,
51 const AH::Array<T, 3> &a, T gain)
52 : b(b * gain / a[0]), a(-a.template slice<1, 2>() / a[0]) {}
53
55 T gain)
56 : NormalizingBiQuadFilterDF1{coefficients.b, coefficients.a, gain} {}
57
58 template <bool Enable = true>
59 static std::enable_if_t<std::is_floating_point<T>::value && Enable, T>
60 update(T input, AH::Array<T, 2> &x, AH::Array<T, 2> &y,
61 const AH::Array<T, 3> &b, const AH::Array<T, 2> &a) {
62 T acc = input * b[0];
63 acc = std::fma(x[0], b[1], acc);
64 acc = std::fma(x[1], b[2], acc);
65 acc = std::fma(y[0], a[0], acc);
66 acc = std::fma(y[1], a[1], acc);
67 x[1] = x[0];
68 x[0] = input;
69 y[1] = y[0];
70 y[0] = acc;
71 return y[0];
72 }
73
74 template <bool Enable = true>
75 static std::enable_if_t<!std::is_floating_point<T>::value && Enable, T>
76 update(T input, AH::Array<T, 2> &x, AH::Array<T, 2> &y,
77 const AH::Array<T, 3> &b, const AH::Array<T, 2> &a) {
78 T acc = input * b[0];
79 acc = x[0] * b[1] + acc;
80 acc = x[1] * b[2] + acc;
81 acc = y[0] * a[0] + acc;
82 acc = y[1] * a[1] + acc;
83 x[1] = x[0];
84 x[0] = input;
85 y[1] = y[0];
86 y[0] = acc;
87 return y[0];
88 }
89
98 T operator()(T input) { return update(input, x, y, b, a); }
99
100 private:
101 AH::Array<T, 2> x = {{}};
102 AH::Array<T, 2> y = {{}};
103 AH::Array<T, 3> b = {{}};
104 AH::Array<T, 2> a = {{}};
105};
106
123template <class T>
125 public:
127
128 NonNormalizingBiQuadFilterDF1(const AH::Array<T, 3> &b,
129 const AH::Array<T, 3> &a)
130 : b(b), a(-a.template slice<1, 2>()), a0(a[0]) {}
131
133 : NonNormalizingBiQuadFilterDF1{coefficients.b, coefficients.a} {}
134
135 NonNormalizingBiQuadFilterDF1(const AH::Array<T, 3> &b,
136 const AH::Array<T, 3> &a, T gain)
137 : b(b * gain), a(-a.template slice<1, 2>()), a0(a[0]) {}
138
140 T gain)
141 : NonNormalizingBiQuadFilterDF1{coefficients.b, coefficients.a, gain} {}
142
143 template <bool Enable = true>
144 static std::enable_if_t<std::is_floating_point<T>::value && Enable, T>
145 update(T input, AH::Array<T, 2> &x, AH::Array<T, 2> &y,
146 const AH::Array<T, 3> &b, const AH::Array<T, 2> &a, T a0) {
147 T acc = input * b[0];
148 acc = std::fma(x[0], b[1], acc);
149 acc = std::fma(x[1], b[2], acc);
150 acc = std::fma(y[0], a[0], acc);
151 acc = std::fma(y[1], a[1], acc);
152 x[1] = x[0];
153 x[0] = input;
154 y[1] = y[0];
155 y[0] = acc / a0;
156 return y[0];
157 }
158
159 template <bool Enable = true>
160 static std::enable_if_t<!std::is_floating_point<T>::value && Enable, T>
161 update(T input, AH::Array<T, 2> &x, AH::Array<T, 2> &y,
162 const AH::Array<T, 3> &b, const AH::Array<T, 2> &a, T a0) {
163 T acc = input * b[0];
164 acc = x[0] * b[1] + acc;
165 acc = x[1] * b[2] + acc;
166 acc = y[0] * a[0] + acc;
167 acc = y[1] * a[1] + acc;
168 x[1] = x[0];
169 x[0] = input;
170 y[1] = y[0];
171 y[0] = acc / a0;
172 return y[0];
173 }
174
183 T operator()(T input) { return update(input, x, y, b, a, a0); }
184
185 private:
186 AH::Array<T, 2> x = {{}};
187 AH::Array<T, 2> y = {{}};
188 AH::Array<T, 3> b = {{}};
189 AH::Array<T, 2> a = {{}};
190 T a0 = T(1.);
191};
192
194
197template <class T>
199 typename std::conditional<std::is_floating_point<T>::value,
202
205
220template <class T = float>
222 public:
223 BiQuadFilterDF1() = default;
224
241 BiQuadFilterDF1(const AH::Array<T, 3> &b_coefficients,
242 const AH::Array<T, 3> &a_coefficients)
243 : BiQuadDF1Implementation<T>{b_coefficients, a_coefficients} {}
244
246 : BiQuadDF1Implementation<T>{coefficients} {}
247
266 BiQuadFilterDF1(const AH::Array<T, 3> &b_coefficients,
267 const AH::Array<T, 3> &a_coefficients, T gain)
268 : BiQuadDF1Implementation<T>{b_coefficients, a_coefficients, gain} {}
269
270 BiQuadFilterDF1(const BiQuadCoefficients<T> &coefficients, T gain)
271 : BiQuadDF1Implementation<T>{coefficients, gain} {}
272
281 T operator()(T input) {
283 }
284};
285
287
288// Direct Form 2 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
289
292
310template <class T>
312 public:
314
315 NormalizingBiQuadFilterDF2(const AH::Array<T, 3> &b,
316 const AH::Array<T, 3> &a)
317 : b(b / a[0]), a(-a.template slice<1, 2>() / a[0]) {}
318
320 : NormalizingBiQuadFilterDF2{coefficients.b, coefficients.a} {}
321
322 NormalizingBiQuadFilterDF2(const AH::Array<T, 3> &b,
323 const AH::Array<T, 3> &a, T gain)
324 : b(b * gain / a[0]), a(-a.template slice<1, 2>() / a[0]) {}
325
327 T gain)
328 : NormalizingBiQuadFilterDF2{coefficients.b, coefficients.a, gain} {}
329
330 template <bool Enable = true>
331 static std::enable_if_t<std::is_floating_point<T>::value && Enable, T>
332 update(T input, AH::Array<T, 2> &w, const AH::Array<T, 3> &b,
333 const AH::Array<T, 2> &a) {
334 input = std::fma(a[0], w[0], input);
335 input = std::fma(a[1], w[1], input);
336 T result = b[0] * input;
337 result = std::fma(b[1], w[0], result);
338 result = std::fma(b[2], w[1], result);
339 w[1] = w[0];
340 w[0] = input;
341 return result;
342 }
343
344 template <bool Enable = true>
345 static std::enable_if_t<!std::is_floating_point<T>::value && Enable, T>
346 update(T input, AH::Array<T, 2> &w, const AH::Array<T, 3> &b,
347 const AH::Array<T, 2> &a) {
348 input += a[0] * w[0];
349 input += a[1] * w[1];
350 T result = b[0] * input;
351 result += b[1] * w[0];
352 result += b[2] * w[1];
353 w[1] = w[0];
354 w[0] = input;
355 return result;
356 }
357
366 T operator()(T input) { return update(input, w, b, a); }
367
368 private:
369 AH::Array<T, 2> w = {{}};
370 AH::Array<T, 3> b = {{}};
371 AH::Array<T, 2> a = {{}};
372};
373
390template <class T>
392 public:
394
395 NonNormalizingBiQuadFilterDF2(const AH::Array<T, 3> &b,
396 const AH::Array<T, 3> &a)
397 : b(b), a(-a.template slice<1, 2>()), a0(a[0]) {}
398
400 : NonNormalizingBiQuadFilterDF2{coefficients.b, coefficients.a} {}
401
402 NonNormalizingBiQuadFilterDF2(const AH::Array<T, 3> &b,
403 const AH::Array<T, 3> &a, T gain)
404 : b(b * gain), a(-a.template slice<1, 2>()), a0(a[0]) {}
405
407 T gain)
408 : NonNormalizingBiQuadFilterDF2{coefficients.b, coefficients.a, gain} {}
409
410 template <bool Enable = true>
411 static std::enable_if_t<std::is_floating_point<T>::value && Enable, T>
412 update(T input, AH::Array<T, 2> &w, const AH::Array<T, 3> &b,
413 const AH::Array<T, 2> &a, T a0) {
414 input = std::fma(a[0], w[0], input);
415 input = std::fma(a[1], w[1], input);
416 input /= a0;
417 T result = b[0] * input;
418 result = std::fma(b[1], w[0], result);
419 result = std::fma(b[2], w[1], result);
420 w[1] = w[0];
421 w[0] = input;
422 return result;
423 }
424
425 template <bool Enable = true>
426 static std::enable_if_t<!std::is_floating_point<T>::value && Enable, T>
427 update(T input, AH::Array<T, 2> &w, const AH::Array<T, 3> &b,
428 const AH::Array<T, 2> &a, T a0) {
429 input += a[0] * w[0];
430 input += a[1] * w[1];
431 input /= a0;
432 T result = b[0] * input;
433 result += b[1] * w[0];
434 result += b[2] * w[1];
435 w[1] = w[0];
436 w[0] = input;
437 return result;
438 }
439
448 T operator()(T input) { return update(input, w, b, a, a0); }
449
450 private:
451 AH::Array<T, 2> w = {{}};
452 AH::Array<T, 3> b = {{}};
453 AH::Array<T, 2> a = {{}};
454 T a0 = T(1.);
455};
456
458
461template <class T>
463 typename std::conditional<std::is_floating_point<T>::value,
466
469
484template <class T = float>
486 public:
487 BiQuadFilterDF2() = default;
488
505 BiQuadFilterDF2(const AH::Array<T, 3> &b_coefficients,
506 const AH::Array<T, 3> &a_coefficients)
507 : BiQuadDF2Implementation<T>{b_coefficients, a_coefficients} {}
508
510 : BiQuadDF2Implementation<T>{coefficients} {}
511
530 BiQuadFilterDF2(const AH::Array<T, 3> &b_coefficients,
531 const AH::Array<T, 3> &a_coefficients, T gain)
532 : BiQuadDF2Implementation<T>{b_coefficients, a_coefficients, gain} {}
533
534 BiQuadFilterDF2(const BiQuadCoefficients<T> &coefficients, T gain)
535 : BiQuadDF2Implementation<T>{coefficients, gain} {}
536
545 T operator()(T input) {
547 }
548};
549
550
typename std::conditional< std::is_floating_point< T >::value, NormalizingBiQuadFilterDF2< T >, NonNormalizingBiQuadFilterDF2< T > >::type BiQuadDF2Implementation
Select the NormalizingIIRFilter implementation if T is a floating point type, NonNormalizingIIRFilter...
Definition: BiQuad.hpp:465
typename std::conditional< std::is_floating_point< T >::value, NormalizingBiQuadFilterDF1< T >, NonNormalizingBiQuadFilterDF1< T > >::type BiQuadDF1Implementation
Select the NormalizingIIRFilter implementation if T is a floating point type, NonNormalizingIIRFilter...
Definition: BiQuad.hpp:201
Generic BiQuad (Bi-Quadratic) filter class, Direct Form 1 implementation.
Definition: BiQuad.hpp:221
BiQuadFilterDF1()=default
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: BiQuad.hpp:281
BiQuadFilterDF1(const AH::Array< T, 3 > &b_coefficients, const AH::Array< T, 3 > &a_coefficients, T gain)
Construct a new BiQuad (Bi-Quadratic) Filter object.
Definition: BiQuad.hpp:266
BiQuadFilterDF1(const BiQuadCoefficients< T > &coefficients)
Definition: BiQuad.hpp:245
BiQuadFilterDF1(const AH::Array< T, 3 > &b_coefficients, const AH::Array< T, 3 > &a_coefficients)
Construct a new BiQuad (Bi-Quadratic) Filter object.
Definition: BiQuad.hpp:241
BiQuadFilterDF1(const BiQuadCoefficients< T > &coefficients, T gain)
Definition: BiQuad.hpp:270
Generic BiQuad (Bi-Quadratic) filter class, Direct Form 2 implementation.
Definition: BiQuad.hpp:485
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: BiQuad.hpp:545
BiQuadFilterDF2(const BiQuadCoefficients< T > &coefficients, T gain)
Definition: BiQuad.hpp:534
BiQuadFilterDF2()=default
BiQuadFilterDF2(const BiQuadCoefficients< T > &coefficients)
Definition: BiQuad.hpp:509
BiQuadFilterDF2(const AH::Array< T, 3 > &b_coefficients, const AH::Array< T, 3 > &a_coefficients, T gain)
Construct a new BiQuad (Bi-Quadratic) Filter object.
Definition: BiQuad.hpp:530
BiQuadFilterDF2(const AH::Array< T, 3 > &b_coefficients, const AH::Array< T, 3 > &a_coefficients)
Construct a new BiQuad (Bi-Quadratic) Filter object.
Definition: BiQuad.hpp:505
BiQuad filter Direct Form 1 implementation that does not normalize the coefficients upon initializati...
Definition: BiQuad.hpp:124
static std::enable_if_t<!std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &x, AH::Array< T, 2 > &y, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a, T a0)
Definition: BiQuad.hpp:161
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: BiQuad.hpp:183
AH::Array< T, 2 > x
Previous inputs.
Definition: BiQuad.hpp:186
T a0
First denominator coefficient.
Definition: BiQuad.hpp:190
AH::Array< T, 2 > y
Previous outputs.
Definition: BiQuad.hpp:187
AH::Array< T, 2 > a
Denominator coefficients.
Definition: BiQuad.hpp:189
NonNormalizingBiQuadFilterDF1(const BiQuadCoefficients< T > &coefficients, T gain)
Definition: BiQuad.hpp:139
AH::Array< T, 3 > b
Numerator coefficients.
Definition: BiQuad.hpp:188
static std::enable_if_t< std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &x, AH::Array< T, 2 > &y, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a, T a0)
Definition: BiQuad.hpp:145
NonNormalizingBiQuadFilterDF1(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a, T gain)
Definition: BiQuad.hpp:135
NonNormalizingBiQuadFilterDF1(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a)
Definition: BiQuad.hpp:128
NonNormalizingBiQuadFilterDF1(const BiQuadCoefficients< T > &coefficients)
Definition: BiQuad.hpp:132
BiQuad filter Direct Form 2 implementation that does not normalize the coefficients upon initializati...
Definition: BiQuad.hpp:391
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: BiQuad.hpp:448
static std::enable_if_t< std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &w, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a, T a0)
Definition: BiQuad.hpp:412
static std::enable_if_t<!std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &w, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a, T a0)
Definition: BiQuad.hpp:427
NonNormalizingBiQuadFilterDF2(const BiQuadCoefficients< T > &coefficients, T gain)
Definition: BiQuad.hpp:406
T a0
First denominator coefficient.
Definition: BiQuad.hpp:454
AH::Array< T, 2 > a
Denominator coefficients.
Definition: BiQuad.hpp:453
AH::Array< T, 3 > b
Numerator coefficients.
Definition: BiQuad.hpp:452
NonNormalizingBiQuadFilterDF2(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a, T gain)
Definition: BiQuad.hpp:402
AH::Array< T, 2 > w
Internal state.
Definition: BiQuad.hpp:451
NonNormalizingBiQuadFilterDF2(const BiQuadCoefficients< T > &coefficients)
Definition: BiQuad.hpp:399
NonNormalizingBiQuadFilterDF2(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a)
Definition: BiQuad.hpp:395
BiQuad filter Direct Form 1 implementation that normalizes the coefficients upon initialization.
Definition: BiQuad.hpp:39
static std::enable_if_t< std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &x, AH::Array< T, 2 > &y, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a)
Definition: BiQuad.hpp:60
NormalizingBiQuadFilterDF1(const BiQuadCoefficients< T > &coefficients, T gain)
Definition: BiQuad.hpp:54
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: BiQuad.hpp:98
AH::Array< T, 2 > x
Previous inputs.
Definition: BiQuad.hpp:101
AH::Array< T, 2 > y
Previous outputs.
Definition: BiQuad.hpp:102
AH::Array< T, 2 > a
Denominator coefficients.
Definition: BiQuad.hpp:104
NormalizingBiQuadFilterDF1()=default
NormalizingBiQuadFilterDF1(const BiQuadCoefficients< T > &coefficients)
Definition: BiQuad.hpp:47
AH::Array< T, 3 > b
Numerator coefficients.
Definition: BiQuad.hpp:103
static std::enable_if_t<!std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &x, AH::Array< T, 2 > &y, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a)
Definition: BiQuad.hpp:76
NormalizingBiQuadFilterDF1(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a)
Definition: BiQuad.hpp:43
NormalizingBiQuadFilterDF1(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a, T gain)
Definition: BiQuad.hpp:50
BiQuad filter Direct Form 2 implementation that normalizes the coefficients upon initialization.
Definition: BiQuad.hpp:311
NormalizingBiQuadFilterDF2(const BiQuadCoefficients< T > &coefficients, T gain)
Definition: BiQuad.hpp:326
NormalizingBiQuadFilterDF2(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a, T gain)
Definition: BiQuad.hpp:322
NormalizingBiQuadFilterDF2(const BiQuadCoefficients< T > &coefficients)
Definition: BiQuad.hpp:319
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: BiQuad.hpp:366
AH::Array< T, 2 > a
Denominator coefficients.
Definition: BiQuad.hpp:371
static std::enable_if_t<!std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &w, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a)
Definition: BiQuad.hpp:346
AH::Array< T, 3 > b
Numerator coefficients.
Definition: BiQuad.hpp:370
NormalizingBiQuadFilterDF2(const AH::Array< T, 3 > &b, const AH::Array< T, 3 > &a)
Definition: BiQuad.hpp:315
AH::Array< T, 2 > w
Internal state.
Definition: BiQuad.hpp:369
static std::enable_if_t< std::is_floating_point< T >::value &&Enable, T > update(T input, AH::Array< T, 2 > &w, const AH::Array< T, 3 > &b, const AH::Array< T, 2 > &a)
Definition: BiQuad.hpp:332
NormalizingBiQuadFilterDF2()=default
Class for transfer function coefficients.