1#ifndef CONSTFILT_FILTER_HPP
2#define CONSTFILT_FILTER_HPP
4#include "vendor/consteig/consteig.hpp"
12template <
typename T, consteig::Size NB, consteig::Size NA>
class Filter
14 static constexpr consteig::Size M = (NA > NB ? NA : NB) - 1u;
18 static_assert(NB >= 1u,
19 "Filter requires at least one numerator coefficient");
20 static_assert(NA >= 1u,
21 "Filter requires at least one denominator coefficient");
22 static_assert(M >= 1u,
"Filter requires max(NB, NA) - 1 >= 1");
27 mutable T _state[M]{};
29 constexpr Filter() =
default;
31 constexpr Filter(
const T (&b)[NB],
const T (&a)[NA])
33 for (consteig::Size i = 0; i < NB; ++i)
37 for (consteig::Size i = 0; i < NA; ++i)
44 constexpr T b_coeff(consteig::Size i)
const
46 return i < NB ? _b[i] : T(0);
48 constexpr T a_coeff(consteig::Size i)
const
50 return i < NA ? _a[i] : T(0);
58 T operator()(T x)
const
60 const T y = _b[0] * x + _state[0];
62 for (consteig::Size k = 0; k < M - 1u; ++k)
65 b_coeff(k + 1u) * x - a_coeff(k + 1u) * y + _state[k + 1u];
67 _state[M - 1u] = b_coeff(M) * x - a_coeff(M) * y;
74 template <consteig::Size N>
75 constexpr void operator()(
const T (&input)[N], T (&output)[N])
const
79 for (consteig::Size n = 0; n < N; ++n)
82 const T y = _b[0] * x + local_state[0];
84 for (consteig::Size k = 0; k < M - 1u; ++k)
86 local_state[k] = b_coeff(k + 1u) * x - a_coeff(k + 1u) * y +
89 local_state[M - 1u] = b_coeff(M) * x - a_coeff(M) * y;
96 constexpr const T *coeffs_b()
const
100 constexpr const T *coeffs_a()
const
108 for (consteig::Size k = 0; k < M; ++k)
110 _state[k] =
static_cast<T
>(0);