arduino-audio-tools
Loading...
Searching...
No Matches
Filter.h
Go to the documentation of this file.
1#pragma once
2#include <math.h>
3
4#include "AudioToolsConfig.h"
6#ifdef USE_TYPETRAITS
7#include <type_traits>
8#endif
9
10
17namespace audio_tools {
18
27template <typename T = float>
28class Filter {
29 public:
30 // construct without coefs
31 Filter() = default;
32 virtual ~Filter() = default;
33 Filter(Filter const&) = delete;
34 Filter& operator=(Filter const&) = delete;
36 virtual T process(T in) = 0;
40 virtual void reset() {}
41};
42
50template <typename T = float>
51class NoFilter : public Filter<T> {
52 public:
53 // construct without coefs
54 NoFilter() = default;
55 T process(T in) override { return in; }
56};
57
68template <typename T = float>
69class FIR : public Filter<T> {
70 public:
71 template <size_t B>
72 FIR(const T (&b)[B], const T factor = 1.0)
73 : lenB(B), factor(factor), needs_divide(factor != T(1)) {
74 setValues(b);
75 }
76
77 template <size_t B>
78 void setValues(const T (&b)[B]) {
79 x.resize(lenB);
80 coeff_b.resize(2 * lenB - 1);
81 for (uint16_t i = 0; i < 2 * lenB - 1; i++) {
82 coeff_b[i] = b[(2 * lenB - 1 - i) % lenB];
83 }
84 }
85
86 void reset() override {
87 i_b = 0;
88 for (uint16_t i = 0; i < lenB; i++) x[i] = 0;
89 }
90
91 T process(T value) override {
92 x[i_b] = value;
93 T b_terms = 0;
94 T* b_shift = &coeff_b[lenB - i_b - 1];
95 for (uint16_t i = 0; i < lenB; i++) {
96 b_terms += b_shift[i] * x[i];
97 }
98 i_b++;
99 if (i_b == lenB) i_b = 0;
100
101#ifdef USE_TYPETRAITS
102 if (!(std::is_same<T, float>::value || std::is_same<T, double>::value)) {
103 b_terms = b_terms / factor;
104 }
105#else
106 // needs_divide is computed once in the constructor (not per sample) --
107 // for a bounded fixed-point T like q1_14_t, comparing against a float
108 // literal here on every process() call would otherwise force a
109 // per-sample float construction/comparison.
110 if (needs_divide) {
111 b_terms = b_terms / factor;
112 }
113#endif
114 return b_terms;
115 }
116
117 private:
118 const uint16_t lenB;
119 uint16_t i_b = 0;
120 Vector<T> x;
121 Vector<T> coeff_b;
122 T factor;
123 bool needs_divide;
124};
125
136template <typename T = float>
137class IIR : public Filter<T> {
138 public:
139 template <size_t B, size_t A>
140 IIR(const T (&b)[B], const T (&_a)[A], T factor = 1.0)
141 : factor(factor), needs_divide(factor != T(1)), lenB(B), lenA(A - 1) {
142 x.resize(lenB);
143 y.resize(lenA);
144 coeff_b.resize(2 * lenB - 1);
145 coeff_a.resize(2 * lenA - 1);
146 T a0 = _a[0];
147 const T* a = &_a[1];
148 for (uint16_t i = 0; i < 2 * lenB - 1; i++) {
149 coeff_b[i] = b[(2 * lenB - 1 - i) % lenB] / a0;
150 }
151 for (uint16_t i = 0; i < 2 * lenA - 1; i++) {
152 coeff_a[i] = a[(2 * lenA - 2 - i) % lenA] / a0;
153 }
154 }
155
156 void reset() override {
157 i_b = 0;
158 i_a = 0;
159 for (uint16_t i = 0; i < lenB; i++) x[i] = 0;
160 for (uint16_t i = 0; i < lenA; i++) y[i] = 0;
161 }
162
163 T process(T value) override {
164 x[i_b] = value;
165 T b_terms = 0;
166 T* b_shift = &coeff_b[lenB - i_b - 1];
167
168 T a_terms = 0;
169 T* a_shift = &coeff_a[lenA - i_a - 1];
170
171 for (uint16_t i = 0; i < lenB; i++) {
172 b_terms += x[i] * b_shift[i];
173 }
174 for (uint16_t i = 0; i < lenA; i++) {
175 a_terms += y[i] * a_shift[i];
176 }
177
178 T filtered = b_terms - a_terms;
179 y[i_a] = filtered;
180 i_b++;
181 if (i_b == lenB) i_b = 0;
182 i_a++;
183 if (i_a == lenA) i_a = 0;
184
185#ifdef USE_TYPETRAITS
186 if (!(std::is_same<T, float>::value || std::is_same<T, double>::value)) {
187 filtered = filtered / factor;
188 }
189#else
190 // needs_divide is computed once in the constructor (not per sample) --
191 // see FIR::process() for why.
192 if (needs_divide) {
193 filtered = filtered / factor;
194 }
195#endif
196 return filtered;
197 }
198
199 private:
200 T factor;
201 bool needs_divide;
202 const uint16_t lenB, lenA;
203 uint16_t i_b = 0, i_a = 0;
204 Vector<T> x;
205 Vector<T> y;
206 Vector<T> coeff_b;
207 Vector<T> coeff_a;
208};
209
219template <typename T = float>
220class BiQuadDF1 : public Filter<T> {
221 public:
222 BiQuadDF1(const T (&b)[3], const T (&a)[3])
223 : b_0(b[0] / a[0]),
224 b_1(b[1] / a[0]),
225 b_2(b[2] / a[0]),
226 a_1(a[1] / a[0]),
227 a_2(a[2] / a[0]) {}
228 BiQuadDF1(const T (&b)[3], const T (&a)[2])
229 : b_0(b[0]), b_1(b[1]), b_2(b[2]), a_1(a[0]), a_2(a[1]) {}
230 BiQuadDF1(const T (&b)[3], const T (&a)[2], T gain)
231 : b_0(gain * b[0]),
232 b_1(gain * b[1]),
233 b_2(gain * b[2]),
234 a_1(a[0]),
235 a_2(a[1]) {}
236 BiQuadDF1(const T (&b)[3], const T (&a)[3], T gain)
237 : b_0(gain * b[0] / a[0]),
238 b_1(gain * b[1] / a[0]),
239 b_2(gain * b[2] / a[0]),
240 a_1(a[1] / a[0]),
241 a_2(a[2] / a[0]) {}
242
243 void reset() override { x_0 = x_1 = y_1 = y_2 = 0; }
244
245 T process(T value) override {
246 T x_2 = x_1;
247 x_1 = x_0;
248 x_0 = value;
249 T b_terms = x_0 * b_0 + x_1 * b_1 + x_2 * b_2;
250 T a_terms = y_1 * a_1 + y_2 * a_2;
251 y_2 = y_1;
252 y_1 = b_terms - a_terms;
253 return y_1;
254 }
255
256 protected:
257 T b_0 = 0;
258 T b_1 = 0;
259 T b_2 = 0;
260 T a_1 = 0;
261 T a_2 = 0;
262
263 // allow constructor w/o parameter in subclasses
264 BiQuadDF1() = default;
265
266 T x_0 = 0;
267 T x_1 = 0;
268 T y_1 = 0;
269 T y_2 = 0;
270};
271
283template <typename T = float>
284class BiQuadDF2 : public Filter<T> {
285 public:
286 BiQuadDF2(const T (&b)[3], const T (&a)[3])
287 : b_0(b[0] / a[0]),
288 b_1(b[1] / a[0]),
289 b_2(b[2] / a[0]),
290 a_1(a[1] / a[0]),
291 a_2(a[2] / a[0]) {}
292 BiQuadDF2(const T (&b)[3], const T (&a)[2])
293 : b_0(b[0]), b_1(b[1]), b_2(b[2]), a_1(a[0]), a_2(a[1]) {}
294 BiQuadDF2(const T (&b)[3], const T (&a)[2], T gain)
295 : b_0(gain * b[0]),
296 b_1(gain * b[1]),
297 b_2(gain * b[2]),
298 a_1(a[0]),
299 a_2(a[1]) {}
300 BiQuadDF2(const T (&b)[3], const T (&a)[3], T gain)
301 : b_0(gain * b[0] / a[0]),
302 b_1(gain * b[1] / a[0]),
303 b_2(gain * b[2] / a[0]),
304 a_1(a[1] / a[0]),
305 a_2(a[2] / a[0]) {}
306
307 void reset() override { w_0 = w_1 = 0; }
308
309 T process(T value) override {
310 T w_2 = w_1;
311 w_1 = w_0;
312 w_0 = value - a_1 * w_1 - a_2 * w_2;
313 T y = b_0 * w_0 + b_1 * w_1 + b_2 * w_2;
314 return y;
315 }
316
317 protected:
318 T b_0 = 0;
319 T b_1 = 0;
320 T b_2 = 0;
321 T a_1 = 0;
322 T a_2 = 0;
323
324 // allow constructor w/o parameter in subclasses
325 BiQuadDF2() = default;
326
327 T w_0 = 0;
328 T w_1 = 0;
329};
330
341 float b_0, b_1, b_2, a_1, a_2;
342};
343
355template <typename T>
357 auto check = [](const char *name, float value) {
358 T t = value;
359 float roundtrip = (float)t;
360 // allow normal quantization noise (e.g. ~1/16384 for q1_14_t); anything
361 // larger indicates the value was clamped/saturated, not just rounded.
362 if (fabs(roundtrip - value) > fabs(value) * 0.01f + 1e-4f) {
363 LOGE(
364 "Filter coefficient %s=%f does not fit in the range of T (stored "
365 "as %f) - the filter will be inaccurate",
366 name, value, roundtrip);
367 }
368 };
369 check("b_0", c.b_0);
370 check("b_1", c.b_1);
371 check("b_2", c.b_2);
372 check("a_1", c.a_1);
373 check("a_2", c.a_2);
374}
375
377inline BiQuadCoeffs calculateLowPassCoeffs(float frequency, float sampleRate,
378 float q) {
379 float w0 = frequency * (2.0f * PI / sampleRate);
380 float sinW0 = sin(w0);
381 float alpha = sinW0 / (q * 2.0f);
382 float cosW0 = cos(w0);
383 float scale = 1.0f / (1.0f + alpha);
384 BiQuadCoeffs c;
385 c.b_0 = ((1.0f - cosW0) / 2.0f) * scale;
386 c.b_1 = (1.0f - cosW0) * scale;
387 c.b_2 = c.b_0;
388 c.a_1 = (-2.0f * cosW0) * scale;
389 c.a_2 = (1.0f - alpha) * scale;
390 return c;
391}
392
409template <typename T = float>
410class LowPassFilter : public BiQuadDF2<T> {
411 public:
412 LowPassFilter() = default;
413 LowPassFilter(float frequency, float sampleRate, float q = 0.7071f)
414 : BiQuadDF2<T>() {
415 begin(frequency, sampleRate, q);
416 }
417 void begin(float frequency, float sampleRate, float q = 0.7071f) {
418 BiQuadCoeffs c = calculateLowPassCoeffs(frequency, sampleRate, q);
419 checkCoeffRange<T>(c);
425 }
426};
427
445template <typename T = float>
446class LowPassFilterDF1 : public BiQuadDF1<T> {
447 public:
448 LowPassFilterDF1() = default;
449 LowPassFilterDF1(float frequency, float sampleRate, float q = 0.7071f)
450 : BiQuadDF1<T>() {
451 begin(frequency, sampleRate, q);
452 }
453 void begin(float frequency, float sampleRate, float q = 0.7071f) {
454 BiQuadCoeffs c = calculateLowPassCoeffs(frequency, sampleRate, q);
455 checkCoeffRange<T>(c);
461 }
462};
463
465inline BiQuadCoeffs calculateHighPassCoeffs(float frequency, float sampleRate,
466 float q) {
467 float w0 = frequency * (2.0f * PI / sampleRate);
468 float sinW0 = sin(w0);
469 float alpha = sinW0 / (q * 2.0f);
470 float cosW0 = cos(w0);
471 float scale = 1.0f / (1.0f + alpha);
472 BiQuadCoeffs c;
473 c.b_0 = ((1.0f + cosW0) / 2.0f) * scale;
474 c.b_1 = -(1.0f + cosW0) * scale;
475 c.b_2 = c.b_0;
476 c.a_1 = (-2.0f * cosW0) * scale;
477 c.a_2 = (1.0f - alpha) * scale;
478 return c;
479}
480
495template <typename T = float>
496class HighPassFilter : public BiQuadDF2<T> {
497 public:
498 HighPassFilter() = default;
499 HighPassFilter(float frequency, float sampleRate, float q = 0.7071f)
500 : BiQuadDF2<T>() {
501 begin(frequency, sampleRate, q);
502 }
503 void begin(float frequency, float sampleRate, float q = 0.7071f) {
504 BiQuadCoeffs c = calculateHighPassCoeffs(frequency, sampleRate, q);
505 checkCoeffRange<T>(c);
511 }
512};
513
528template <typename T = float>
529class HighPassFilterDF1 : public BiQuadDF1<T> {
530 public:
531 HighPassFilterDF1() = default;
532 HighPassFilterDF1(float frequency, float sampleRate, float q = 0.7071f)
533 : BiQuadDF1<T>() {
534 begin(frequency, sampleRate, q);
535 }
536 void begin(float frequency, float sampleRate, float q = 0.7071f) {
537 BiQuadCoeffs c = calculateHighPassCoeffs(frequency, sampleRate, q);
538 checkCoeffRange<T>(c);
544 }
545};
546
548inline BiQuadCoeffs calculateBandPassCoeffs(float frequency, float sampleRate,
549 float q) {
550 float w0 = frequency * (2.0f * PI / sampleRate);
551 float sinW0 = sin(w0);
552 float alpha = sinW0 / (q * 2.0f);
553 float cosW0 = cos(w0);
554 float scale = 1.0f / (1.0f + alpha);
555 BiQuadCoeffs c;
556 c.b_0 = alpha * scale;
557 c.b_1 = 0;
558 c.b_2 = (-alpha) * scale;
559 c.a_1 = (-2.0f * cosW0) * scale;
560 c.a_2 = (1.0f - alpha) * scale;
561 return c;
562}
563
579template <typename T = float>
580class BandPassFilter : public BiQuadDF2<T> {
581 public:
582 BandPassFilter() = default;
583 BandPassFilter(float frequency, float sampleRate, float q = 1.0)
584 : BiQuadDF2<T>() {
585 begin(frequency, sampleRate, q);
586 }
587 void begin(float frequency, float sampleRate, float q = 1.0) {
588 BiQuadCoeffs c = calculateBandPassCoeffs(frequency, sampleRate, q);
589 checkCoeffRange<T>(c);
595 }
596};
597
612template <typename T = float>
613class BandPassFilterDF1 : public BiQuadDF1<T> {
614 public:
615 BandPassFilterDF1() = default;
616 BandPassFilterDF1(float frequency, float sampleRate, float q = 1.0)
617 : BiQuadDF1<T>() {
618 begin(frequency, sampleRate, q);
619 }
620 void begin(float frequency, float sampleRate, float q = 1.0) {
621 BiQuadCoeffs c = calculateBandPassCoeffs(frequency, sampleRate, q);
622 checkCoeffRange<T>(c);
628 }
629};
630
631
634inline BiQuadCoeffs calculateNotchCoeffs(float frequency, float sampleRate,
635 float q) {
636 float w0 = frequency * (2.0f * PI / sampleRate);
637 float sinW0 = sin(w0);
638 float alpha = sinW0 / (q * 2.0f);
639 float cosW0 = cos(w0);
640 float scale = 1.0f / (1.0f + alpha);
641 BiQuadCoeffs c;
642 c.b_0 = scale;
643 c.b_1 = (-2.0f * cosW0) * scale;
644 c.b_2 = c.b_0;
645 c.a_1 = (-2.0f * cosW0) * scale;
646 c.a_2 = (1.0f - alpha) * scale;
647 return c;
648}
649
666template <typename T = float>
667class NotchFilter : public BiQuadDF2<T> {
668 public:
669 NotchFilter() = default;
670 NotchFilter(float frequency, float sampleRate, float q = 1.0)
671 : BiQuadDF2<T>() {
672 begin(frequency, sampleRate, q);
673 }
674
675 void begin(float frequency, float sampleRate, float q = 1.0) {
676 BiQuadCoeffs c = calculateNotchCoeffs(frequency, sampleRate, q);
677 checkCoeffRange<T>(c);
683 }
684};
685
701template <typename T = float>
702class NotchFilterDF1 : public BiQuadDF1<T> {
703 public:
704 NotchFilterDF1() = default;
705 NotchFilterDF1(float frequency, float sampleRate, float q = 1.0)
706 : BiQuadDF1<T>() {
707 begin(frequency, sampleRate, q);
708 }
709
710 void begin(float frequency, float sampleRate, float q = 1.0) {
711 BiQuadCoeffs c = calculateNotchCoeffs(frequency, sampleRate, q);
712 checkCoeffRange<T>(c);
718 }
719};
720
722inline BiQuadCoeffs calculateLowShelfCoeffs(float frequency, float sampleRate,
723 float gain, float slope) {
724 float a = pow(10.0f, gain / 40.0f);
725 float w0 = frequency * (2.0f * PI / sampleRate);
726 float sinW0 = sin(w0);
727 // float alpha = (sinW0 * sqrt((a+1/a)*(1/slope-1)+2) ) / 2.0;
728 float cosW0 = cos(w0);
729 // generate three helper-values (intermediate results):
730 float sinsq =
731 sinW0 * sqrt((pow(a, 2.0f) + 1.0f) * (1.0f / slope - 1.0f) + 2.0f * a);
732 float aMinus = (a - 1.0f) * cosW0;
733 float aPlus = (a + 1.0f) * cosW0;
734 float scale = 1.0f / ((a + 1.0f) + aMinus + sinsq);
735 BiQuadCoeffs c;
736 c.b_0 = a * ((a + 1.0f) - aMinus + sinsq) * scale;
737 c.b_1 = 2.0f * a * ((a - 1.0f) - aPlus) * scale;
738 c.b_2 = a * ((a + 1.0f) - aMinus - sinsq) * scale;
739 c.a_1 = -2.0f * ((a - 1.0f) + aPlus) * scale;
740 c.a_2 = ((a + 1.0f) + aMinus - sinsq) * scale;
741 return c;
742}
743
766template <typename T = float>
767class LowShelfFilter : public BiQuadDF2<T> {
768 public:
769 LowShelfFilter() = default;
770 LowShelfFilter(float frequency, float sampleRate, float gain,
771 float slope = 1.0f)
772 : BiQuadDF2<T>() {
773 begin(frequency, sampleRate, gain, slope);
774 }
775
776 void begin(float frequency, float sampleRate, float gain,
777 float slope = 1.0f) {
778 BiQuadCoeffs c = calculateLowShelfCoeffs(frequency, sampleRate, gain, slope);
779 checkCoeffRange<T>(c);
785 }
786};
787
807template <typename T = float>
808class LowShelfFilterDF1 : public BiQuadDF1<T> {
809 public:
810 LowShelfFilterDF1() = default;
811 LowShelfFilterDF1(float frequency, float sampleRate, float gain,
812 float slope = 1.0f)
813 : BiQuadDF1<T>() {
814 begin(frequency, sampleRate, gain, slope);
815 }
816
817 void begin(float frequency, float sampleRate, float gain,
818 float slope = 1.0f) {
819 BiQuadCoeffs c = calculateLowShelfCoeffs(frequency, sampleRate, gain, slope);
820 checkCoeffRange<T>(c);
826 }
827};
828
831 float sampleRate, float gain,
832 float slope) {
833 float a = pow(10.0f, gain / 40.0f);
834 float w0 = frequency * (2.0f * PI / sampleRate);
835 float sinW0 = sin(w0);
836 // float alpha = (sinW0 * sqrt((a+1/a)*(1/slope-1)+2) ) / 2.0;
837 float cosW0 = cos(w0);
838 // generate three helper-values (intermediate results):
839 float sinsq =
840 sinW0 * sqrt((pow(a, 2.0f) + 1.0f) * (1.0f / slope - 1.0f) + 2.0f * a);
841 float aMinus = (a - 1.0f) * cosW0;
842 float aPlus = (a + 1.0f) * cosW0;
843 float scale = 1.0f / ((a + 1.0f) - aMinus + sinsq);
844 BiQuadCoeffs c;
845 c.b_0 = a * ((a + 1.0f) + aMinus + sinsq) * scale;
846 c.b_1 = -2.0f * a * ((a - 1.0f) + aPlus) * scale;
847 c.b_2 = a * ((a + 1.0f) + aMinus - sinsq) * scale;
848 c.a_1 = 2.0f * ((a - 1.0f) - aPlus) * scale;
849 c.a_2 = ((a + 1.0f) - aMinus - sinsq) * scale;
850 return c;
851}
852
876template <typename T = float>
877class HighShelfFilter : public BiQuadDF2<T> {
878 public:
879 HighShelfFilter() = default;
880 HighShelfFilter(float frequency, float sampleRate, float gain,
881 float slope = 1.0f)
882 : BiQuadDF2<T>() {
883 begin(frequency, sampleRate, gain, slope);
884 }
885 void begin(float frequency, float sampleRate, float gain,
886 float slope = 1.0f) {
887 BiQuadCoeffs c = calculateHighShelfCoeffs(frequency, sampleRate, gain, slope);
888 checkCoeffRange<T>(c);
894 }
895};
896
914template <typename T = float>
915class HighShelfFilterDF1 : public BiQuadDF1<T> {
916 public:
918 HighShelfFilterDF1(float frequency, float sampleRate, float gain,
919 float slope = 1.0f)
920 : BiQuadDF1<T>() {
921 begin(frequency, sampleRate, gain, slope);
922 }
923 void begin(float frequency, float sampleRate, float gain,
924 float slope = 1.0f) {
925 BiQuadCoeffs c = calculateHighShelfCoeffs(frequency, sampleRate, gain, slope);
926 checkCoeffRange<T>(c);
932 }
933};
934
948template <typename T, size_t N>
949class SOSFilter : public Filter<T> {
950 public:
951 SOSFilter(const T (&b)[N][3], const T (&a)[N][3], const T (&gain)[N]) {
952 for (size_t i = 0; i < N; i++)
953 filters[i] = new BiQuadDF2<T>(b[i], a[i], gain[i]);
954 }
955 SOSFilter(const T (&sos)[N][6], const T (&gain)[N]) {
956 for (size_t i = 0; i < N; i++) {
957 T b[3];
958 T a[3];
959 copy(b, &sos[i][0]);
960 copy(a, &sos[i][3]);
961 filters[i] = new BiQuadDF2<T>(b, a, gain[i]);
962 }
963 }
964 SOSFilter(const T (&b)[N][3], const T (&a)[N][2], const T (&gain)[N]) {
965 for (size_t i = 0; i < N; i++)
966 filters[i] = new BiQuadDF2<T>(b[i], a[i], gain[i]);
967 }
968 SOSFilter(const T (&b)[N][3], const T (&a)[N][2]) {
969 for (size_t i = 0; i < N; i++) filters[i] = new BiQuadDF2<T>(b[i], a[i]);
970 }
971 SOSFilter(const T (&b)[N][3], const T (&a)[N][3]) {
972 for (size_t i = 0; i < N; i++) filters[i] = new BiQuadDF2<T>(b[i], a[i]);
973 }
974 SOSFilter(SOSFilter const&) = delete;
975 SOSFilter& operator=(SOSFilter const&) = delete;
977 for (size_t i = 0; i < N; i++) delete filters[i];
978 }
979 void reset() override {
980 for (Filter<T>*& filter : filters) filter->reset();
981 }
982 T process(T value) override {
983 for (Filter<T>*& filter : filters) value = filter->process(value);
984 return value;
985 }
986
987 private:
988 Filter<T>* filters[N];
989 template <size_t M>
990 void copy(T (&dest)[M], const T* src) {
991 for (size_t i = 0; i < M; i++) dest[i] = src[i];
992 }
993};
994
1003template <typename T, size_t N>
1004class FilterChain : public Filter<T> {
1005 public:
1006 FilterChain(Filter<T>* (&&filters)[N]) {
1007 for (size_t i = 0; i < N; i++) {
1008 this->filters[i] = filters[i];
1009 }
1010 }
1011
1012 void reset() override {
1013 for (Filter<T>*& filter : filters) {
1014 if (filter != nullptr) filter->reset();
1015 }
1016 }
1017
1018 T process(T value) override {
1019 for (Filter<T>*& filter : filters) {
1020 if (filter != nullptr) {
1021 value = filter->process(value);
1022 }
1023 }
1024 return value;
1025 }
1026
1027 private:
1028 Filter<T>* filters[N] = {0};
1029};
1030
1031} // namespace audio_tools
#define PI
Definition AudioEffectsSuite.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Second-order band-pass filter (BiQuad DF1). Same coefficients as BandPassFilter; use this (not BandPa...
Definition Filter.h:613
BandPassFilterDF1(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:616
void begin(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:620
Second-order band-pass filter (BiQuad DF2). Passes frequencies near the center frequency and attenuat...
Definition Filter.h:580
BandPassFilter(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:583
void begin(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:587
Second-order IIR filter in Direct Form I. Maintains separate input and output histories (x and y dela...
Definition Filter.h:220
T process(T value) override
Processes the input value and returns the filtered output value.
Definition Filter.h:245
T y_2
Definition Filter.h:269
T a_2
Definition Filter.h:261
T y_1
Definition Filter.h:268
BiQuadDF1(const T(&b)[3], const T(&a)[2])
Definition Filter.h:228
T x_1
Definition Filter.h:267
T b_1
Definition Filter.h:258
T b_2
Definition Filter.h:259
T a_1
Definition Filter.h:260
T x_0
Definition Filter.h:266
BiQuadDF1(const T(&b)[3], const T(&a)[3], T gain)
Definition Filter.h:236
BiQuadDF1(const T(&b)[3], const T(&a)[3])
Definition Filter.h:222
T b_0
Definition Filter.h:257
void reset() override
Definition Filter.h:243
BiQuadDF1(const T(&b)[3], const T(&a)[2], T gain)
Definition Filter.h:230
Second-order IIR filter in Direct Form II. Uses a single delay line, requiring less memory than DF1....
Definition Filter.h:284
T process(T value) override
Processes the input value and returns the filtered output value.
Definition Filter.h:309
T a_2
Definition Filter.h:322
T w_0
Definition Filter.h:327
BiQuadDF2(const T(&b)[3], const T(&a)[3])
Definition Filter.h:286
T w_1
Definition Filter.h:328
T b_1
Definition Filter.h:319
T b_2
Definition Filter.h:320
BiQuadDF2(const T(&b)[3], const T(&a)[3], T gain)
Definition Filter.h:300
T a_1
Definition Filter.h:321
BiQuadDF2(const T(&b)[3], const T(&a)[2])
Definition Filter.h:292
T b_0
Definition Filter.h:318
void reset() override
Definition Filter.h:307
BiQuadDF2(const T(&b)[3], const T(&a)[2], T gain)
Definition Filter.h:294
Finite Impulse Response (FIR) filter. Performs convolution of the input signal with a set of feedforw...
Definition Filter.h:69
T process(T value) override
Processes the input value and returns the filtered output value.
Definition Filter.h:91
void setValues(const T(&b)[B])
Definition Filter.h:78
void reset() override
Definition Filter.h:86
A cascade of N arbitrary filters applied in series. Each sample is passed through all filters in orde...
Definition Filter.h:1004
T process(T value) override
Processes the input value and returns the filtered output value.
Definition Filter.h:1018
void reset() override
Definition Filter.h:1012
FilterChain(Filter< T > *(&&filters)[N])
Definition Filter.h:1006
Abstract filter interface definition. Subclasses implement process() to transform audio samples one a...
Definition Filter.h:28
virtual void reset()
Definition Filter.h:40
Filter(Filter const &)=delete
virtual T process(T in)=0
Processes the input value and returns the filtered output value.
Filter & operator=(Filter const &)=delete
virtual ~Filter()=default
Second-order high-pass filter (BiQuad DF1). Same coefficients as HighPassFilter; use this (not HighPa...
Definition Filter.h:529
HighPassFilterDF1(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:532
void begin(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:536
Second-order high-pass filter (BiQuad DF2). Attenuates frequencies below the cutoff frequency....
Definition Filter.h:496
HighPassFilter(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:499
void begin(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:503
Second-order high-shelf filter (BiQuad DF1). Same coefficients as HighShelfFilter....
Definition Filter.h:915
void begin(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:923
HighShelfFilterDF1(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:918
Second-order high-shelf filter (BiQuad DF2). Boosts or cuts frequencies above the shelf frequency by ...
Definition Filter.h:877
HighShelfFilter(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:880
void begin(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:885
Infinite Impulse Response (IIR) filter. Uses both feedforward (b[]) and feedback (a[]) coefficients....
Definition Filter.h:137
T process(T value) override
Processes the input value and returns the filtered output value.
Definition Filter.h:163
IIR(const T(&b)[B], const T(&_a)[A], T factor=1.0)
Definition Filter.h:140
void reset() override
Definition Filter.h:156
Second-order low-pass filter (BiQuad DF1). Same coefficients as LowPassFilter, but built on BiQuadDF1...
Definition Filter.h:446
LowPassFilterDF1(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:449
void begin(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:453
Second-order low-pass filter (BiQuad DF2). Attenuates frequencies above the cutoff frequency....
Definition Filter.h:410
void begin(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:417
LowPassFilter(float frequency, float sampleRate, float q=0.7071f)
Definition Filter.h:413
Second-order low-shelf filter (BiQuad DF1). Same coefficients as LowShelfFilter. NOTE: switching to D...
Definition Filter.h:808
LowShelfFilterDF1(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:811
void begin(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:817
Second-order low-shelf filter (BiQuad DF2). Boosts or cuts frequencies below the shelf frequency by t...
Definition Filter.h:767
void begin(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:776
LowShelfFilter(float frequency, float sampleRate, float gain, float slope=1.0f)
Definition Filter.h:770
Passes the input through unchanged. Useful as a placeholder when a Filter is required but no processi...
Definition Filter.h:51
T process(T in) override
Processes the input value and returns the filtered output value.
Definition Filter.h:55
Second-order notch (band-reject) filter (BiQuad DF1). Same coefficients as NotchFilter; use this (not...
Definition Filter.h:702
void begin(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:710
NotchFilterDF1(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:705
Second-order notch (band-reject) filter (BiQuad DF2). Rejects frequencies near the center frequency a...
Definition Filter.h:667
NotchFilter(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:670
void begin(float frequency, float sampleRate, float q=1.0)
Definition Filter.h:675
Second Order Sections (SOS) filter — a cascade of N BiQuad DF2 stages. Higher-order filters should be...
Definition Filter.h:949
SOSFilter(const T(&b)[N][3], const T(&a)[N][2], const T(&gain)[N])
Definition Filter.h:964
T process(T value) override
Processes the input value and returns the filtered output value.
Definition Filter.h:982
SOSFilter & operator=(SOSFilter const &)=delete
SOSFilter(const T(&b)[N][3], const T(&a)[N][3], const T(&gain)[N])
Definition Filter.h:951
SOSFilter(const T(&b)[N][3], const T(&a)[N][3])
Definition Filter.h:971
SOSFilter(SOSFilter const &)=delete
~SOSFilter()
Definition Filter.h:976
SOSFilter(const T(&sos)[N][6], const T(&gain)[N])
Definition Filter.h:955
SOSFilter(const T(&b)[N][3], const T(&a)[N][2])
Definition Filter.h:968
void reset() override
Definition Filter.h:979
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
BiQuadCoeffs calculateHighShelfCoeffs(float frequency, float sampleRate, float gain, float slope)
Computes the b0/b1/b2/a1/a2 biquad coefficients for a high-shelf filter.
Definition Filter.h:830
BiQuadCoeffs calculateBandPassCoeffs(float frequency, float sampleRate, float q)
Computes the b0/b1/b2/a1/a2 biquad coefficients for a band-pass filter.
Definition Filter.h:548
void checkCoeffRange(const BiQuadCoeffs &c)
Warns (once per call, via LOGE) about any coefficient that doesn't survive being stored in T....
Definition Filter.h:356
BiQuadCoeffs calculateLowShelfCoeffs(float frequency, float sampleRate, float gain, float slope)
Computes the b0/b1/b2/a1/a2 biquad coefficients for a low-shelf filter.
Definition Filter.h:722
BiQuadCoeffs calculateLowPassCoeffs(float frequency, float sampleRate, float q)
Computes the b0/b1/b2/a1/a2 biquad coefficients for a low-pass filter.
Definition Filter.h:377
BiQuadCoeffs calculateHighPassCoeffs(float frequency, float sampleRate, float q)
Computes the b0/b1/b2/a1/a2 biquad coefficients for a high-pass filter.
Definition Filter.h:465
BiQuadCoeffs calculateNotchCoeffs(float frequency, float sampleRate, float q)
Definition Filter.h:634
Biquad coefficients, always computed in float regardless of the filter's sample type T....
Definition Filter.h:340
float a_2
Definition Filter.h:341
float a_1
Definition Filter.h:341
float b_1
Definition Filter.h:341
float b_0
Definition Filter.h:341
float b_2
Definition Filter.h:341