OpenShot Audio Library | OpenShotAudio 0.4.0
 
Loading...
Searching...
No Matches
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
23namespace juce
24{
25
26constexpr 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
46IIRCoefficients::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
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//==============================================================================
263template <typename Mutex>
264IIRFilterBase<Mutex>::IIRFilterBase() noexcept = default;
265
266template <typename Mutex>
267IIRFilterBase<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//==============================================================================
274template <typename Mutex>
276{
277 const typename Mutex::ScopedLockType sl (processLock);
278 active = false;
279}
280
281template <typename Mutex>
282void IIRFilterBase<Mutex>::setCoefficients (const IIRCoefficients& newCoefficients) noexcept
283{
284 const typename Mutex::ScopedLockType sl (processLock);
285 coefficients = newCoefficients;
286 active = true;
287}
288
289//==============================================================================
290template <typename Mutex>
292{
293 const typename Mutex::ScopedLockType sl (processLock);
294 v1 = v2 = 0.0;
295}
296
297template <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
310template <typename Mutex>
311void 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
339template class IIRFilterBase<SpinLock>;
341
342} // namespace juce
static Type gainWithLowerBound(Type gain, Type lowerBoundDb)
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
static constexpr FloatType twoPi
static constexpr FloatType sqrt2
static constexpr FloatType pi