31 template <
typename SampleType =
float>
32 static SampleType
eval(
const std::vector<SampleType>& coeffs, SampleType x) {
33 if (coeffs.empty())
return 0;
34 SampleType result = coeffs.back();
35 for (
int i =
static_cast<int>(coeffs.size()) - 2;
i >= 0; --
i) {
36 result = result * x + coeffs[
static_cast<size_t>(
i)];
42 template <
typename SampleType =
float>
44 const std::vector<SampleType>& coeffs,
45 std::complex<SampleType> z) {
46 if (coeffs.empty())
return {0, 0};
47 std::complex<SampleType> result = coeffs.back();
48 for (
int i =
static_cast<int>(coeffs.size()) - 2;
i >= 0; --
i) {
49 result = result * z + coeffs[
static_cast<size_t>(
i)];
56 template <
typename SampleType =
float>
57 static std::pair<std::complex<SampleType>, std::complex<SampleType>>
59 if (std::abs(
a) < SampleType{1e-12f}) {
60 if (std::abs(b) < SampleType{1e-12f}) {
61 return {{SampleType{0.0f}, SampleType{0.0f}},
62 {SampleType{0.0f}, SampleType{0.0f}}};
64 const auto root = std::complex<SampleType>{-
c / b, SampleType{0.0f}};
68 SampleType disc = b * b - SampleType{4.0f} *
a *
c;
70 SampleType sq = std::sqrt(disc);
71 return {(-b + sq) / (SampleType{2.0f} *
a),
72 (-b - sq) / (SampleType{2.0f} *
a)};
74 SampleType real = -b / (SampleType{2.0f} *
a);
75 SampleType imag = std::sqrt(-disc) / (SampleType{2.0f} *
a);
76 return {{real, imag}, {real, -imag}};
81 template <
typename SampleType =
float>
82 static std::vector<SampleType>
multiply(
const std::vector<SampleType>&
a,
83 const std::vector<SampleType>& b) {
84 if (
a.empty() || b.empty())
return {};
85 std::vector<SampleType> result(
a.size() + b.size() - 1, SampleType{0.0f});
86 for (
size_t i = 0;
i <
a.size(); ++
i) {
87 for (
size_t j = 0; j < b.size(); ++j) {
88 result[
i + j] +=
a[
i] * b[j];
95 template <
typename SampleType =
float>
96 static std::vector<SampleType>
add(
const std::vector<SampleType>&
a,
97 const std::vector<SampleType>& b) {
98 auto& longer = (
a.size() >= b.size()) ?
a : b;
99 auto& shorter = (
a.size() >= b.size()) ? b :
a;
100 std::vector<SampleType> result = longer;
101 for (
size_t i = 0;
i < shorter.size(); ++
i) {
102 result[
i] += shorter[
i];
108 template <
typename SampleType =
float>
109 static std::vector<SampleType>
scale(
const std::vector<SampleType>& p,
111 std::vector<SampleType> result(p.size());
112 for (
size_t i = 0;
i < p.size(); ++
i) result[
i] = p[
i] * s;
117 template <
typename SampleType =
float>
118 static std::vector<SampleType>
derivative(
const std::vector<SampleType>& p) {
119 if (p.size() <= 1)
return {0};
120 std::vector<SampleType> result(p.size() - 1);
121 for (
size_t i = 1;
i < p.size(); ++
i) {
122 result[
i - 1] = p[
i] *
static_cast<SampleType
>(
i);
129template <
typename SampleType =
float>
131 SampleType
m[2][2] = {{SampleType{1}, SampleType{0}},
132 {SampleType{0}, SampleType{1}}};
135 return {{{SampleType{1}, SampleType{0}},
136 {SampleType{0}, SampleType{1}}}};
141 r.m[0][0] =
m[0][0] * b.m[0][0] +
m[0][1] * b.m[1][0];
142 r.m[0][1] =
m[0][0] * b.m[0][1] +
m[0][1] * b.m[1][1];
143 r.m[1][0] =
m[1][0] * b.m[0][0] +
m[1][1] * b.m[1][0];
144 r.m[1][1] =
m[1][0] * b.m[0][1] +
m[1][1] * b.m[1][1];
149 return m[0][0] *
m[1][1] -
m[0][1] *
m[1][0];
154 if (std::abs(d) < SampleType{1e-10f})
return identity();
155 SampleType inv_d = SampleType{1.0f} / d;
156 return {{{
m[1][1] * inv_d, -
m[0][1] * inv_d},
157 {-
m[1][0] * inv_d,
m[0][0] * inv_d}}};
165template <
typename SampleType =
float>
167 SampleType
m[3][3] = {{SampleType{1}, SampleType{0}, SampleType{0}},
168 {SampleType{0}, SampleType{1}, SampleType{0}},
169 {SampleType{0}, SampleType{0}, SampleType{1}}};
172 return {{{SampleType{1}, SampleType{0}, SampleType{0}},
173 {SampleType{0}, SampleType{1}, SampleType{0}},
174 {SampleType{0}, SampleType{0}, SampleType{1}}}};
178 Mat3T r{{{SampleType{0}, SampleType{0}, SampleType{0}},
179 {SampleType{0}, SampleType{0}, SampleType{0}},
180 {SampleType{0}, SampleType{0}, SampleType{0}}}};
181 for (
int i = 0;
i < 3; ++
i)
182 for (
int j = 0; j < 3; ++j)
183 for (
int k = 0; k < 3; ++k)
184 r.m[
i][j] +=
m[
i][k] * b.m[k][j];
189 return m[0][0] * (
m[1][1] *
m[2][2] -
m[1][2] *
m[2][1])
190 -
m[0][1] * (
m[1][0] *
m[2][2] -
m[1][2] *
m[2][0])
191 +
m[0][2] * (
m[1][0] *
m[2][1] -
m[1][1] *
m[2][0]);
Definition additive_bank.hpp:218
Mat3T< double > Mat3d
Definition poly_math.hpp:196
Mat2T< double > Mat2d
Definition poly_math.hpp:162
@ c
Definition spectrum_trace.hpp:35
Mat3T< float > Mat3
Definition poly_math.hpp:195
Mat2T< float > Mat2
Definition poly_math.hpp:161
@ a
Definition formant_filter_bank.hpp:20
@ i
Definition formant_filter_bank.hpp:20
Simple 2x2 matrix for biquad coefficient manipulation.
Definition poly_math.hpp:130
Mat2T operator*(const Mat2T &b) const
Definition poly_math.hpp:139
SampleType determinant() const
Definition poly_math.hpp:148
static Mat2T identity()
Definition poly_math.hpp:134
Mat2T inverse() const
Definition poly_math.hpp:152
float m[2][2]
Definition poly_math.hpp:131
Simple 3x3 matrix for state-space filter representations.
Definition poly_math.hpp:166
Mat3T operator*(const Mat3T &b) const
Definition poly_math.hpp:177
float m[3][3]
Definition poly_math.hpp:167
static Mat3T identity()
Definition poly_math.hpp:171
SampleType determinant() const
Definition poly_math.hpp:188
Polynomial evaluation and manipulation utilities.
Definition poly_math.hpp:27
static std::complex< SampleType > eval_complex(const std::vector< SampleType > &coeffs, std::complex< SampleType > z)
Evaluate complex polynomial (for frequency response).
Definition poly_math.hpp:43
static std::vector< SampleType > add(const std::vector< SampleType > &a, const std::vector< SampleType > &b)
Add two polynomials. Not RT-safe.
Definition poly_math.hpp:96
static std::vector< SampleType > multiply(const std::vector< SampleType > &a, const std::vector< SampleType > &b)
Multiply two polynomials (convolution of coefficients). Not RT-safe.
Definition poly_math.hpp:82
static SampleType eval(const std::vector< SampleType > &coeffs, SampleType x)
Evaluate polynomial using Horner's method.
Definition poly_math.hpp:32
static std::vector< SampleType > scale(const std::vector< SampleType > &p, SampleType s)
Scale all coefficients by a constant. Not RT-safe.
Definition poly_math.hpp:109
static std::vector< SampleType > derivative(const std::vector< SampleType > &p)
Derivative of a polynomial. Not RT-safe.
Definition poly_math.hpp:118
static std::pair< std::complex< SampleType >, std::complex< SampleType > > roots_quadratic(SampleType a, SampleType b, SampleType c)
Roots of quadratic ax^2 + bx + c.
Definition poly_math.hpp:58