OpenShot Library | OpenShotAudio 0.2.2
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>
43IIR::Coefficients<NumericType>::Coefficients (NumericType b0, NumericType b1,
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;
276 auto aminus1TimesCoso = aminus1 * coso;
277
278 return *new Coefficients (A * (aplus1 - aminus1TimesCoso + beta),
279 A * 2 * (aminus1 - aplus1 * coso),
280 A * (aplus1 - aminus1TimesCoso - beta),
281 aplus1 + aminus1TimesCoso + beta,
282 -2 * (aminus1 + aplus1 * coso),
283 aplus1 + aminus1TimesCoso - beta);
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;
302 auto aminus1TimesCoso = aminus1 * coso;
303
304 return *new Coefficients (A * (aplus1 + aminus1TimesCoso + beta),
305 A * -2 * (aminus1 + aplus1 * coso),
306 A * (aplus1 + aminus1TimesCoso - beta),
307 aplus1 - aminus1TimesCoso + beta,
308 2 * (aminus1 - aplus1 * coso),
309 aplus1 - aminus1TimesCoso - beta);
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>
373void IIR::Coefficients<NumericType>::getMagnitudeForFrequencyArray (const double* frequencies, double* magnitudes,
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>
439void IIR::Coefficients<NumericType>::getPhaseForFrequencyArray (double* frequencies, double* phases,
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;
456 Complex<double> jw = std::exp (-MathConstants<double>::twoPi * frequencies[i] * j * invSampleRate);
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
A smart-pointer class which points to a reference-counted object.
Commonly used mathematical constants.
A set of coefficients for use in an Filter object.
static Ptr makeNotch(double sampleRate, NumericType frequency)
Returns the coefficients for a notch filter.
static Ptr makeHighShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
Returns the coefficients for a high-pass shelf filter with variable Q and gain.
void getMagnitudeForFrequencyArray(const double *frequencies, double *magnitudes, size_t numSamples, double sampleRate) const noexcept
Returns the magnitude frequency response of the filter for a given frequency array and sample rate.
double getMagnitudeForFrequency(double frequency, double sampleRate) const noexcept
Returns the magnitude frequency response of the filter for a given frequency and sample rate.
static Ptr makeAllPass(double sampleRate, NumericType frequency)
Returns the coefficients for an all-pass filter.
static Ptr makeFirstOrderHighPass(double sampleRate, NumericType frequency)
Returns the coefficients for a first order high-pass filter.
void getPhaseForFrequencyArray(double *frequencies, double *phases, size_t numSamples, double sampleRate) const noexcept
Returns the phase frequency response of the filter for a given frequency array and sample rate.
static Ptr makeFirstOrderAllPass(double sampleRate, NumericType frequency)
Returns the coefficients for a first order all-pass filter.
static Ptr makePeakFilter(double sampleRate, NumericType centreFrequency, NumericType Q, NumericType gainFactor)
Returns the coefficients for a peak filter centred around a given frequency, with a variable Q and ga...
static Ptr makeLowPass(double sampleRate, NumericType frequency)
Returns the coefficients for a low-pass filter.
Coefficients()
Creates a null set of coefficients (which will produce silence).
double getPhaseForFrequency(double frequency, double sampleRate) const noexcept
Returns the phase frequency response of the filter for a given frequency and sample rate.
size_t getFilterOrder() const noexcept
Returns the filter order associated with the coefficients.
static Ptr makeLowShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
Returns the coefficients for a low-pass shelf filter with variable Q and gain.
static Ptr makeBandPass(double sampleRate, NumericType frequency)
Returns the coefficients for a band-pass filter.
static Ptr makeHighPass(double sampleRate, NumericType frequency)
Returns the coefficients for a high-pass filter.
static Ptr makeFirstOrderLowPass(double sampleRate, NumericType frequency)
Returns the coefficients for a first order low-pass filter.