LMMS
Loading...
Searching...
No Matches
juce_FilterDesign.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28namespace dsp
29{
30
31template <typename FloatType>
32typename FIR::Coefficients<FloatType>::Ptr
34 double sampleRate, size_t order,
36 FloatType beta)
37{
38 jassert (sampleRate > 0);
39 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
40
41 auto* result = new typename FIR::Coefficients<FloatType> (order + 1u);
42
43 auto* c = result->getRawCoefficients();
44 auto normalisedFrequency = frequency / sampleRate;
45
46 for (size_t i = 0; i <= order; ++i)
47 {
48 if (i == order / 2)
49 {
50 c[i] = static_cast<FloatType> (normalisedFrequency * 2);
51 }
52 else
53 {
54 auto indice = MathConstants<double>::pi * (static_cast<double> (i) - 0.5 * static_cast<double> (order));
55 c[i] = static_cast<FloatType> (std::sin (2.0 * indice * normalisedFrequency) / indice);
56 }
57 }
58
59 WindowingFunction<FloatType> theWindow (order + 1, type, false, beta);
60 theWindow.multiplyWithWindowingTable (c, order + 1);
61
62 return *result;
63}
64
65template <typename FloatType>
67 FilterDesign<FloatType>::designFIRLowpassKaiserMethod (FloatType frequency, double sampleRate,
68 FloatType normalisedTransitionWidth,
69 FloatType amplitudedB)
70{
71 jassert (sampleRate > 0);
72 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
73 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
74 jassert (amplitudedB >= -100 && amplitudedB <= 0);
75
76 FloatType beta = 0;
77
78 if (amplitudedB < -50)
79 beta = static_cast<FloatType> (0.1102 * (-amplitudedB - 8.7));
80 else if (amplitudedB <= -21)
81 beta = static_cast<FloatType> (0.5842 * std::pow (-amplitudedB - 21, 0.4) + 0.07886 * (-amplitudedB - 21));
82
83 int order = amplitudedB < -21 ? roundToInt (std::ceil ((-amplitudedB - 7.95) / (2.285 * normalisedTransitionWidth * MathConstants<double>::twoPi)))
84 : roundToInt (std::ceil (5.79 / (normalisedTransitionWidth * MathConstants<double>::twoPi)));
85
86 jassert (order >= 0);
87
88 return designFIRLowpassWindowMethod (frequency, sampleRate, static_cast<size_t> (order),
90}
91
92
93template <typename FloatType>
95 FilterDesign<FloatType>::designFIRLowpassTransitionMethod (FloatType frequency, double sampleRate, size_t order,
96 FloatType normalisedTransitionWidth, FloatType spline)
97{
98 jassert (sampleRate > 0);
99 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
100 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
101 jassert (spline >= 1.0 && spline <= 4.0);
102
103 auto normalisedFrequency = frequency / static_cast<FloatType> (sampleRate);
104
105 auto* result = new typename FIR::Coefficients<FloatType> (order + 1u);
106 auto* c = result->getRawCoefficients();
107
108 for (size_t i = 0; i <= order; ++i)
109 {
110 if (i == order / 2 && order % 2 == 0)
111 {
112 c[i] = static_cast<FloatType> (2 * normalisedFrequency);
113 }
114 else
115 {
116 auto indice = MathConstants<double>::pi * ((double) i - 0.5 * (double) order);
117 auto indice2 = MathConstants<double>::pi * normalisedTransitionWidth * ((double) i - 0.5 * (double) order) / spline;
118 c[i] = static_cast<FloatType> (std::sin (2 * indice * normalisedFrequency)
119 / indice * std::pow (std::sin (indice2) / indice2, spline));
120 }
121 }
122
123 return *result;
124}
125
126template <typename FloatType>
129 double sampleRate, size_t order,
130 FloatType normalisedTransitionWidth,
131 FloatType stopBandWeight)
132{
133 jassert (sampleRate > 0);
134 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
135 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
136 jassert (stopBandWeight >= 1.0 && stopBandWeight <= 100.0);
137
138 auto normalisedFrequency = static_cast<double> (frequency) / sampleRate;
139
140 auto wp = MathConstants<double>::twoPi * (static_cast<double> (normalisedFrequency - normalisedTransitionWidth / 2.0));
141 auto ws = MathConstants<double>::twoPi * (static_cast<double> (normalisedFrequency + normalisedTransitionWidth / 2.0));
142
143 auto N = order + 1;
144
145 auto* result = new typename FIR::Coefficients<FloatType> (static_cast<size_t> (N));
146 auto* c = result->getRawCoefficients();
147
148 if (N % 2 == 1)
149 {
150 // Type I
151 auto M = (N - 1) / 2;
152
153 Matrix<double> b (M + 1, 1),
154 q (2 * M + 1, 1);
155
156 auto sinc = [] (double x) { return x == 0 ? 1 : std::sin (x * MathConstants<double>::pi)
158
159 auto factorp = wp / MathConstants<double>::pi;
160 auto factors = ws / MathConstants<double>::pi;
161
162 for (size_t i = 0; i <= M; ++i)
163 b (i, 0) = factorp * sinc (factorp * (double) i);
164
165 q (0, 0) = factorp + stopBandWeight * (1.0 - factors);
166
167 for (size_t i = 1; i <= 2 * M; ++i)
168 q (i, 0) = factorp * sinc (factorp * (double) i) - stopBandWeight * factors * sinc (factors * (double) i);
169
170 auto Q1 = Matrix<double>::toeplitz (q, M + 1);
171 auto Q2 = Matrix<double>::hankel (q, M + 1, 0);
172
173 Q1 += Q2; Q1 *= 0.5;
174
175 Q1.solve (b);
176
177 c[M] = static_cast<FloatType> (b (0, 0));
178
179 for (size_t i = 1; i <= M; ++i)
180 {
181 c[M - i] = static_cast<FloatType> (b (i, 0) * 0.5);
182 c[M + i] = static_cast<FloatType> (b (i, 0) * 0.5);
183 }
184 }
185 else
186 {
187 // Type II
188 auto M = N / 2;
189
190 Matrix<double> b (M, 1);
191 Matrix<double> qp (2 * M, 1);
192 Matrix<double> qs (2 * M, 1);
193
194 auto sinc = [] (double x) { return x == 0 ? 1 : std::sin (x * MathConstants<double>::pi)
196
197 auto factorp = wp / MathConstants<double>::pi;
198 auto factors = ws / MathConstants<double>::pi;
199
200 for (size_t i = 0; i < M; ++i)
201 b (i, 0) = factorp * sinc (factorp * ((double) i + 0.5));
202
203 for (size_t i = 0; i < 2 * M; ++i)
204 {
205 qp (i, 0) = 0.25 * factorp * sinc (factorp * (double) i);
206 qs (i, 0) = -0.25 * stopBandWeight * factors * sinc (factors * (double) i);
207 }
208
209 auto Q1p = Matrix<double>::toeplitz (qp, M);
210 auto Q2p = Matrix<double>::hankel (qp, M, 1);
211 auto Q1s = Matrix<double>::toeplitz (qs, M);
212 auto Q2s = Matrix<double>::hankel (qs, M, 1);
213
214 auto Id = Matrix<double>::identity (M);
215 Id *= (0.25 * stopBandWeight);
216
217 Q1p += Q2p;
218 Q1s += Q2s;
219 Q1s += Id;
220
221 auto& Q = Q1s;
222 Q += Q1p;
223
224 Q.solve (b);
225
226 for (size_t i = 0; i < M; ++i)
227 {
228 c[M - i - 1] = static_cast<FloatType> (b (i, 0) * 0.25);
229 c[M + i] = static_cast<FloatType> (b (i, 0) * 0.25);
230 }
231 }
232
233 return *result;
234}
235
236template <typename FloatType>
239 FloatType amplitudedB)
240{
241 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
242 jassert (amplitudedB >= -300 && amplitudedB <= -10);
243
244 auto wpT = (0.5 - normalisedTransitionWidth) * MathConstants<double>::pi;
245
246 auto n = roundToInt (std::ceil ((amplitudedB - 18.18840664 * wpT + 33.64775300) / (18.54155181 * wpT - 29.13196871)));
247 auto kp = (n * wpT - 1.57111377 * n + 0.00665857) / (-1.01927560 * n + 0.37221484);
248 auto A = (0.01525753 * n + 0.03682344 + 9.24760314 / (double) n) * kp + 1.01701407 + 0.73512298 / (double) n;
249 auto B = (0.00233667 * n - 1.35418408 + 5.75145813 / (double) n) * kp + 1.02999650 - 0.72759508 / (double) n;
250
253
254 auto diff = (hn.size() - hnm.size()) / 2;
255
256 for (int i = 0; i < diff; ++i)
257 {
258 hnm.add (0.0);
259 hnm.insert (0, 0.0);
260 }
261
262 auto hh = hn;
263
264 for (int i = 0; i < hn.size(); ++i)
265 hh.setUnchecked (i, A * hh[i] + B * hnm[i]);
266
267 auto* result = new typename FIR::Coefficients<FloatType> (static_cast<size_t> (hh.size()));
268 auto* c = result->getRawCoefficients();
269
270 for (int i = 0; i < hh.size(); ++i)
271 c[i] = (float) hh[i];
272
273 auto NN = [&]
274 {
275 if (n % 2 == 0)
276 return 2.0 * result->getMagnitudeForFrequency (0.5, 1.0);
277
278 auto w01 = std::sqrt (kp * kp + (1 - kp * kp) * std::pow (std::cos (MathConstants<double>::pi / (2.0 * n + 1.0)), 2.0));
279
280 if (std::abs (w01) > 1.0)
281 return 2.0 * result->getMagnitudeForFrequency (0.5, 1.0);
282
283 auto om01 = std::acos (-w01);
284 return -2.0 * result->getMagnitudeForFrequency (om01 / MathConstants<double>::twoPi, 1.0);
285 }();
286
287 for (int i = 0; i < hh.size(); ++i)
288 c[i] = static_cast<FloatType> ((A * hn[i] + B * hnm[i]) / NN);
289
290 c[2 * n + 1] = static_cast<FloatType> (0.5);
291
292 return *result;
293}
294
295template <typename FloatType>
297{
298 Array<double> alpha;
299 alpha.resize (2 * n + 1);
300
301 alpha.setUnchecked (2 * n, 1.0 / std::pow (1.0 - kp * kp, n));
302
303 if (n > 0)
304 alpha.setUnchecked (2 * n - 2, -(2 * n * kp * kp + 1) * alpha[2 * n]);
305
306 if (n > 1)
307 alpha.setUnchecked (2 * n - 4, -(4 * n + 1 + (n - 1) * (2 * n - 1) * kp * kp) / (2.0 * n) * alpha[2 * n - 2]
308 - (2 * n + 1) * ((n + 1) * kp * kp + 1) / (2.0 * n) * alpha[2 * n]);
309
310 for (int k = n; k >= 3; --k)
311 {
312 auto c1 = (3 * (n*(n + 2) - k * (k - 2)) + 2 * k - 3 + 2 * (k - 2)*(2 * k - 3) * kp * kp) * alpha[2 * k - 4];
313 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];
314 auto c3 = (n * (n + 2) - (k - 1) * (k + 1)) * alpha[2 * k];
315 auto c4 = (n * (n + 2) - (k - 3) * (k - 1));
316
317 alpha.setUnchecked (2 * k - 6, -(c1 + c2 + c3) / c4);
318 }
319
320 Array<double> ai;
321 ai.resize (2 * n + 1 + 1);
322
323 for (int k = 0; k <= n; ++k)
324 ai.setUnchecked (2 * k + 1, alpha[2 * k] / (2.0 * k + 1.0));
325
326 Array<double> hn;
327 hn.resize (2 * n + 1 + 2 * n + 1 + 1);
328
329 for (int k = 0; k <= n; ++k)
330 {
331 hn.setUnchecked (2 * n + 1 + (2 * k + 1), 0.5 * ai[2 * k + 1]);
332 hn.setUnchecked (2 * n + 1 - (2 * k + 1), 0.5 * ai[2 * k + 1]);
333 }
334
335 return hn;
336}
337
338template <typename FloatType>
341 FloatType normalisedTransitionWidth,
342 FloatType passbandAmplitudedB,
343 FloatType stopbandAmplitudedB)
344{
345 return designIIRLowpassHighOrderGeneralMethod (0, frequency, sampleRate, normalisedTransitionWidth,
346 passbandAmplitudedB, stopbandAmplitudedB);
347}
348
349template <typename FloatType>
352 FloatType normalisedTransitionWidth,
353 FloatType passbandAmplitudedB,
354 FloatType stopbandAmplitudedB)
355{
356 return designIIRLowpassHighOrderGeneralMethod (1, frequency, sampleRate, normalisedTransitionWidth,
357 passbandAmplitudedB, stopbandAmplitudedB);
358}
359
360template <typename FloatType>
363 FloatType normalisedTransitionWidth,
364 FloatType passbandAmplitudedB,
365 FloatType stopbandAmplitudedB)
366{
367 return designIIRLowpassHighOrderGeneralMethod (2, frequency, sampleRate, normalisedTransitionWidth,
368 passbandAmplitudedB, stopbandAmplitudedB);
369}
370
371template <typename FloatType>
374 FloatType normalisedTransitionWidth,
375 FloatType passbandAmplitudedB,
376 FloatType stopbandAmplitudedB)
377{
378 return designIIRLowpassHighOrderGeneralMethod (3, frequency, sampleRate, normalisedTransitionWidth,
379 passbandAmplitudedB, stopbandAmplitudedB);
380}
381
382template <typename FloatType>
384 FilterDesign<FloatType>::designIIRLowpassHighOrderGeneralMethod (int type, FloatType frequency, double sampleRate,
385 FloatType normalisedTransitionWidth,
386 FloatType passbandAmplitudedB,
387 FloatType stopbandAmplitudedB)
388{
389 jassert (0 < sampleRate);
390 jassert (0 < frequency && frequency <= sampleRate * 0.5);
391 jassert (0 < normalisedTransitionWidth && normalisedTransitionWidth <= 0.5);
392 jassert (-20 < passbandAmplitudedB && passbandAmplitudedB < 0);
393 jassert (-300 < stopbandAmplitudedB && stopbandAmplitudedB < -20);
394
395 auto normalisedFrequency = frequency / sampleRate;
396
397 auto fp = normalisedFrequency - normalisedTransitionWidth / 2;
398 jassert (0.0 < fp && fp < 0.5);
399
400 auto fs = normalisedFrequency + normalisedTransitionWidth / 2;
401 jassert (0.0 < fs && fs < 0.5);
402
403 double Ap = passbandAmplitudedB;
404 double As = stopbandAmplitudedB;
405 auto Gp = Decibels::decibelsToGain (Ap, -300.0);
406 auto Gs = Decibels::decibelsToGain (As, -300.0);
407 auto epsp = std::sqrt (1.0 / (Gp * Gp) - 1.0);
408 auto epss = std::sqrt (1.0 / (Gs * Gs) - 1.0);
409
410 auto omegap = std::tan (MathConstants<double>::pi * fp);
411 auto omegas = std::tan (MathConstants<double>::pi * fs);
412 constexpr auto halfPi = MathConstants<double>::halfPi;
413
414 auto k = omegap / omegas;
415 auto k1 = epsp / epss;
416
417 int N;
418
419 if (type == 0)
420 {
421 N = roundToInt (std::ceil (std::log (1.0 / k1) / std::log (1.0 / k)));
422 }
423 else if (type == 1 || type == 2)
424 {
425 N = roundToInt (std::ceil (std::acosh (1.0 / k1) / std::acosh (1.0 / k)));
426 }
427 else
428 {
429 double K, Kp, K1, K1p;
430
433
434 N = roundToInt (std::ceil ((K1p * K) / (K1 * Kp)));
435 }
436
437 const int r = N % 2;
438 const int L = (N - r) / 2;
439 const double H0 = (type == 1 || type == 3) ? std::pow (Gp, 1.0 - r) : 1.0;
440
441 Array<Complex<double>> pa, za;
442 Complex<double> j (0, 1);
443
444 if (type == 0)
445 {
446 if (r == 1)
447 pa.add (-omegap * std::pow (epsp, -1.0 / (double) N));
448
449 for (int i = 1; i <= L; ++i)
450 {
451 auto ui = (2 * i - 1.0) / (double) N;
452 pa.add (omegap * std::pow (epsp, -1.0 / (double) N) * j * exp (ui * halfPi * j));
453 }
454 }
455 else if (type == 1)
456 {
457 auto v0 = std::asinh (1.0 / epsp) / (N * halfPi);
458
459 if (r == 1)
460 pa.add (-omegap * std::sinh (v0 * halfPi));
461
462 for (int i = 1; i <= L; ++i)
463 {
464 auto ui = (2 * i - 1.0) / (double) N;
465 pa.add (omegap * j * std::cos ((ui - j * v0) * halfPi));
466 }
467 }
468 else if (type == 2)
469 {
470 auto v0 = std::asinh (epss) / (N * halfPi);
471
472 if (r == 1)
473 pa.add(-1.0 / (k / omegap * std::sinh (v0 * halfPi)));
474
475 for (int i = 1; i <= L; ++i)
476 {
477 auto ui = (2 * i - 1.0) / (double) N;
478
479 pa.add (1.0 / (k / omegap * j * std::cos ((ui - j * v0) * halfPi)));
480 za.add (1.0 / (k / omegap * j * std::cos (ui * halfPi)));
481 }
482 }
483 else
484 {
485 auto v0 = -j * (SpecialFunctions::asne (j / epsp, k1) / (double) N);
486
487 if (r == 1)
488 pa.add (omegap * j * SpecialFunctions::sne (j * v0, k));
489
490 for (int i = 1; i <= L; ++i)
491 {
492 auto ui = (2 * i - 1.0) / (double) N;
493 auto zetai = SpecialFunctions::cde (ui, k);
494
495 pa.add (omegap * j * SpecialFunctions::cde (ui - j * v0, k));
496 za.add (omegap * j / (k * zetai));
497 }
498 }
499
501
502 if (r == 1)
503 {
504 p.add ((1.0 + pa[0]) / (1.0 - pa[0]));
505 g.add (0.5 * (1.0 - p[0]));
506 }
507
508 for (int i = 0; i < L; ++i)
509 {
510 p.add ((1.0 + pa[i + r]) / (1.0 - pa[i + r]));
511 z.add (za.size() == 0 ? -1.0 : (1.0 + za[i]) / (1.0 - za[i]));
512 g.add ((1.0 - p[i + r]) / (1.0 - z[i]));
513 }
514
516
517 if (r == 1)
518 {
519 auto b0 = static_cast<FloatType> (H0 * std::real (g[0]));
520 auto b1 = b0;
521 auto a1 = static_cast<FloatType> (-std::real (p[0]));
522
523 cascadedCoefficients.add (new IIR::Coefficients<FloatType> (b0, b1, 1.0f, a1));
524 }
525
526 for (int i = 0; i < L; ++i)
527 {
528 auto gain = std::pow (std::abs (g[i + r]), 2.0);
529
530 auto b0 = static_cast<FloatType> (gain);
531 auto b1 = static_cast<FloatType> (std::real (-z[i] - std::conj (z[i])) * gain);
532 auto b2 = static_cast<FloatType> (std::real ( z[i] * std::conj (z[i])) * gain);
533
534 auto a1 = static_cast<FloatType> (std::real (-p[i+r] - std::conj (p[i + r])));
535 auto a2 = static_cast<FloatType> (std::real ( p[i+r] * std::conj (p[i + r])));
536
537 cascadedCoefficients.add (new IIR::Coefficients<FloatType> (b0, b1, b2, 1, a1, a2));
538 }
539
540 return cascadedCoefficients;
541}
542
543template <typename FloatType>
546 double sampleRate, int order)
547{
548 jassert (sampleRate > 0);
549 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
550 jassert (order > 0);
551
553
554 if (order % 2 == 1)
555 {
556 arrayFilters.add (*IIR::Coefficients<FloatType>::makeFirstOrderLowPass (sampleRate, frequency));
557
558 for (int i = 0; i < order / 2; ++i)
559 {
560 auto Q = 1.0 / (2.0 * std::cos ((i + 1.0) * MathConstants<double>::pi / order));
561 arrayFilters.add (*IIR::Coefficients<FloatType>::makeLowPass (sampleRate, frequency,
562 static_cast<FloatType> (Q)));
563 }
564 }
565 else
566 {
567 for (int i = 0; i < order / 2; ++i)
568 {
569 auto Q = 1.0 / (2.0 * std::cos ((2.0 * i + 1.0) * MathConstants<double>::pi / (order * 2.0)));
570 arrayFilters.add (*IIR::Coefficients<FloatType>::makeLowPass (sampleRate, frequency,
571 static_cast<FloatType> (Q)));
572 }
573 }
574
575 return arrayFilters;
576}
577
578template <typename FloatType>
581 double sampleRate, int order)
582{
583 jassert (sampleRate > 0);
584 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
585 jassert (order > 0);
586
588
589 if (order % 2 == 1)
590 {
591 arrayFilters.add (*IIR::Coefficients<FloatType>::makeFirstOrderHighPass (sampleRate, frequency));
592
593 for (int i = 0; i < order / 2; ++i)
594 {
595 auto Q = 1.0 / (2.0 * std::cos ((i + 1.0) * MathConstants<double>::pi / order));
596 arrayFilters.add (*IIR::Coefficients<FloatType>::makeHighPass (sampleRate, frequency,
597 static_cast<FloatType> (Q)));
598 }
599 }
600 else
601 {
602 for (int i = 0; i < order / 2; ++i)
603 {
604 auto Q = 1.0 / (2.0 * std::cos ((2.0 * i + 1.0) * MathConstants<double>::pi / (order * 2.0)));
605 arrayFilters.add (*IIR::Coefficients<FloatType>::makeHighPass (sampleRate, frequency,
606 static_cast<FloatType> (Q)));
607 }
608 }
609
610 return arrayFilters;
611}
612
613template <typename FloatType>
616 FloatType stopbandAmplitudedB)
617{
618 jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5);
619 jassert (stopbandAmplitudedB > -300 && stopbandAmplitudedB < -10);
620
621 const double wt = MathConstants<double>::twoPi * normalisedTransitionWidth;
622 const double ds = Decibels::decibelsToGain (stopbandAmplitudedB, static_cast<FloatType> (-300.0));
623
624 auto k = std::pow (std::tan ((MathConstants<double>::pi - wt) / 4), 2.0);
625 auto kp = std::sqrt (1.0 - k * k);
626 auto e = (1 - std::sqrt (kp)) / (1 + std::sqrt (kp)) * 0.5;
627 auto q = e + 2 * std::pow (e, 5.0) + 15 * std::pow (e, 9.0) + 150 * std::pow (e, 13.0);
628
629 auto k1 = ds * ds / (1 - ds * ds);
630 int n = roundToInt (std::ceil (std::log (k1 * k1 / 16) / std::log (q)));
631
632 if (n % 2 == 0)
633 ++n;
634
635 if (n == 1)
636 n = 3;
637
638 auto q1 = std::pow (q, (double) n);
639 k1 = 4 * std::sqrt (q1);
640
641 const int N = (n - 1) / 2;
642 Array<double> ai;
643
644 for (int i = 1; i <= N; ++i)
645 {
646 double num = 0.0;
647 double delta = 1.0;
648 int m = 0;
649
650 while (std::abs (delta) > 1e-100)
651 {
652 delta = std::pow (-1, m) * std::pow (q, m * (m + 1))
653 * std::sin ((2 * m + 1) * MathConstants<double>::pi * i / (double) n);
654 num += delta;
655 m++;
656 }
657
658 num *= 2 * std::pow (q, 0.25);
659
660 double den = 0.0;
661 delta = 1.0;
662 m = 1;
663
664 while (std::abs (delta) > 1e-100)
665 {
666 delta = std::pow (-1, m) * std::pow (q, m * m)
667 * std::cos (m * MathConstants<double>::twoPi * i / (double) n);
668 den += delta;
669 ++m;
670 }
671
672 den = 1 + 2 * den;
673
674 auto wi = num / den;
675 auto api = std::sqrt ((1 - wi * wi * k) * (1 - wi * wi / k)) / (1 + wi * wi);
676
677 ai.add ((1 - api) / (1 + api));
678 }
679
681
682 for (int i = 0; i < N; i += 2)
683 structure.directPath.add (new IIR::Coefficients<FloatType> (static_cast<FloatType> (ai[i]),
684 0, 1, 1, 0, static_cast<FloatType> (ai[i])));
685
686 structure.delayedPath.add (new IIR::Coefficients<FloatType> (0, 1, 1, 0));
687
688 for (int i = 1; i < N; i += 2)
689 structure.delayedPath.add (new IIR::Coefficients<FloatType> (static_cast<FloatType> (ai[i]),
690 0, 1, 1, 0, static_cast<FloatType> (ai[i])));
691
692 structure.alpha.addArray (ai);
693
694 return structure;
695}
696
697
698template struct FilterDesign<float>;
699template struct FilterDesign<double>;
700
701} // namespace dsp
702} // namespace juce
class MasterUI * ui
Definition Connection.cpp:39
#define sinc(x)
Definition analyzer.cpp:35
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
Definition juce_Array.h:56
void setUnchecked(int indexToChange, ParameterType newValue)
Definition juce_Array.h:568
void addArray(const Type *elementsToAdd, int numElementsToAdd)
Definition juce_Array.h:583
int size() const noexcept
Definition juce_Array.h:215
void add(const ElementType &newElement)
Definition juce_Array.h:418
void resize(int targetNumItems)
Definition juce_Array.h:670
static Type decibelsToGain(Type decibels, Type minusInfinityDb=Type(defaultMinusInfinitydB))
Definition juce_Decibels.h:42
Definition juce_ReferenceCountedArray.h:51
ObjectClass * add(ObjectClass *newObject)
Definition juce_ReferenceCountedArray.h:354
Definition juce_Matrix.h:41
static Matrix hankel(const Matrix &vector, size_t size, size_t offset=0)
Definition juce_Matrix.cpp:61
static Matrix identity(size_t size)
Definition juce_Matrix.cpp:32
static Matrix toeplitz(const Matrix &vector, size_t size)
Definition juce_Matrix.cpp:43
Definition juce_Windowing.h:43
@ kaiser
Definition juce_Windowing.h:56
void multiplyWithWindowingTable(FloatType *samples, size_t size) noexcept
Definition juce_Windowing.cpp:169
* e
Definition inflate.c:1404
unsigned z
Definition inflate.c:1589
unsigned * m
Definition inflate.c:1559
register unsigned k
Definition inflate.c:946
register unsigned j
Definition inflate.c:1576
int g
Definition inflate.c:1573
register unsigned i
Definition inflate.c:1575
unsigned x[BMAX+1]
Definition inflate.c:1586
static void c2(register WDL_FFT_COMPLEX *a)
Definition fft.c:270
static void c4(register WDL_FFT_COMPLEX *a)
Definition fft.c:283
#define jassert(expression)
#define A(x)
Definition lice_arc.cpp:13
Definition juce_AudioBlock.h:29
std::complex< Type > Complex
Definition juce_dsp.h:194
Definition carla_juce.cpp:31
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465
#define N
Definition nseel-cfunc.c:36
#define M
Definition nseel-cfunc.c:37
static bool diff(const std::string fn1, const std::string fn2)
Definition playertest.cpp:161
static constexpr FloatType halfPi
Definition juce_MathsFunctions.h:388
static constexpr FloatType twoPi
Definition juce_MathsFunctions.h:385
static constexpr FloatType pi
Definition juce_MathsFunctions.h:382
Definition juce_FIRFilter.h:219
ReferenceCountedObjectPtr< Coefficients > Ptr
Definition juce_FIRFilter.h:238
Array< double > alpha
Definition juce_FilterDesign.h:261
ReferenceCountedArray< IIRCoefficients > directPath
Definition juce_FilterDesign.h:260
ReferenceCountedArray< IIRCoefficients > delayedPath
Definition juce_FilterDesign.h:260
Definition juce_FilterDesign.h:42
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderButterworthMethod(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
Definition juce_FilterDesign.cpp:340
static FIRCoefficientsPtr designFIRLowpassLeastSquaresMethod(FloatType frequency, double sampleRate, size_t order, FloatType normalisedTransitionWidth, FloatType stopBandWeight)
Definition juce_FilterDesign.cpp:128
static FIRCoefficientsPtr designFIRLowpassKaiserMethod(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType amplitudedB)
Definition juce_FilterDesign.cpp:67
typename WindowingFunction< FloatType >::WindowingMethod WindowingMethod
Definition juce_FilterDesign.h:46
static Array< double > getPartialImpulseResponseHn(int n, double kp)
Definition juce_FilterDesign.cpp:296
static IIRPolyphaseAllpassStructure designIIRLowpassHalfBandPolyphaseAllpassMethod(FloatType normalisedTransitionWidth, FloatType stopbandAmplitudedB)
Definition juce_FilterDesign.cpp:615
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderChebyshev1Method(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
Definition juce_FilterDesign.cpp:351
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderGeneralMethod(int type, FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
Definition juce_FilterDesign.cpp:384
static ReferenceCountedArray< IIRCoefficients > designIIRHighpassHighOrderButterworthMethod(FloatType frequency, double sampleRate, int order)
Definition juce_FilterDesign.cpp:580
static FIRCoefficientsPtr designFIRLowpassTransitionMethod(FloatType frequency, double sampleRate, size_t order, FloatType normalisedTransitionWidth, FloatType spline)
Definition juce_FilterDesign.cpp:95
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderChebyshev2Method(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
Definition juce_FilterDesign.cpp:362
static ReferenceCountedArray< IIRCoefficients > designIIRLowpassHighOrderEllipticMethod(FloatType frequency, double sampleRate, FloatType normalisedTransitionWidth, FloatType passbandAmplitudedB, FloatType stopbandAmplitudedB)
Definition juce_FilterDesign.cpp:373
static FIRCoefficientsPtr designFIRLowpassHalfBandEquirippleMethod(FloatType normalisedTransitionWidth, FloatType amplitudedB)
Definition juce_FilterDesign.cpp:238
static FIRCoefficientsPtr designFIRLowpassWindowMethod(FloatType frequency, double sampleRate, size_t order, WindowingMethod type, FloatType beta=static_cast< FloatType >(2))
Definition juce_FilterDesign.cpp:33
Definition juce_IIRFilter.h:129
static Ptr makeFirstOrderHighPass(double sampleRate, NumericType frequency)
Definition juce_IIRFilter.cpp:316
static Ptr makeHighPass(double sampleRate, NumericType frequency)
Definition juce_IIRFilter.cpp:345
static Ptr makeLowPass(double sampleRate, NumericType frequency)
Definition juce_IIRFilter.cpp:330
static Ptr makeFirstOrderLowPass(double sampleRate, NumericType frequency)
Definition juce_IIRFilter.cpp:309
static Complex< double > sne(Complex< double > u, double k) noexcept
Definition juce_SpecialFunctions.cpp:97
static Complex< double > cde(Complex< double > u, double k) noexcept
Definition juce_SpecialFunctions.cpp:74
static Complex< double > asne(Complex< double > w, double k) noexcept
Definition juce_SpecialFunctions.cpp:120
static void ellipticIntegralK(double k, double &K, double &Kp) noexcept
Definition juce_SpecialFunctions.cpp:51
int n
Definition crypt.c:458
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
int r
Definition crypt.c:458
b
Definition crypt.c:628
uch hh[RAND_HEAD_LEN]
Definition crypt.c:595
register uch * q
Definition fileio.c:817
int result
Definition process.c:1455