OpenShot Audio Library | OpenShotAudio  0.3.0
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
void add(const ElementType &newElement)
Definition: juce_Array.h:418
static Ptr makeNotch(double sampleRate, NumericType frequency)
static Ptr makeFirstOrderHighPass(double sampleRate, NumericType frequency)
static Ptr makeAllPass(double sampleRate, NumericType frequency)
static Ptr makePeakFilter(double sampleRate, NumericType centreFrequency, NumericType Q, NumericType gainFactor)
static Ptr makeLowPass(double sampleRate, NumericType frequency)
void getMagnitudeForFrequencyArray(const double *frequencies, double *magnitudes, size_t numSamples, double sampleRate) const noexcept
ElementType * begin() noexcept
Definition: juce_Array.h:328
static Ptr makeHighPass(double sampleRate, NumericType frequency)
static Ptr makeLowShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)
static Ptr makeFirstOrderAllPass(double sampleRate, NumericType frequency)
static Ptr makeFirstOrderLowPass(double sampleRate, NumericType frequency)
static Ptr makeBandPass(double sampleRate, NumericType frequency)
double getPhaseForFrequency(double frequency, double sampleRate) const noexcept
void clear()
Definition: juce_Array.h:188
int size() const noexcept
Definition: juce_Array.h:215
void getPhaseForFrequencyArray(double *frequencies, double *phases, size_t numSamples, double sampleRate) const noexcept
static Ptr makeHighShelf(double sampleRate, NumericType cutOffFrequency, NumericType Q, NumericType gainFactor)