OpenShot Audio Library | OpenShotAudio  0.6.0
juce_audio_basics/utilities/juce_IIRFilter.cpp
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  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 constexpr auto minimumDecibels = -300.0f;
27 
29 {
30  zeromem (coefficients, sizeof (coefficients));
31 }
32 
34 
36 {
37  memcpy (coefficients, other.coefficients, sizeof (coefficients));
38 }
39 
41 {
42  memcpy (coefficients, other.coefficients, sizeof (coefficients));
43  return *this;
44 }
45 
46 IIRCoefficients::IIRCoefficients (double c1, double c2, double c3,
47  double c4, double c5, double c6) noexcept
48 {
49  const auto a = 1.0 / c4;
50 
51  coefficients[0] = (float) (c1 * a);
52  coefficients[1] = (float) (c2 * a);
53  coefficients[2] = (float) (c3 * a);
54  coefficients[3] = (float) (c5 * a);
55  coefficients[4] = (float) (c6 * a);
56 }
57 
59  double frequency) noexcept
60 {
61  return makeLowPass (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
62 }
63 
65  double frequency,
66  double Q) noexcept
67 {
68  jassert (sampleRate > 0.0);
69  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
70  jassert (Q > 0.0);
71 
72  const auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
73  const auto nSquared = n * n;
74  const auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
75 
76  return IIRCoefficients (c1,
77  c1 * 2.0,
78  c1,
79  1.0,
80  c1 * 2.0 * (1.0 - nSquared),
81  c1 * (1.0 - 1.0 / Q * n + nSquared));
82 }
83 
85  double frequency) noexcept
86 {
87  return makeHighPass (sampleRate, frequency, 1.0 / std::sqrt (2.0));
88 }
89 
91  double frequency,
92  double Q) noexcept
93 {
94  jassert (sampleRate > 0.0);
95  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
96  jassert (Q > 0.0);
97 
98  const auto n = std::tan (MathConstants<double>::pi * frequency / sampleRate);
99  const auto nSquared = n * n;
100  const auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
101 
102  return IIRCoefficients (c1,
103  c1 * -2.0,
104  c1,
105  1.0,
106  c1 * 2.0 * (nSquared - 1.0),
107  c1 * (1.0 - 1.0 / Q * n + nSquared));
108 }
109 
111  double frequency) noexcept
112 {
113  return makeBandPass (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
114 }
115 
117  double frequency,
118  double Q) noexcept
119 {
120  jassert (sampleRate > 0.0);
121  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
122  jassert (Q > 0.0);
123 
124  const auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
125  const auto nSquared = n * n;
126  const auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
127 
128  return IIRCoefficients (c1 * n / Q,
129  0.0,
130  -c1 * n / Q,
131  1.0,
132  c1 * 2.0 * (1.0 - nSquared),
133  c1 * (1.0 - 1.0 / Q * n + nSquared));
134 }
135 
137  double frequency) noexcept
138 {
139  return makeNotchFilter (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
140 }
141 
143  double frequency,
144  double Q) noexcept
145 {
146  jassert (sampleRate > 0.0);
147  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
148  jassert (Q > 0.0);
149 
150  const auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
151  const auto nSquared = n * n;
152  const auto c1 = 1.0 / (1.0 + n / Q + nSquared);
153 
154  return IIRCoefficients (c1 * (1.0 + nSquared),
155  2.0 * c1 * (1.0 - nSquared),
156  c1 * (1.0 + nSquared),
157  1.0,
158  c1 * 2.0 * (1.0 - nSquared),
159  c1 * (1.0 - n / Q + nSquared));
160 }
161 
163  double frequency) noexcept
164 {
165  return makeAllPass (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
166 }
167 
169  double frequency,
170  double Q) noexcept
171 {
172  jassert (sampleRate > 0.0);
173  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
174  jassert (Q > 0.0);
175 
176  const auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
177  const auto nSquared = n * n;
178  const auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
179 
180  return IIRCoefficients (c1 * (1.0 - n / Q + nSquared),
181  c1 * 2.0 * (1.0 - nSquared),
182  1.0,
183  1.0,
184  c1 * 2.0 * (1.0 - nSquared),
185  c1 * (1.0 - n / Q + nSquared));
186 }
187 
189  double cutOffFrequency,
190  double Q,
191  float gainFactor) noexcept
192 {
193  jassert (sampleRate > 0.0);
194  jassert (cutOffFrequency > 0.0 && cutOffFrequency <= sampleRate * 0.5);
195  jassert (Q > 0.0);
196 
197  const auto A = std::sqrt (Decibels::gainWithLowerBound (gainFactor, minimumDecibels));
198  const auto aminus1 = A - 1.0;
199  const auto aplus1 = A + 1.0;
200  const auto omega = (MathConstants<double>::twoPi * jmax (cutOffFrequency, 2.0)) / sampleRate;
201  const auto coso = std::cos (omega);
202  const auto beta = std::sin (omega) * std::sqrt (A) / Q;
203  const auto aminus1TimesCoso = aminus1 * coso;
204 
205  return IIRCoefficients (A * (aplus1 - aminus1TimesCoso + beta),
206  A * 2.0 * (aminus1 - aplus1 * coso),
207  A * (aplus1 - aminus1TimesCoso - beta),
208  aplus1 + aminus1TimesCoso + beta,
209  -2.0 * (aminus1 + aplus1 * coso),
210  aplus1 + aminus1TimesCoso - beta);
211 }
212 
214  double cutOffFrequency,
215  double Q,
216  float gainFactor) noexcept
217 {
218  jassert (sampleRate > 0.0);
219  jassert (cutOffFrequency > 0.0 && cutOffFrequency <= sampleRate * 0.5);
220  jassert (Q > 0.0);
221 
222  const auto A = std::sqrt (Decibels::gainWithLowerBound (gainFactor, minimumDecibels));
223  const auto aminus1 = A - 1.0;
224  const auto aplus1 = A + 1.0;
225  const auto omega = (MathConstants<double>::twoPi * jmax (cutOffFrequency, 2.0)) / sampleRate;
226  const auto coso = std::cos (omega);
227  const auto beta = std::sin (omega) * std::sqrt (A) / Q;
228  const auto aminus1TimesCoso = aminus1 * coso;
229 
230  return IIRCoefficients (A * (aplus1 + aminus1TimesCoso + beta),
231  A * -2.0 * (aminus1 + aplus1 * coso),
232  A * (aplus1 + aminus1TimesCoso - beta),
233  aplus1 - aminus1TimesCoso + beta,
234  2.0 * (aminus1 - aplus1 * coso),
235  aplus1 - aminus1TimesCoso - beta);
236 }
237 
239  double frequency,
240  double Q,
241  float gainFactor) noexcept
242 {
243  jassert (sampleRate > 0.0);
244  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
245  jassert (Q > 0.0);
246 
247  const auto A = std::sqrt (Decibels::gainWithLowerBound (gainFactor, minimumDecibels));
248  const auto omega = (MathConstants<double>::twoPi * jmax (frequency, 2.0)) / sampleRate;
249  const auto alpha = 0.5 * std::sin (omega) / Q;
250  const auto c2 = -2.0 * std::cos (omega);
251  const auto alphaTimesA = alpha * A;
252  const auto alphaOverA = alpha / A;
253 
254  return IIRCoefficients (1.0 + alphaTimesA,
255  c2,
256  1.0 - alphaTimesA,
257  1.0 + alphaOverA,
258  c2,
259  1.0 - alphaOverA);
260 }
261 
262 //==============================================================================
263 template <typename Mutex>
264 IIRFilterBase<Mutex>::IIRFilterBase() noexcept = default;
265 
266 template <typename Mutex>
267 IIRFilterBase<Mutex>::IIRFilterBase (const IIRFilterBase& other) noexcept : active (other.active)
268 {
269  const typename Mutex::ScopedLockType sl (other.processLock);
270  coefficients = other.coefficients;
271 }
272 
273 //==============================================================================
274 template <typename Mutex>
276 {
277  const typename Mutex::ScopedLockType sl (processLock);
278  active = false;
279 }
280 
281 template <typename Mutex>
282 void IIRFilterBase<Mutex>::setCoefficients (const IIRCoefficients& newCoefficients) noexcept
283 {
284  const typename Mutex::ScopedLockType sl (processLock);
285  coefficients = newCoefficients;
286  active = true;
287 }
288 
289 //==============================================================================
290 template <typename Mutex>
292 {
293  const typename Mutex::ScopedLockType sl (processLock);
294  v1 = v2 = 0.0;
295 }
296 
297 template <typename Mutex>
299 {
300  auto out = coefficients.coefficients[0] * in + v1;
301 
302  JUCE_SNAP_TO_ZERO (out);
303 
304  v1 = coefficients.coefficients[1] * in - coefficients.coefficients[3] * out + v2;
305  v2 = coefficients.coefficients[2] * in - coefficients.coefficients[4] * out;
306 
307  return out;
308 }
309 
310 template <typename Mutex>
311 void IIRFilterBase<Mutex>::processSamples (float* const samples, const int numSamples) noexcept
312 {
313  const typename Mutex::ScopedLockType sl (processLock);
314 
315  if (active)
316  {
317  auto c0 = coefficients.coefficients[0];
318  auto c1 = coefficients.coefficients[1];
319  auto c2 = coefficients.coefficients[2];
320  auto c3 = coefficients.coefficients[3];
321  auto c4 = coefficients.coefficients[4];
322  auto lv1 = v1, lv2 = v2;
323 
324  for (int i = 0; i < numSamples; ++i)
325  {
326  auto in = samples[i];
327  auto out = c0 * in + lv1;
328  samples[i] = out;
329 
330  lv1 = c1 * in - c3 * out + lv2;
331  lv2 = c2 * in - c4 * out;
332  }
333 
334  JUCE_SNAP_TO_ZERO (lv1); v1 = lv1;
335  JUCE_SNAP_TO_ZERO (lv2); v2 = lv2;
336  }
337 }
338 
339 template class IIRFilterBase<SpinLock>;
341 
342 } // namespace juce
static Type gainWithLowerBound(Type gain, Type lowerBoundDb)
Definition: juce_Decibels.h:68
static IIRCoefficients makeAllPass(double sampleRate, double frequency) noexcept
IIRCoefficients & operator=(const IIRCoefficients &) noexcept
static IIRCoefficients makeLowPass(double sampleRate, double frequency) noexcept
static IIRCoefficients makeNotchFilter(double sampleRate, double frequency) noexcept
static IIRCoefficients makePeakFilter(double sampleRate, double centreFrequency, double Q, float gainFactor) noexcept
static IIRCoefficients makeBandPass(double sampleRate, double frequency) noexcept
static IIRCoefficients makeHighShelf(double sampleRate, double cutOffFrequency, double Q, float gainFactor) noexcept
static IIRCoefficients makeLowShelf(double sampleRate, double cutOffFrequency, double Q, float gainFactor) noexcept
static IIRCoefficients makeHighPass(double sampleRate, double frequency) noexcept
IIRFilterBase() noexcept
float processSingleSampleRaw(float sample) noexcept
void setCoefficients(const IIRCoefficients &newCoefficients) noexcept
void processSamples(float *samples, int numSamples) noexcept