32 template <
typename FloatType>
35 double sampleRate,
size_t order,
39 jassert (sampleRate > 0);
40 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
45 auto normalisedFrequency = frequency / sampleRate;
47 for (
size_t i = 0; i <= order; ++i)
51 c[i] =
static_cast<FloatType
> (normalisedFrequency * 2);
56 c[i] =
static_cast<FloatType
> (std::sin (2.0 * indice * normalisedFrequency) / indice);
66 template <
typename FloatType>
69 FloatType normalisedTransitionWidth,
70 FloatType amplitudedB)
72 jassert (sampleRate > 0);
73 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
74 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
75 jassert (amplitudedB >= -100 && amplitudedB <= 0);
79 if (amplitudedB < -50)
80 beta =
static_cast<FloatType
> (0.1102 * (-amplitudedB - 8.7));
81 else if (amplitudedB <= -21)
82 beta =
static_cast<FloatType
> (0.5842 * std::pow (-amplitudedB - 21, 0.4) + 0.07886 * (-amplitudedB - 21));
84 int order = amplitudedB < -21 ? roundToInt (std::ceil ((-amplitudedB - 7.95) / (2.285 * normalisedTransitionWidth *
MathConstants<double>::twoPi)))
85 : roundToInt (std::ceil (5.79 / (normalisedTransitionWidth * MathConstants<double>::twoPi)));
89 return designFIRLowpassWindowMethod (frequency, sampleRate, static_cast<size_t> (order),
94 template <
typename FloatType>
97 FloatType normalisedTransitionWidth, FloatType spline)
99 jassert (sampleRate > 0);
100 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
101 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
102 jassert (spline >= 1.0 && spline <= 4.0);
104 auto normalisedFrequency = frequency /
static_cast<FloatType
> (sampleRate);
109 for (
size_t i = 0; i <= order; ++i)
111 if (i == order / 2 && order % 2 == 0)
113 c[i] =
static_cast<FloatType
> (2 * normalisedFrequency);
119 c[i] =
static_cast<FloatType
> (std::sin (2 * indice * normalisedFrequency)
120 / indice * std::pow (std::sin (indice2) / indice2, spline));
127 template <
typename FloatType>
130 double sampleRate,
size_t order,
131 FloatType normalisedTransitionWidth,
132 FloatType stopBandWeight)
134 jassert (sampleRate > 0);
135 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
136 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
137 jassert (stopBandWeight >= 1.0 && stopBandWeight <= 100.0);
139 auto normalisedFrequency =
static_cast<double> (frequency) / sampleRate;
147 auto* c = result->getRawCoefficients();
152 auto M = (N - 1) / 2;
158 / (MathConstants<double>::pi * x); };
163 for (
size_t i = 0; i <= M; ++i)
164 b (i, 0) = factorp * sinc (factorp * i);
166 q (0, 0) = factorp + stopBandWeight * (1.0 - factors);
168 for (
size_t i = 1; i <= 2 * M; ++i)
169 q (i, 0) = factorp * sinc (factorp * i) - stopBandWeight * factors * sinc (factors * i);
178 c[M] =
static_cast<FloatType
> (b (0, 0));
180 for (
size_t i = 1; i <= M; ++i)
182 c[M - i] =
static_cast<FloatType
> (b (i, 0) * 0.5);
183 c[M + i] =
static_cast<FloatType
> (b (i, 0) * 0.5);
196 / (MathConstants<double>::pi * x); };
201 for (
size_t i = 0; i < M; ++i)
202 b (i, 0) = factorp * sinc (factorp * (i + 0.5));
204 for (
size_t i = 0; i < 2 * M; ++i)
206 qp (i, 0) = 0.25 * factorp * sinc (factorp * i);
207 qs (i, 0) = -0.25 * stopBandWeight * factors * sinc (factors * i);
216 Id *= (0.25 * stopBandWeight);
227 for (
size_t i = 0; i < M; ++i)
229 c[M - i - 1] =
static_cast<FloatType
> (b (i, 0) * 0.25);
230 c[M + i] =
static_cast<FloatType
> (b (i, 0) * 0.25);
237 template <
typename FloatType>
240 FloatType amplitudedB)
242 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
243 jassert (amplitudedB >= -300 && amplitudedB <= -10);
247 auto n = roundToInt (std::ceil ((amplitudedB - 18.18840664 * wpT + 33.64775300) / (18.54155181 * wpT - 29.13196871)));
248 auto kp = (n * wpT - 1.57111377 * n + 0.00665857) / (-1.01927560 * n + 0.37221484);
249 auto A = (0.01525753 * n + 0.03682344 + 9.24760314 / (double) n) * kp + 1.01701407 + 0.73512298 / (double) n;
250 auto B = (0.00233667 * n - 1.35418408 + 5.75145813 / (double) n) * kp + 1.02999650 - 0.72759508 / (double) n;
255 auto diff = (hn.size() - hnm.size()) / 2;
257 for (
int i = 0; i < diff; ++i)
265 for (
int i = 0; i < hn.size(); ++i)
266 hh.setUnchecked (i, A * hh[i] + B * hnm[i]);
269 auto* c = result->getRawCoefficients();
271 for (
int i = 0; i < hh.size(); ++i)
272 c[i] = (
float) hh[i];
278 NN = 2.0 * result->getMagnitudeForFrequency (0.5, 1.0);
283 auto om01 = std::acos (-w01);
288 for (
int i = 0; i < hh.size(); ++i)
289 c[i] = static_cast<FloatType> ((A * hn[i] + B * hnm[i]) / NN);
291 c[2 * n + 1] =
static_cast<FloatType
> (0.5);
296 template <
typename FloatType>
302 alpha.
setUnchecked (2 * n, 1.0 / std::pow (1.0 - kp * kp, n));
305 alpha.
setUnchecked (2 * n - 2, -(2 * n * kp * kp + 1) * alpha[2 * n]);
308 alpha.
setUnchecked (2 * n - 4, -(4 * n + 1 + (n - 1) * (2 * n - 1) * kp * kp) / (2.0 * n) * alpha[2 * n - 2]
309 - (2 * n + 1) * ((n + 1) * kp * kp + 1) / (2.0 * n) * alpha[2 * n]);
311 for (
int k = n; k >= 3; --k)
313 auto c1 = (3 * (n*(n + 2) - k * (k - 2)) + 2 * k - 3 + 2 * (k - 2)*(2 * k - 3) * kp * kp) * alpha[2 * k - 4];
314 auto c2 = (3 * (n*(n + 2) - (k - 1) * (k + 1)) + 2 * (2 * k - 1) + 2 * k*(2 * k - 1) * kp * kp) * alpha[2 * k - 2];
315 auto c3 = (n * (n + 2) - (k - 1) * (k + 1)) * alpha[2 * k];
316 auto c4 = (n * (n + 2) - (k - 3) * (k - 1));
322 ai.
resize (2 * n + 1 + 1);
324 for (
int k = 0; k <= n; ++k)
325 ai.
setUnchecked (2 * k + 1, alpha[2 * k] / (2.0 * k + 1.0));
328 hn.
resize (2 * n + 1 + 2 * n + 1 + 1);
330 for (
int k = 0; k <= n; ++k)
332 hn.
setUnchecked (2 * n + 1 + (2 * k + 1), 0.5 * ai[2 * k + 1]);
333 hn.
setUnchecked (2 * n + 1 - (2 * k + 1), 0.5 * ai[2 * k + 1]);
339 template <
typename FloatType>
342 FloatType normalisedTransitionWidth,
343 FloatType passbandAmplitudedB,
344 FloatType stopbandAmplitudedB)
346 return designIIRLowpassHighOrderGeneralMethod (0, frequency, sampleRate, normalisedTransitionWidth,
347 passbandAmplitudedB, stopbandAmplitudedB);
350 template <
typename FloatType>
353 FloatType normalisedTransitionWidth,
354 FloatType passbandAmplitudedB,
355 FloatType stopbandAmplitudedB)
357 return designIIRLowpassHighOrderGeneralMethod (1, frequency, sampleRate, normalisedTransitionWidth,
358 passbandAmplitudedB, stopbandAmplitudedB);
361 template <
typename FloatType>
364 FloatType normalisedTransitionWidth,
365 FloatType passbandAmplitudedB,
366 FloatType stopbandAmplitudedB)
368 return designIIRLowpassHighOrderGeneralMethod (2, frequency, sampleRate, normalisedTransitionWidth,
369 passbandAmplitudedB, stopbandAmplitudedB);
372 template <
typename FloatType>
375 FloatType normalisedTransitionWidth,
376 FloatType passbandAmplitudedB,
377 FloatType stopbandAmplitudedB)
379 return designIIRLowpassHighOrderGeneralMethod (3, frequency, sampleRate, normalisedTransitionWidth,
380 passbandAmplitudedB, stopbandAmplitudedB);
383 template <
typename FloatType>
386 FloatType normalisedTransitionWidth,
387 FloatType passbandAmplitudedB,
388 FloatType stopbandAmplitudedB)
390 jassert (sampleRate > 0);
391 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
392 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
393 jassert (passbandAmplitudedB > -20 && passbandAmplitudedB < 0);
394 jassert (stopbandAmplitudedB > -300 && stopbandAmplitudedB < -20);
396 auto normalisedFrequency = frequency / sampleRate;
398 auto fp = normalisedFrequency - normalisedTransitionWidth / 2;
399 auto fs = normalisedFrequency + normalisedTransitionWidth / 2;
401 double Ap = passbandAmplitudedB;
402 double As = stopbandAmplitudedB;
405 auto epsp = std::sqrt (1.0 / (Gp * Gp) - 1.0);
406 auto epss = std::sqrt (1.0 / (Gs * Gs) - 1.0);
412 auto k = omegap / omegas;
413 auto k1 = epsp / epss;
419 N = roundToInt (std::ceil (std::log (1.0 / k1) / std::log (1.0 / k)));
421 else if (type == 1 || type == 2)
423 N = roundToInt (std::ceil (std::acosh (1.0 / k1) / std::acosh (1.0 / k)));
427 double K, Kp, K1, K1p;
432 N = roundToInt (std::ceil ((K1p * K) / (K1 * Kp)));
436 const int L = (N - r) / 2;
437 const double H0 = (type == 1 || type == 3) ? std::pow (Gp, 1.0 - r) : 1.0;
440 Complex<double> j (0, 1);
445 pa.
add (-omegap * std::pow (epsp, -1.0 / (
double) N));
447 for (
int i = 1; i <= L; ++i)
449 auto ui = (2 * i - 1.0) / (double) N;
450 pa.
add (omegap * std::pow (epsp, -1.0 / (
double) N) * j * exp (ui * halfPi * j));
455 auto v0 = std::asinh (1.0 / epsp) / (N * halfPi);
458 pa.
add (-omegap * std::sinh (v0 * halfPi));
460 for (
int i = 1; i <= L; ++i)
462 auto ui = (2 * i - 1.0) / (double) N;
463 pa.
add (omegap * j * std::cos ((ui - j * v0) * halfPi));
468 auto v0 = std::asinh (epss) / (N * halfPi);
471 pa.
add(-1.0 / (k / omegap * std::sinh (v0 * halfPi)));
473 for (
int i = 1; i <= L; ++i)
475 auto ui = (2 * i - 1.0) / (double) N;
477 pa.
add (1.0 / (k / omegap * j * std::cos ((ui - j * v0) * halfPi)));
478 za.
add (1.0 / (k / omegap * j * std::cos (ui * halfPi)));
488 for (
int i = 1; i <= L; ++i)
490 auto ui = (2 * i - 1.0) / (double) N;
494 za.
add (omegap * j / (k * zetai));
502 p.
add ((1.0 + pa[0]) / (1.0 - pa[0]));
503 g.
add (0.5 * (1.0 - p[0]));
506 for (
int i = 0; i < L; ++i)
508 p.
add ((1.0 + pa[i + r]) / (1.0 - pa[i + r]));
509 z.
add (za.
size() == 0 ? -1.0 : (1.0 + za[i]) / (1.0 - za[i]));
510 g.
add ((1.0 - p[i + r]) / (1.0 - z[i]));
517 auto b0 =
static_cast<FloatType
> (H0 * std::real (g[0]));
519 auto a1 =
static_cast<FloatType
> (-std::real (p[0]));
524 for (
int i = 0; i < L; ++i)
526 auto gain = std::pow (std::abs (g[i + r]), 2.0);
528 auto b0 =
static_cast<FloatType
> (gain);
529 auto b1 =
static_cast<FloatType
> (std::real (-z[i] - std::conj (z[i])) * gain);
530 auto b2 =
static_cast<FloatType
> (std::real ( z[i] * std::conj (z[i])) * gain);
532 auto a1 =
static_cast<FloatType
> (std::real (-p[i+r] - std::conj (p[i + r])));
533 auto a2 =
static_cast<FloatType
> (std::real ( p[i+r] * std::conj (p[i + r])));
538 return cascadedCoefficients;
541 template <
typename FloatType>
544 double sampleRate,
int order)
546 jassert (sampleRate > 0);
547 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
556 for (
auto i = 0; i < order / 2; ++i)
560 static_cast<FloatType> (Q)));
565 for (
auto i = 0; i < order / 2; ++i)
569 static_cast<FloatType> (Q)));
576 template <
typename FloatType>
579 double sampleRate,
int order)
581 jassert (sampleRate > 0);
582 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
591 for (
auto i = 0; i < order / 2; ++i)
595 static_cast<FloatType> (Q)));
600 for (
auto i = 0; i < order / 2; ++i)
604 static_cast<FloatType> (Q)));
611 template <
typename FloatType>
614 FloatType stopbandAmplitudedB)
616 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
617 jassert (stopbandAmplitudedB > -300 && stopbandAmplitudedB < -10);
623 auto kp = std::sqrt (1.0 - k * k);
624 auto e = (1 - std::sqrt (kp)) / (1 + std::sqrt (kp)) * 0.5;
625 auto q = e + 2 * std::pow (e, 5.0) + 15 * std::pow (e, 9.0) + 150 * std::pow (e, 13.0);
627 auto k1 = ds * ds / (1 - ds * ds);
628 int n = roundToInt (std::ceil (std::log (k1 * k1 / 16) / std::log (q)));
636 auto q1 = std::pow (q, (
double) n);
637 k1 = 4 * std::sqrt (q1);
639 const int N = (n - 1) / 2;
642 for (
int i = 1; i <= N; ++i)
648 while (std::abs (delta) > 1e-100)
650 delta = std::pow (-1, m) * std::pow (q, m * (m + 1))
656 num *= 2 * std::pow (q, 0.25);
662 while (std::abs (delta) > 1e-100)
664 delta = std::pow (-1, m) * std::pow (q, m * m)
673 auto api = std::sqrt ((1 - wi * wi * k) * (1 - wi * wi / k)) / (1 + wi * wi);
675 ai.
add ((1 - api) / (1 + api));
680 for (
int i = 0; i < N; i += 2)
682 0, 1, 1, 0, static_cast<FloatType> (ai[i])));
686 for (
int i = 1; i < N; i += 2)
688 0, 1, 1, 0, static_cast<FloatType> (ai[i])));
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderChebyshev1Method(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderEllipticMethod(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderChebyshev2Method(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
static IIRPolyphaseAllpassStructure designIIRLowpassHalfBandPolyphaseAllpassMethod(FloatType normalisedTransitionWidth, FloatType stopbandAmplitudedB)
static Type decibelsToGain(Type decibels, Type minusInfinityDb=Type(defaultMinusInfinitydB))
void addArray(const Type *elementsToAdd, int numElementsToAdd)
void add(const ElementType &newElement)
ObjectClass * add(ObjectClass *newObject)
ReferenceCountedObjectPtr< Coefficients > Ptr
static Matrix identity(size_t size)
static FIRCoefficientsPtr designFIRLowpassLeastSquaresMethod(FloatType frequency, double sampleRate, size_t order, FloatType normalisedTransitionWidth, FloatType stopBandWeight)
void resize(int targetNumItems)
static Matrix hankel(const Matrix &vector, size_t size, size_t offset=0)
NumericType * getRawCoefficients() noexcept
static FIRCoefficientsPtr designFIRLowpassTransitionMethod(FloatType frequency, double sampleRate, size_t order, FloatType normalisedTransitionWidth, FloatType spline)
static void ellipticIntegralK(double k, double &K, double &Kp) noexcept
void setUnchecked(int indexToChange, ParameterType newValue)
void multiplyWithWindowingTable(FloatType *samples, size_t size) noexcept
static FIRCoefficientsPtr designFIRLowpassWindowMethod(FloatType frequency, double sampleRate, size_t order, WindowingMethod type, FloatType beta=static_cast< FloatType >(2))
int size() const noexcept
static Complex< double > asne(Complex< double > w, double k) noexcept
static FIRCoefficientsPtr designFIRLowpassHalfBandEquirippleMethod(FloatType normalisedTransitionWidth, FloatType amplitudedB)
static Complex< double > sne(Complex< double > u, double k) noexcept
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderButterworthMethod(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
static Matrix toeplitz(const Matrix &vector, size_t size)
static Complex< double > cde(Complex< double > u, double k) noexcept
static FIRCoefficientsPtr designFIRLowpassKaiserMethod(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType amplitudedB)
static ReferenceCountedArray< IIRCoefficients > designIIRHighpassHighOrderButterworthMethod(FloatType frequency, double sampleRate, int order)