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 
27 namespace juce
28 {
29 namespace dsp
30 {
31 
32 template <typename NumericType>
34  : coefficients ({ NumericType(),
35  NumericType(),
36  NumericType(),
37  NumericType(),
38  NumericType() })
39 {
40 }
41 
42 template <typename NumericType>
43 IIR::Coefficients<NumericType>::Coefficients (NumericType b0, NumericType b1,
44  NumericType a0, NumericType a1)
45 {
46  jassert (a0 != 0);
47 
49 
50  auto a0inv = static_cast<NumericType> (1) / a0;
51 
52  coefficients.add (b0 * a0inv,
53  b1 * a0inv,
54  a1 * a0inv);
55 }
56 
57 template <typename NumericType>
58 IIR::Coefficients<NumericType>::Coefficients (NumericType b0, NumericType b1, NumericType b2,
59  NumericType a0, NumericType a1, NumericType a2)
60 {
61  jassert (a0 != 0);
62 
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 
74 template <typename NumericType>
75 IIR::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 
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 
93 template <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 
105 template <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 
117 template <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 
129 template <typename NumericType>
131  NumericType frequency)
132 {
133  return makeLowPass (sampleRate, frequency, inverseRootTwo);
134 }
135 
136 template <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 
155 template <typename NumericType>
157  NumericType frequency)
158 {
159  return makeHighPass (sampleRate, frequency, inverseRootTwo);
160 }
161 
162 template <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 
181 template <typename NumericType>
183  NumericType frequency)
184 {
185  return makeBandPass (sampleRate, frequency, inverseRootTwo);
186 }
187 
188 template <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 
208 template <typename NumericType>
210  NumericType frequency)
211 {
212  return makeNotch (sampleRate, frequency, inverseRootTwo);
213 }
214 
215 template <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 
234 template <typename NumericType>
236  NumericType frequency)
237 {
238  return makeAllPass (sampleRate, frequency, inverseRootTwo);
239 }
240 
241 template <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 
260 template <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 
286 template <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 
312 template <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 
336 template <typename NumericType>
338 {
339  return (static_cast<size_t> (coefficients.size()) - 1) / 2;
340 }
341 
342 template <typename NumericType>
343 double 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 
372 template <typename NumericType>
373 void 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 
408 template <typename NumericType>
409 double 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 
438 template <typename NumericType>
439 void 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 
477 template struct IIR::Coefficients<float>;
478 template struct IIR::Coefficients<double>;
479 
480 } // namespace dsp
481 } // namespace juce
double getMagnitudeForFrequency(double frequency, double sampleRate) const noexcept
Returns the magnitude frequency response of the filter for a given frequency and sample rate...
Array< NumericType > coefficients
The raw coefficients.
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition: juce_Array.h:422
static Ptr makeNotch(double sampleRate, NumericType frequency)
Returns the coefficients for a notch filter.
Coefficients()
Creates a null set of coefficients (which will produce silence).
static Ptr makeFirstOrderHighPass(double sampleRate, NumericType frequency)
Returns the coefficients for a first order high-pass filter.
static Ptr makeAllPass(double sampleRate, NumericType frequency)
Returns the coefficients for an 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.
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...
ElementType * begin() noexcept
Returns a pointer to the first element in the array.
Definition: juce_Array.h:332
static Ptr makeHighPass(double sampleRate, NumericType frequency)
Returns the coefficients for a high-pass filter.
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 makeFirstOrderAllPass(double sampleRate, NumericType frequency)
Returns the coefficients for a first order all-pass filter.
A set of coefficients for use in an Filter object.
static Ptr makeFirstOrderLowPass(double sampleRate, NumericType frequency)
Returns the coefficients for a first order low-pass filter.
static Ptr makeBandPass(double sampleRate, NumericType frequency)
Returns the coefficients for a band-pass filter.
double getPhaseForFrequency(double frequency, double sampleRate) const noexcept
Returns the phase frequency response of the filter for a given frequency and sample rate...
void clear()
Removes all elements from the array.
Definition: juce_Array.h:192
int size() const noexcept
Returns the current number of elements in the array.
Definition: juce_Array.h:219
A smart-pointer class which points to a reference-counted object.
Commonly used mathematical constants.
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...
size_t getFilterOrder() const noexcept
Returns the filter order associated with the coefficients.
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.