OpenShot Audio Library | OpenShotAudio  0.3.3
juce_audio_basics/utilities/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  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 
27 {
28  zeromem (coefficients, sizeof (coefficients));
29 }
30 
32 
34 {
35  memcpy (coefficients, other.coefficients, sizeof (coefficients));
36 }
37 
39 {
40  memcpy (coefficients, other.coefficients, sizeof (coefficients));
41  return *this;
42 }
43 
44 IIRCoefficients::IIRCoefficients (double c1, double c2, double c3,
45  double c4, double c5, double c6) noexcept
46 {
47  auto a = 1.0 / c4;
48 
49  coefficients[0] = (float) (c1 * a);
50  coefficients[1] = (float) (c2 * a);
51  coefficients[2] = (float) (c3 * a);
52  coefficients[3] = (float) (c5 * a);
53  coefficients[4] = (float) (c6 * a);
54 }
55 
57  double frequency) noexcept
58 {
59  return makeLowPass (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
60 }
61 
63  double frequency,
64  double Q) noexcept
65 {
66  jassert (sampleRate > 0.0);
67  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
68  jassert (Q > 0.0);
69 
70  auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
71  auto nSquared = n * n;
72  auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
73 
74  return IIRCoefficients (c1,
75  c1 * 2.0,
76  c1,
77  1.0,
78  c1 * 2.0 * (1.0 - nSquared),
79  c1 * (1.0 - 1.0 / Q * n + nSquared));
80 }
81 
83  double frequency) noexcept
84 {
85  return makeHighPass (sampleRate, frequency, 1.0 / std::sqrt(2.0));
86 }
87 
89  double frequency,
90  double Q) noexcept
91 {
92  jassert (sampleRate > 0.0);
93  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
94  jassert (Q > 0.0);
95 
96  auto n = std::tan (MathConstants<double>::pi * frequency / sampleRate);
97  auto nSquared = n * n;
98  auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
99 
100  return IIRCoefficients (c1,
101  c1 * -2.0,
102  c1,
103  1.0,
104  c1 * 2.0 * (nSquared - 1.0),
105  c1 * (1.0 - 1.0 / Q * n + nSquared));
106 }
107 
109  double frequency) noexcept
110 {
111  return makeBandPass (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
112 }
113 
115  double frequency,
116  double Q) noexcept
117 {
118  jassert (sampleRate > 0.0);
119  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
120  jassert (Q > 0.0);
121 
122  auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
123  auto nSquared = n * n;
124  auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
125 
126  return IIRCoefficients (c1 * n / Q,
127  0.0,
128  -c1 * n / Q,
129  1.0,
130  c1 * 2.0 * (1.0 - nSquared),
131  c1 * (1.0 - 1.0 / Q * n + nSquared));
132 }
133 
135  double frequency) noexcept
136 {
137  return makeNotchFilter (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
138 }
139 
141  double frequency,
142  double Q) noexcept
143 {
144  jassert (sampleRate > 0.0);
145  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
146  jassert (Q > 0.0);
147 
148  auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
149  auto nSquared = n * n;
150  auto c1 = 1.0 / (1.0 + n / Q + nSquared);
151 
152  return IIRCoefficients (c1 * (1.0 + nSquared),
153  2.0 * c1 * (1.0 - nSquared),
154  c1 * (1.0 + nSquared),
155  1.0,
156  c1 * 2.0 * (1.0 - nSquared),
157  c1 * (1.0 - n / Q + nSquared));
158 }
159 
161  double frequency) noexcept
162 {
163  return makeAllPass (sampleRate, frequency, 1.0 / MathConstants<double>::sqrt2);
164 }
165 
167  double frequency,
168  double Q) noexcept
169 {
170  jassert (sampleRate > 0.0);
171  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
172  jassert (Q > 0.0);
173 
174  auto n = 1.0 / std::tan (MathConstants<double>::pi * frequency / sampleRate);
175  auto nSquared = n * n;
176  auto c1 = 1.0 / (1.0 + 1.0 / Q * n + nSquared);
177 
178  return IIRCoefficients (c1 * (1.0 - n / Q + nSquared),
179  c1 * 2.0 * (1.0 - nSquared),
180  1.0,
181  1.0,
182  c1 * 2.0 * (1.0 - nSquared),
183  c1 * (1.0 - n / Q + nSquared));
184 }
185 
187  double cutOffFrequency,
188  double Q,
189  float gainFactor) noexcept
190 {
191  jassert (sampleRate > 0.0);
192  jassert (cutOffFrequency > 0.0 && cutOffFrequency <= sampleRate * 0.5);
193  jassert (Q > 0.0);
194 
195  auto A = jmax (0.0f, std::sqrt (gainFactor));
196  auto aminus1 = A - 1.0;
197  auto aplus1 = A + 1.0;
198  auto omega = (MathConstants<double>::twoPi * jmax (cutOffFrequency, 2.0)) / sampleRate;
199  auto coso = std::cos (omega);
200  auto beta = std::sin (omega) * std::sqrt (A) / Q;
201  auto aminus1TimesCoso = aminus1 * coso;
202 
203  return IIRCoefficients (A * (aplus1 - aminus1TimesCoso + beta),
204  A * 2.0 * (aminus1 - aplus1 * coso),
205  A * (aplus1 - aminus1TimesCoso - beta),
206  aplus1 + aminus1TimesCoso + beta,
207  -2.0 * (aminus1 + aplus1 * coso),
208  aplus1 + aminus1TimesCoso - beta);
209 }
210 
212  double cutOffFrequency,
213  double Q,
214  float gainFactor) noexcept
215 {
216  jassert (sampleRate > 0.0);
217  jassert (cutOffFrequency > 0.0 && cutOffFrequency <= sampleRate * 0.5);
218  jassert (Q > 0.0);
219 
220  auto A = jmax (0.0f, std::sqrt (gainFactor));
221  auto aminus1 = A - 1.0;
222  auto aplus1 = A + 1.0;
223  auto omega = (MathConstants<double>::twoPi * jmax (cutOffFrequency, 2.0)) / sampleRate;
224  auto coso = std::cos (omega);
225  auto beta = std::sin (omega) * std::sqrt (A) / Q;
226  auto aminus1TimesCoso = aminus1 * coso;
227 
228  return IIRCoefficients (A * (aplus1 + aminus1TimesCoso + beta),
229  A * -2.0 * (aminus1 + aplus1 * coso),
230  A * (aplus1 + aminus1TimesCoso - beta),
231  aplus1 - aminus1TimesCoso + beta,
232  2.0 * (aminus1 - aplus1 * coso),
233  aplus1 - aminus1TimesCoso - beta);
234 }
235 
237  double frequency,
238  double Q,
239  float gainFactor) noexcept
240 {
241  jassert (sampleRate > 0.0);
242  jassert (frequency > 0.0 && frequency <= sampleRate * 0.5);
243  jassert (Q > 0.0);
244 
245  auto A = jmax (0.0f, std::sqrt (gainFactor));
246  auto omega = (MathConstants<double>::twoPi * jmax (frequency, 2.0)) / sampleRate;
247  auto alpha = 0.5 * std::sin (omega) / Q;
248  auto c2 = -2.0 * std::cos (omega);
249  auto alphaTimesA = alpha * A;
250  auto alphaOverA = alpha / A;
251 
252  return IIRCoefficients (1.0 + alphaTimesA,
253  c2,
254  1.0 - alphaTimesA,
255  1.0 + alphaOverA,
256  c2,
257  1.0 - alphaOverA);
258 }
259 
260 //==============================================================================
262 {
263 }
264 
265 IIRFilter::IIRFilter (const IIRFilter& other) noexcept : active (other.active)
266 {
267  const SpinLock::ScopedLockType sl (other.processLock);
268  coefficients = other.coefficients;
269 }
270 
272 {
273 }
274 
275 //==============================================================================
276 void IIRFilter::makeInactive() noexcept
277 {
278  const SpinLock::ScopedLockType sl (processLock);
279  active = false;
280 }
281 
282 void IIRFilter::setCoefficients (const IIRCoefficients& newCoefficients) noexcept
283 {
284  const SpinLock::ScopedLockType sl (processLock);
285  coefficients = newCoefficients;
286  active = true;
287 }
288 
289 //==============================================================================
290 void IIRFilter::reset() noexcept
291 {
292  const SpinLock::ScopedLockType sl (processLock);
293  v1 = v2 = 0.0;
294 }
295 
296 float IIRFilter::processSingleSampleRaw (float in) noexcept
297 {
298  auto out = coefficients.coefficients[0] * in + v1;
299 
300  JUCE_SNAP_TO_ZERO (out);
301 
302  v1 = coefficients.coefficients[1] * in - coefficients.coefficients[3] * out + v2;
303  v2 = coefficients.coefficients[2] * in - coefficients.coefficients[4] * out;
304 
305  return out;
306 }
307 
308 void IIRFilter::processSamples (float* const samples, const int numSamples) noexcept
309 {
310  const SpinLock::ScopedLockType sl (processLock);
311 
312  if (active)
313  {
314  auto c0 = coefficients.coefficients[0];
315  auto c1 = coefficients.coefficients[1];
316  auto c2 = coefficients.coefficients[2];
317  auto c3 = coefficients.coefficients[3];
318  auto c4 = coefficients.coefficients[4];
319  auto lv1 = v1, lv2 = v2;
320 
321  for (int i = 0; i < numSamples; ++i)
322  {
323  auto in = samples[i];
324  auto out = c0 * in + lv1;
325  samples[i] = out;
326 
327  lv1 = c1 * in - c3 * out + lv2;
328  lv2 = c2 * in - c4 * out;
329  }
330 
331  JUCE_SNAP_TO_ZERO (lv1); v1 = lv1;
332  JUCE_SNAP_TO_ZERO (lv2); v2 = lv2;
333  }
334 }
335 
336 } // namespace juce
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
float processSingleSampleRaw(float sample) noexcept
void processSamples(float *samples, int numSamples) noexcept
void setCoefficients(const IIRCoefficients &newCoefficients) noexcept