29constexpr auto minimumDecibels = -300.0;
31template <
typename NumericType>
33 NumericType frequency)
35 jassert (sampleRate > 0.0);
36 jassert (frequency > 0 && frequency <=
static_cast<float> (sampleRate * 0.5));
40 return { { n, n, n + 1, n - 1 } };
43template <
typename NumericType>
45 NumericType frequency)
47 jassert (sampleRate > 0.0);
48 jassert (frequency > 0 && frequency <=
static_cast<float> (sampleRate * 0.5));
52 return { { 1, -1, n + 1, n - 1 } };
55template <
typename NumericType>
57 NumericType frequency)
59 jassert (sampleRate > 0.0);
60 jassert (frequency > 0 && frequency <=
static_cast<float> (sampleRate * 0.5));
64 return { { n - 1, n + 1, n + 1, n - 1 } };
67template <
typename NumericType>
69 NumericType frequency)
71 return makeLowPass (sampleRate, frequency, inverseRootTwo);
74template <
typename NumericType>
76 NumericType frequency,
79 jassert (sampleRate > 0.0);
80 jassert (frequency > 0 && frequency <=
static_cast<float> (sampleRate * 0.5));
84 const auto nSquared = n * n;
85 const auto invQ = 1 / Q;
86 const auto c1 = 1 / (1 + invQ * n + nSquared);
88 return { { c1, c1 * 2, c1,
89 1, c1 * 2 * (1 - nSquared),
90 c1 * (1 - invQ * n + nSquared) } };
93template <
typename NumericType>
95 NumericType frequency)
97 return makeHighPass (sampleRate, frequency, inverseRootTwo);
100template <
typename NumericType>
102 NumericType frequency,
105 jassert (sampleRate > 0.0);
106 jassert (frequency > 0 && frequency <=
static_cast<float> (sampleRate * 0.5));
110 const auto nSquared = n * n;
111 const auto invQ = 1 / Q;
112 const auto c1 = 1 / (1 + invQ * n + nSquared);
114 return { { c1, c1 * -2, c1,
115 1, c1 * 2 * (nSquared - 1),
116 c1 * (1 - invQ * n + nSquared) } };
119template <
typename NumericType>
121 NumericType frequency)
123 return makeBandPass (sampleRate, frequency, inverseRootTwo);
126template <
typename NumericType>
128 NumericType frequency,
131 jassert (sampleRate > 0.0);
132 jassert (frequency > 0 && frequency <=
static_cast<float> (sampleRate * 0.5));
136 const auto nSquared = n * n;
137 const auto invQ = 1 / Q;
138 const auto c1 = 1 / (1 + invQ * n + nSquared);
140 return { { c1 * n * invQ, 0,
142 c1 * 2 * (1 - nSquared),
143 c1 * (1 - invQ * n + nSquared) } };
146template <
typename NumericType>
148 NumericType frequency)
150 return makeNotch (sampleRate, frequency, inverseRootTwo);
153template <
typename NumericType>
155 NumericType frequency,
158 jassert (sampleRate > 0.0);
159 jassert (frequency > 0 && frequency <=
static_cast<float> (sampleRate * 0.5));
163 const auto nSquared = n * n;
164 const auto invQ = 1 / Q;
165 const auto c1 = 1 / (1 + n * invQ + nSquared);
166 const auto b0 = c1 * (1 + nSquared);
167 const auto b1 = 2 * c1 * (1 - nSquared);
169 return { { b0, b1, b0, 1, b1, c1 * (1 - n * invQ + nSquared) } };
172template <
typename NumericType>
174 NumericType frequency)
176 return makeAllPass (sampleRate, frequency, inverseRootTwo);
179template <
typename NumericType>
181 NumericType frequency,
184 jassert (sampleRate > 0);
185 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
189 const auto nSquared = n * n;
190 const auto invQ = 1 / Q;
191 const auto c1 = 1 / (1 + invQ * n + nSquared);
192 const auto b0 = c1 * (1 - n * invQ + nSquared);
193 const auto b1 = c1 * 2 * (1 - nSquared);
195 return { { b0, b1, 1, 1, b1, b0 } };
198template <
typename NumericType>
200 NumericType cutOffFrequency,
202 NumericType gainFactor)
204 jassert (sampleRate > 0.0);
205 jassert (cutOffFrequency > 0.0 && cutOffFrequency <= sampleRate * 0.5);
209 const auto aminus1 = A - 1;
210 const auto aplus1 = A + 1;
211 const auto omega = (2 *
MathConstants<NumericType>::pi * jmax (cutOffFrequency,
static_cast<NumericType
> (2.0))) /
static_cast<NumericType
> (sampleRate);
212 const auto coso = std::cos (omega);
213 const auto beta = std::sin (omega) * std::sqrt (A) / Q;
214 const auto aminus1TimesCoso = aminus1 * coso;
216 return { { A * (aplus1 - aminus1TimesCoso + beta),
217 A * 2 * (aminus1 - aplus1 * coso),
218 A * (aplus1 - aminus1TimesCoso - beta),
219 aplus1 + aminus1TimesCoso + beta,
220 -2 * (aminus1 + aplus1 * coso),
221 aplus1 + aminus1TimesCoso - beta } };
224template <
typename NumericType>
226 NumericType cutOffFrequency,
228 NumericType gainFactor)
230 jassert (sampleRate > 0);
231 jassert (cutOffFrequency > 0 && cutOffFrequency <=
static_cast<NumericType
> (sampleRate * 0.5));
235 const auto aminus1 = A - 1;
236 const auto aplus1 = A + 1;
237 const auto omega = (2 *
MathConstants<NumericType>::pi * jmax (cutOffFrequency,
static_cast<NumericType
> (2.0))) /
static_cast<NumericType
> (sampleRate);
238 const auto coso = std::cos (omega);
239 const auto beta = std::sin (omega) * std::sqrt (A) / Q;
240 const auto aminus1TimesCoso = aminus1 * coso;
242 return { { A * (aplus1 + aminus1TimesCoso + beta),
243 A * -2 * (aminus1 + aplus1 * coso),
244 A * (aplus1 + aminus1TimesCoso - beta),
245 aplus1 - aminus1TimesCoso + beta,
246 2 * (aminus1 - aplus1 * coso),
247 aplus1 - aminus1TimesCoso - beta } };
250template <
typename NumericType>
252 NumericType frequency,
254 NumericType gainFactor)
256 jassert (sampleRate > 0);
257 jassert (frequency > 0 && frequency <=
static_cast<NumericType
> (sampleRate * 0.5));
259 jassert (gainFactor > 0);
262 const auto omega = (2 *
MathConstants<NumericType>::pi * jmax (frequency,
static_cast<NumericType
> (2.0))) /
static_cast<NumericType
> (sampleRate);
263 const auto alpha = std::sin (omega) / (Q * 2);
264 const auto c2 = -2 * std::cos (omega);
265 const auto alphaTimesA = alpha * A;
266 const auto alphaOverA = alpha / A;
268 return { { 1 + alphaTimesA, c2, 1 - alphaTimesA, 1 + alphaOverA, c2, 1 - alphaOverA } };
275template <
typename NumericType>
278 assign ({ NumericType(), NumericType(), NumericType(),
279 NumericType(), NumericType(), NumericType() });
282template <
typename NumericType>
284 NumericType a0, NumericType a1)
290template <
typename NumericType>
292 NumericType a0, NumericType a1, NumericType a2)
294 assign ({ b0, b1, b2,
298template <
typename NumericType>
300 NumericType a0, NumericType a1, NumericType a2, NumericType a3)
302 assign ({ b0, b1, b2, b3,
306template <
typename NumericType>
308 NumericType frequency)
310 return *
new Coefficients (ArrayCoeffs::makeFirstOrderLowPass (sampleRate, frequency));
313template <
typename NumericType>
315 NumericType frequency)
317 return *
new Coefficients (ArrayCoeffs::makeFirstOrderHighPass (sampleRate, frequency));
320template <
typename NumericType>
322 NumericType frequency)
324 return *
new Coefficients (ArrayCoeffs::makeFirstOrderAllPass (sampleRate, frequency));
327template <
typename NumericType>
329 NumericType frequency)
331 return *
new Coefficients (ArrayCoeffs::makeLowPass (sampleRate, frequency));
334template <
typename NumericType>
336 NumericType frequency,
339 return *
new Coefficients (ArrayCoeffs::makeLowPass (sampleRate, frequency, Q));
342template <
typename NumericType>
344 NumericType frequency)
346 return *
new Coefficients (ArrayCoeffs::makeHighPass (sampleRate, frequency));
349template <
typename NumericType>
351 NumericType frequency,
354 return *
new Coefficients (ArrayCoeffs::makeHighPass (sampleRate, frequency, Q));
357template <
typename NumericType>
359 NumericType frequency)
361 return *
new Coefficients (ArrayCoeffs::makeBandPass (sampleRate, frequency));
364template <
typename NumericType>
366 NumericType frequency,
369 return *
new Coefficients (ArrayCoeffs::makeBandPass (sampleRate, frequency, Q));
372template <
typename NumericType>
374 NumericType frequency)
376 return *
new Coefficients (ArrayCoeffs::makeNotch (sampleRate, frequency));
379template <
typename NumericType>
381 NumericType frequency,
384 return *
new Coefficients (ArrayCoeffs::makeNotch (sampleRate, frequency, Q));
387template <
typename NumericType>
389 NumericType frequency)
391 return *
new Coefficients (ArrayCoeffs::makeAllPass (sampleRate, frequency));
394template <
typename NumericType>
396 NumericType frequency,
399 return *
new Coefficients (ArrayCoeffs::makeAllPass (sampleRate, frequency, Q));
402template <
typename NumericType>
404 NumericType cutOffFrequency,
406 NumericType gainFactor)
408 return *
new Coefficients (ArrayCoeffs::makeLowShelf (sampleRate, cutOffFrequency, Q, gainFactor));
411template <
typename NumericType>
413 NumericType cutOffFrequency,
415 NumericType gainFactor)
417 return *
new Coefficients (ArrayCoeffs::makeHighShelf (sampleRate, cutOffFrequency, Q, gainFactor));
420template <
typename NumericType>
422 NumericType frequency,
424 NumericType gainFactor)
426 return *
new Coefficients (ArrayCoeffs::makePeakFilter (sampleRate, frequency, Q, gainFactor));
429template <
typename NumericType>
432 return (
static_cast<size_t> (coefficients.size()) - 1) / 2;
435template <
typename NumericType>
438 constexpr Complex<double> j (0, 1);
439 const auto order = getFilterOrder();
440 const auto* coefs = coefficients.begin();
442 jassert (frequency >= 0 && frequency <= sampleRate * 0.5);
444 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
447 for (
size_t n = 0; n <= order; ++n)
449 numerator +=
static_cast<double> (coefs[n]) * factor;
456 for (
size_t n = order + 1; n <= 2 * order; ++n)
458 denominator +=
static_cast<double> (coefs[n]) * factor;
462 return std::abs (numerator / denominator);
465template <
typename NumericType>
467 size_t numSamples,
double sampleRate)
const noexcept
469 constexpr Complex<double> j (0, 1);
470 const auto order = getFilterOrder();
471 const auto* coefs = coefficients.begin();
473 jassert (order >= 0);
475 for (
size_t i = 0; i < numSamples; ++i)
477 jassert (frequencies[i] >= 0 && frequencies[i] <= sampleRate * 0.5);
479 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
482 for (
size_t n = 0; n <= order; ++n)
484 numerator +=
static_cast<double> (coefs[n]) * factor;
491 for (
size_t n = order + 1; n <= 2 * order; ++n)
493 denominator +=
static_cast<double> (coefs[n]) * factor;
497 magnitudes[i] = std::abs (numerator / denominator);
501template <
typename NumericType>
504 constexpr Complex<double> j (0, 1);
505 const auto order = getFilterOrder();
506 const auto* coefs = coefficients.begin();
508 jassert (frequency >= 0 && frequency <= sampleRate * 0.5);
510 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
513 for (
size_t n = 0; n <= order; ++n)
515 numerator +=
static_cast<double> (coefs[n]) * factor;
522 for (
size_t n = order + 1; n <= 2 * order; ++n)
524 denominator +=
static_cast<double> (coefs[n]) * factor;
528 return std::arg (numerator / denominator);
531template <
typename NumericType>
533 size_t numSamples,
double sampleRate)
const noexcept
535 jassert (sampleRate > 0);
537 constexpr Complex<double> j (0, 1);
538 const auto order = getFilterOrder();
539 const auto* coefs = coefficients.begin();
540 auto invSampleRate = 1 / sampleRate;
542 jassert (order >= 0);
544 for (
size_t i = 0; i < numSamples; ++i)
546 jassert (frequencies[i] >= 0 && frequencies[i] <= sampleRate * 0.5);
548 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
551 for (
size_t n = 0; n <= order; ++n)
553 numerator +=
static_cast<double> (coefs[n]) * factor;
560 for (
size_t n = order + 1; n <= 2 * order; ++n)
562 denominator +=
static_cast<double> (coefs[n]) * factor;
566 phases[i] = std::arg (numerator / denominator);
static Type gainWithLowerBound(Type gain, Type lowerBoundDb)
static std::array< NumericType, 6 > makeHighPass(double sampleRate, NumericType frequency)
static std::array< NumericType, 6 > makePeakFilter(double sampleRate, NumericType centreFrequency, NumericType Q, NumericType gainFactor)
static std::array< NumericType, 6 > makeBandPass(double sampleRate, NumericType frequency)
static std::array< NumericType, 4 > makeFirstOrderHighPass(double sampleRate, NumericType frequency)
static std::array< NumericType, 6 > makeLowPass(double sampleRate, NumericType frequency)
static std::array< NumericType, 6 > makeLowShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
static std::array< NumericType, 4 > makeFirstOrderLowPass(double sampleRate, NumericType frequency)
static std::array< NumericType, 4 > makeFirstOrderAllPass(double sampleRate, NumericType frequency)
static std::array< NumericType, 6 > makeAllPass(double sampleRate, NumericType frequency)
static std::array< NumericType, 6 > makeHighShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
static std::array< NumericType, 6 > makeNotch(double sampleRate, NumericType frequency)
static Ptr makeLowShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
static Ptr makeFirstOrderHighPass(double sampleRate, NumericType frequency)
static Ptr makeHighPass(double sampleRate, NumericType frequency)
static Ptr makeHighShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
void getMagnitudeForFrequencyArray(const double *frequencies, double *magnitudes, size_t numSamples, double sampleRate) const noexcept
static Ptr makeLowPass(double sampleRate, NumericType frequency)
double getMagnitudeForFrequency(double frequency, double sampleRate) const noexcept
static Ptr makePeakFilter(double sampleRate, NumericType centreFrequency, NumericType Q, NumericType gainFactor)
void getPhaseForFrequencyArray(double *frequencies, double *phases, size_t numSamples, double sampleRate) const noexcept
static Ptr makeAllPass(double sampleRate, NumericType frequency)
static Ptr makeBandPass(double sampleRate, NumericType frequency)
double getPhaseForFrequency(double frequency, double sampleRate) const noexcept
static Ptr makeNotch(double sampleRate, NumericType frequency)
size_t getFilterOrder() const noexcept
static Ptr makeFirstOrderLowPass(double sampleRate, NumericType frequency)
static Ptr makeFirstOrderAllPass(double sampleRate, NumericType frequency)