OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
juce_dsp/processors/juce_IIRFilter.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
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 5 End-User License
11 Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
12 27th April 2017).
13
14 End User License Agreement: www.juce.com/juce-5-licence
15 Privacy Policy: www.juce.com/juce-5-privacy-policy
16
17 Or: You may also use this code under the terms of the GPL v3 (see
18 www.gnu.org/licenses).
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29namespace dsp
30{
31
32template <typename NumericType>
34 : coefficients ({ NumericType(),
35 NumericType(),
36 NumericType(),
37 NumericType(),
38 NumericType() })
39{
40}
41
42template <typename NumericType>
44 NumericType a0, NumericType a1)
45{
46 jassert (a0 != 0);
47
48 coefficients.clear();
49
50 auto a0inv = static_cast<NumericType> (1) / a0;
51
52 coefficients.add (b0 * a0inv,
53 b1 * a0inv,
54 a1 * a0inv);
55}
56
57template <typename NumericType>
58IIR::Coefficients<NumericType>::Coefficients (NumericType b0, NumericType b1, NumericType b2,
59 NumericType a0, NumericType a1, NumericType a2)
60{
61 jassert (a0 != 0);
62
63 coefficients.clear();
64
65 auto a0inv = static_cast<NumericType> (1) / a0;
66
67 coefficients.add (b0 * a0inv,
68 b1 * a0inv,
69 b2 * a0inv,
70 a1 * a0inv,
71 a2 * a0inv);
72}
73
74template <typename NumericType>
75IIR::Coefficients<NumericType>::Coefficients (NumericType b0, NumericType b1, NumericType b2, NumericType b3,
76 NumericType a0, NumericType a1, NumericType a2, NumericType a3)
77{
78 jassert (a0 != 0);
79
80 coefficients.clear();
81
82 auto a0inv = static_cast<NumericType> (1) / a0;
83
84 coefficients.add (b0 * a0inv,
85 b1 * a0inv,
86 b2 * a0inv,
87 b3 * a0inv,
88 a1 * a0inv,
89 a2 * a0inv,
90 a3 * a0inv);
91}
92
93template <typename NumericType>
95 NumericType frequency)
96{
97 jassert (sampleRate > 0.0);
98 jassert (frequency > 0 && frequency <= static_cast<float> (sampleRate * 0.5));
99
100 auto n = std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
101
102 return *new Coefficients (n, n, n + 1, n - 1);
103}
104
105template <typename NumericType>
107 NumericType frequency)
108{
109 jassert (sampleRate > 0.0);
110 jassert (frequency > 0 && frequency <= static_cast<float> (sampleRate * 0.5));
111
112 auto n = std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
113
114 return *new Coefficients (1, -1, n + 1, n - 1);
115}
116
117template <typename NumericType>
119 NumericType frequency)
120{
121 jassert (sampleRate > 0.0);
122 jassert (frequency > 0 && frequency <= static_cast<float> (sampleRate * 0.5));
123
124 auto n = std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
125
126 return *new Coefficients (n - 1, n + 1, n + 1, n - 1);
127}
128
129template <typename NumericType>
131 NumericType frequency)
132{
133 return makeLowPass (sampleRate, frequency, inverseRootTwo);
134}
135
136template <typename NumericType>
138 NumericType frequency,
139 NumericType Q)
140{
141 jassert (sampleRate > 0.0);
142 jassert (frequency > 0 && frequency <= static_cast<float> (sampleRate * 0.5));
143 jassert (Q > 0.0);
144
145 auto n = 1 / std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
146 auto nSquared = n * n;
147 auto invQ = 1 / Q;
148 auto c1 = 1 / (1 + invQ * n + nSquared);
149
150 return *new Coefficients (c1, c1 * 2, c1,
151 1, c1 * 2 * (1 - nSquared),
152 c1 * (1 - invQ * n + nSquared));
153}
154
155template <typename NumericType>
157 NumericType frequency)
158{
159 return makeHighPass (sampleRate, frequency, inverseRootTwo);
160}
161
162template <typename NumericType>
164 NumericType frequency,
165 NumericType Q)
166{
167 jassert (sampleRate > 0.0);
168 jassert (frequency > 0 && frequency <= static_cast<float> (sampleRate * 0.5));
169 jassert (Q > 0.0);
170
171 auto n = std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
172 auto nSquared = n * n;
173 auto invQ = 1 / Q;
174 auto c1 = 1 / (1 + invQ * n + nSquared);
175
176 return *new Coefficients (c1, c1 * -2, c1,
177 1, c1 * 2 * (nSquared - 1),
178 c1 * (1 - invQ * n + nSquared));
179}
180
181template <typename NumericType>
183 NumericType frequency)
184{
185 return makeBandPass (sampleRate, frequency, inverseRootTwo);
186}
187
188template <typename NumericType>
190 NumericType frequency,
191 NumericType Q)
192{
193 jassert (sampleRate > 0.0);
194 jassert (frequency > 0 && frequency <= static_cast<float> (sampleRate * 0.5));
195 jassert (Q > 0.0);
196
197 auto n = 1 / std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
198 auto nSquared = n * n;
199 auto invQ = 1 / Q;
200 auto c1 = 1 / (1 + invQ * n + nSquared);
201
202 return *new Coefficients (c1 * n * invQ, 0,
203 -c1 * n * invQ, 1,
204 c1 * 2 * (1 - nSquared),
205 c1 * (1 - invQ * n + nSquared));
206}
207
208template <typename NumericType>
210 NumericType frequency)
211{
212 return makeNotch (sampleRate, frequency, inverseRootTwo);
213}
214
215template <typename NumericType>
217 NumericType frequency,
218 NumericType Q)
219{
220 jassert (sampleRate > 0.0);
221 jassert (frequency > 0 && frequency <= static_cast<float> (sampleRate * 0.5));
222 jassert (Q > 0.0);
223
224 auto n = 1 / std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
225 auto nSquared = n * n;
226 auto invQ = 1 / Q;
227 auto c1 = 1 / (1 + n * invQ + nSquared);
228 auto b0 = c1 * (1 + nSquared);
229 auto b1 = 2 * c1 * (1 - nSquared);
230
231 return *new Coefficients (b0, b1, b0, 1, b1, c1 * (1 - n * invQ + nSquared));
232}
233
234template <typename NumericType>
236 NumericType frequency)
237{
238 return makeAllPass (sampleRate, frequency, inverseRootTwo);
239}
240
241template <typename NumericType>
243 NumericType frequency,
244 NumericType Q)
245{
246 jassert (sampleRate > 0);
247 jassert (frequency > 0 && frequency <= sampleRate * 0.5);
248 jassert (Q > 0);
249
250 auto n = 1 / std::tan (MathConstants<NumericType>::pi * frequency / static_cast<NumericType> (sampleRate));
251 auto nSquared = n * n;
252 auto invQ = 1 / Q;
253 auto c1 = 1 / (1 + invQ * n + nSquared);
254 auto b0 = c1 * (1 - n * invQ + nSquared);
255 auto b1 = c1 * 2 * (1 - nSquared);
256
257 return *new Coefficients (b0, b1, 1, 1, b1, b0);
258}
259
260template <typename NumericType>
262 NumericType cutOffFrequency,
263 NumericType Q,
264 NumericType gainFactor)
265{
266 jassert (sampleRate > 0.0);
267 jassert (cutOffFrequency > 0.0 && cutOffFrequency <= sampleRate * 0.5);
268 jassert (Q > 0.0);
269
270 auto A = jmax (static_cast<NumericType> (0.0), std::sqrt (gainFactor));
271 auto aminus1 = A - 1;
272 auto aplus1 = A + 1;
273 auto omega = (2 * MathConstants<NumericType>::pi * jmax (cutOffFrequency, static_cast<NumericType> (2.0))) / static_cast<NumericType> (sampleRate);
274 auto coso = std::cos (omega);
275 auto beta = std::sin (omega) * std::sqrt (A) / Q;
277
278 return *new Coefficients (A * (aplus1 - aminus1TimesCoso + beta),
279 A * 2 * (aminus1 - aplus1 * coso),
280 A * (aplus1 - aminus1TimesCoso - beta),
282 -2 * (aminus1 + aplus1 * coso),
284}
285
286template <typename NumericType>
288 NumericType cutOffFrequency,
289 NumericType Q,
290 NumericType gainFactor)
291{
292 jassert (sampleRate > 0);
293 jassert (cutOffFrequency > 0 && cutOffFrequency <= static_cast<NumericType> (sampleRate * 0.5));
294 jassert (Q > 0);
295
296 auto A = jmax (static_cast<NumericType> (0.0), std::sqrt (gainFactor));
297 auto aminus1 = A - 1;
298 auto aplus1 = A + 1;
299 auto omega = (2 * MathConstants<NumericType>::pi * jmax (cutOffFrequency, static_cast<NumericType> (2.0))) / static_cast<NumericType> (sampleRate);
300 auto coso = std::cos (omega);
301 auto beta = std::sin (omega) * std::sqrt (A) / Q;
303
304 return *new Coefficients (A * (aplus1 + aminus1TimesCoso + beta),
305 A * -2 * (aminus1 + aplus1 * coso),
306 A * (aplus1 + aminus1TimesCoso - beta),
308 2 * (aminus1 - aplus1 * coso),
310}
311
312template <typename NumericType>
314 NumericType frequency,
315 NumericType Q,
316 NumericType gainFactor)
317{
318 jassert (sampleRate > 0);
319 jassert (frequency > 0 && frequency <= static_cast<NumericType> (sampleRate * 0.5));
320 jassert (Q > 0);
321 jassert (gainFactor > 0);
322
323 auto A = jmax (static_cast<NumericType> (0.0), std::sqrt (gainFactor));
324 auto omega = (2 * MathConstants<NumericType>::pi * jmax (frequency, static_cast<NumericType> (2.0))) / static_cast<NumericType> (sampleRate);
325 auto alpha = std::sin (omega) / (Q * 2);
326 auto c2 = -2 * std::cos (omega);
327 auto alphaTimesA = alpha * A;
328 auto alphaOverA = alpha / A;
329
330 return *new Coefficients (1 + alphaTimesA, c2,
331 1 - alphaTimesA,
332 1 + alphaOverA, c2,
333 1 - alphaOverA);
334}
335
336template <typename NumericType>
338{
339 return (static_cast<size_t> (coefficients.size()) - 1) / 2;
340}
341
342template <typename NumericType>
343double IIR::Coefficients<NumericType>::getMagnitudeForFrequency (double frequency, double sampleRate) const noexcept
344{
345 constexpr Complex<double> j (0, 1);
346 const auto order = getFilterOrder();
347 const auto* coefs = coefficients.begin();
348
349 jassert (frequency >= 0 && frequency <= sampleRate * 0.5);
350
351 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
352 Complex<double> jw = std::exp (-MathConstants<double>::twoPi * frequency * j / sampleRate);
353
354 for (size_t n = 0; n <= order; ++n)
355 {
356 numerator += static_cast<double> (coefs[n]) * factor;
357 factor *= jw;
358 }
359
360 denominator = 1.0;
361 factor = jw;
362
363 for (size_t n = order + 1; n <= 2 * order; ++n)
364 {
365 denominator += static_cast<double> (coefs[n]) * factor;
366 factor *= jw;
367 }
368
369 return std::abs (numerator / denominator);
370}
371
372template <typename NumericType>
374 size_t numSamples, double sampleRate) const noexcept
375{
376 constexpr Complex<double> j (0, 1);
377 const auto order = getFilterOrder();
378 const auto* coefs = coefficients.begin();
379
380 jassert (order >= 0);
381
382 for (size_t i = 0; i < numSamples; ++i)
383 {
384 jassert (frequencies[i] >= 0 && frequencies[i] <= sampleRate * 0.5);
385
386 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
387 Complex<double> jw = std::exp (-MathConstants<double>::twoPi * frequencies[i] * j / sampleRate);
388
389 for (size_t n = 0; n <= order; ++n)
390 {
391 numerator += static_cast<double> (coefs[n]) * factor;
392 factor *= jw;
393 }
394
395 denominator = 1.0;
396 factor = jw;
397
398 for (size_t n = order + 1; n <= 2 * order; ++n)
399 {
400 denominator += static_cast<double> (coefs[n]) * factor;
401 factor *= jw;
402 }
403
404 magnitudes[i] = std::abs(numerator / denominator);
405 }
406}
407
408template <typename NumericType>
409double IIR::Coefficients<NumericType>::getPhaseForFrequency (double frequency, double sampleRate) const noexcept
410{
411 constexpr Complex<double> j (0, 1);
412 const auto order = getFilterOrder();
413 const auto* coefs = coefficients.begin();
414
415 jassert (frequency >= 0 && frequency <= sampleRate * 0.5);
416
417 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
418 Complex<double> jw = std::exp (-MathConstants<double>::twoPi * frequency * j / sampleRate);
419
420 for (size_t n = 0; n <= order; ++n)
421 {
422 numerator += static_cast<double> (coefs[n]) * factor;
423 factor *= jw;
424 }
425
426 denominator = 1.0;
427 factor = jw;
428
429 for (size_t n = order + 1; n <= 2 * order; ++n)
430 {
431 denominator += static_cast<double> (coefs[n]) * factor;
432 factor *= jw;
433 }
434
435 return std::arg (numerator / denominator);
436}
437
438template <typename NumericType>
440 size_t numSamples, double sampleRate) const noexcept
441{
442 jassert (sampleRate > 0);
443
444 constexpr Complex<double> j (0, 1);
445 const auto order = getFilterOrder();
446 const auto* coefs = coefficients.begin();
447 auto invSampleRate = 1 / sampleRate;
448
449 jassert (order >= 0);
450
451 for (size_t i = 0; i < numSamples; ++i)
452 {
453 jassert (frequencies[i] >= 0 && frequencies[i] <= sampleRate * 0.5);
454
455 Complex<double> numerator = 0.0, denominator = 0.0, factor = 1.0;
457
458 for (size_t n = 0; n <= order; ++n)
459 {
460 numerator += static_cast<double> (coefs[n]) * factor;
461 factor *= jw;
462 }
463
464 denominator = 1.0;
465 factor = jw;
466
467 for (size_t n = order + 1; n <= 2 * order; ++n)
468 {
469 denominator += static_cast<double> (coefs[n]) * factor;
470 factor *= jw;
471 }
472
473 phases[i] = std::arg (numerator / denominator);
474 }
475}
476
477template struct IIR::Coefficients<float>;
478template struct IIR::Coefficients<double>;
479
480} // namespace dsp
481} // namespace juce
ElementType * begin() noexcept
Definition juce_Array.h:328
void add(const ElementType &newElement)
Definition juce_Array.h:418
static Ptr makeNotch(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
double getMagnitudeForFrequency(double frequency, double sampleRate) const noexcept
static Ptr makeAllPass(double sampleRate, NumericType frequency)
static Ptr makeFirstOrderHighPass(double sampleRate, NumericType frequency)
void getPhaseForFrequencyArray(double *frequencies, double *phases, size_t numSamples, double sampleRate) const noexcept
static Ptr makeFirstOrderAllPass(double sampleRate, NumericType frequency)
static Ptr makePeakFilter(double sampleRate, NumericType centreFrequency, NumericType Q, NumericType gainFactor)
static Ptr makeLowPass(double sampleRate, NumericType frequency)
double getPhaseForFrequency(double frequency, double sampleRate) const noexcept
static Ptr makeLowShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
static Ptr makeBandPass(double sampleRate, NumericType frequency)
static Ptr makeHighPass(double sampleRate, NumericType frequency)
static Ptr makeFirstOrderLowPass(double sampleRate, NumericType frequency)