27template <
typename T =
float>
50template <
typename T =
float>
68template <
typename T =
float>
72 FIR(
const T (&b)[
B],
const T factor = 1.0)
73 : lenB(
B), factor(factor), needs_divide(factor != T(1)) {
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];
88 for (uint16_t i = 0; i < lenB; i++) x[i] = 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];
99 if (i_b == lenB) i_b = 0;
102 if (!(std::is_same<T, float>::value || std::is_same<T, double>::value)) {
103 b_terms = b_terms / factor;
111 b_terms = b_terms / factor;
136template <
typename T =
float>
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) {
144 coeff_b.resize(2 * lenB - 1);
145 coeff_a.resize(2 * lenA - 1);
148 for (uint16_t i = 0; i < 2 * lenB - 1; i++) {
149 coeff_b[i] = b[(2 * lenB - 1 - i) % lenB] / a0;
151 for (uint16_t i = 0; i < 2 * lenA - 1; i++) {
152 coeff_a[i] = a[(2 * lenA - 2 - i) % lenA] / a0;
159 for (uint16_t i = 0; i < lenB; i++) x[i] = 0;
160 for (uint16_t i = 0; i < lenA; i++) y[i] = 0;
166 T* b_shift = &coeff_b[lenB - i_b - 1];
169 T* a_shift = &coeff_a[lenA - i_a - 1];
171 for (uint16_t i = 0; i < lenB; i++) {
172 b_terms += x[i] * b_shift[i];
174 for (uint16_t i = 0; i < lenA; i++) {
175 a_terms += y[i] * a_shift[i];
178 T filtered = b_terms - a_terms;
181 if (i_b == lenB) i_b = 0;
183 if (i_a == lenA) i_a = 0;
186 if (!(std::is_same<T, float>::value || std::is_same<T, double>::value)) {
187 filtered = filtered / factor;
193 filtered = filtered / factor;
202 const uint16_t lenB, lenA;
203 uint16_t i_b = 0, i_a = 0;
219template <
typename T =
float>
237 :
b_0(gain * b[0] / a[0]),
238 b_1(gain * b[1] / a[0]),
239 b_2(gain * b[2] / a[0]),
252 y_1 = b_terms - a_terms;
283template <
typename T =
float>
301 :
b_0(gain * b[0] / a[0]),
302 b_1(gain * b[1] / a[0]),
303 b_2(gain * b[2] / a[0]),
357 auto check = [](
const char *name,
float value) {
359 float roundtrip = (float)t;
362 if (fabs(roundtrip - value) > fabs(value) * 0.01f + 1e-4f) {
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);
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);
385 c.
b_0 = ((1.0f - cosW0) / 2.0f) * scale;
386 c.
b_1 = (1.0f - cosW0) * scale;
388 c.
a_1 = (-2.0f * cosW0) * scale;
389 c.
a_2 = (1.0f - alpha) * scale;
409template <
typename T =
float>
415 begin(frequency, sampleRate, q);
417 void begin(
float frequency,
float sampleRate,
float q = 0.7071f) {
419 checkCoeffRange<T>(c);
445template <
typename T =
float>
451 begin(frequency, sampleRate, q);
453 void begin(
float frequency,
float sampleRate,
float q = 0.7071f) {
455 checkCoeffRange<T>(c);
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);
473 c.
b_0 = ((1.0f + cosW0) / 2.0f) * scale;
474 c.
b_1 = -(1.0f + cosW0) * scale;
476 c.
a_1 = (-2.0f * cosW0) * scale;
477 c.
a_2 = (1.0f - alpha) * scale;
495template <
typename T =
float>
501 begin(frequency, sampleRate, q);
503 void begin(
float frequency,
float sampleRate,
float q = 0.7071f) {
505 checkCoeffRange<T>(c);
528template <
typename T =
float>
534 begin(frequency, sampleRate, q);
536 void begin(
float frequency,
float sampleRate,
float q = 0.7071f) {
538 checkCoeffRange<T>(c);
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);
556 c.
b_0 = alpha * scale;
558 c.
b_2 = (-alpha) * scale;
559 c.
a_1 = (-2.0f * cosW0) * scale;
560 c.
a_2 = (1.0f - alpha) * scale;
579template <
typename T =
float>
585 begin(frequency, sampleRate, q);
587 void begin(
float frequency,
float sampleRate,
float q = 1.0) {
589 checkCoeffRange<T>(c);
612template <
typename T =
float>
618 begin(frequency, sampleRate, q);
620 void begin(
float frequency,
float sampleRate,
float q = 1.0) {
622 checkCoeffRange<T>(c);
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);
643 c.
b_1 = (-2.0f * cosW0) * scale;
645 c.
a_1 = (-2.0f * cosW0) * scale;
646 c.
a_2 = (1.0f - alpha) * scale;
666template <
typename T =
float>
672 begin(frequency, sampleRate, q);
675 void begin(
float frequency,
float sampleRate,
float q = 1.0) {
677 checkCoeffRange<T>(c);
701template <
typename T =
float>
707 begin(frequency, sampleRate, q);
710 void begin(
float frequency,
float sampleRate,
float q = 1.0) {
712 checkCoeffRange<T>(c);
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);
728 float cosW0 = cos(w0);
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);
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;
766template <
typename T =
float>
773 begin(frequency, sampleRate, gain, slope);
776 void begin(
float frequency,
float sampleRate,
float gain,
777 float slope = 1.0f) {
779 checkCoeffRange<T>(c);
807template <
typename T =
float>
814 begin(frequency, sampleRate, gain, slope);
817 void begin(
float frequency,
float sampleRate,
float gain,
818 float slope = 1.0f) {
820 checkCoeffRange<T>(c);
831 float sampleRate,
float gain,
833 float a = pow(10.0f, gain / 40.0f);
834 float w0 = frequency * (2.0f *
PI / sampleRate);
835 float sinW0 = sin(w0);
837 float cosW0 = cos(w0);
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);
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;
876template <
typename T =
float>
883 begin(frequency, sampleRate, gain, slope);
885 void begin(
float frequency,
float sampleRate,
float gain,
886 float slope = 1.0f) {
888 checkCoeffRange<T>(c);
914template <
typename T =
float>
921 begin(frequency, sampleRate, gain, slope);
923 void begin(
float frequency,
float sampleRate,
float gain,
924 float slope = 1.0f) {
926 checkCoeffRange<T>(c);
948template <
typename T,
size_t N>
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++)
956 for (
size_t i = 0; i < N; i++) {
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++)
969 for (
size_t i = 0; i < N; i++) filters[i] = new BiQuadDF2<T>(b[i], a[i]);
972 for (
size_t i = 0; i < N; i++) filters[i] = new BiQuadDF2<T>(b[i], a[i]);
977 for (
size_t i = 0; i < N; i++)
delete filters[i];
980 for (
Filter<T>*& filter : filters) filter->reset();
983 for (
Filter<T>*& filter : filters) value = filter->process(value);
990 void copy(T (&dest)[M],
const T* src) {
991 for (
size_t i = 0; i < M; i++) dest[i] = src[i];
1003template <
typename T,
size_t N>
1007 for (
size_t i = 0; i < N; i++) {
1008 this->filters[i] = filters[i];
1014 if (filter !=
nullptr) filter->reset();
1020 if (filter !=
nullptr) {
1021 value = filter->process(value);
#define PI
Definition AudioEffectsSuite.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30