OpenShot Library | OpenShotAudio 0.2.2
juce_IIRFilter_Impl.h
1
2/** @weakgroup juce_dsp-processors
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 By using JUCE, you agree to the terms of both the JUCE 5 End-User License
15 Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
16 27th April 2017).
17
18 End User License Agreement: www.juce.com/juce-5-licence
19 Privacy Policy: www.juce.com/juce-5-privacy-policy
20
21 Or: You may also use this code under the terms of the GPL v3 (see
22 www.gnu.org/licenses).
23
24 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
25 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
26 DISCLAIMED.
27
28 ==============================================================================
29*/
30
31namespace juce
32{
33namespace dsp
34{
35namespace IIR
36{
37
38#ifndef DOXYGEN
39
40//==============================================================================
41template <typename SampleType>
43 : coefficients (new Coefficients<typename Filter<SampleType>::NumericType> (1, 0, 1, 0))
44{
45 reset();
46}
47
48template <typename SampleType>
49Filter<SampleType>::Filter (CoefficientsPtr c) : coefficients (std::move (c))
50{
51 reset();
52}
53
54template <typename SampleType>
55void Filter<SampleType>::reset (SampleType resetToValue)
56{
57 auto newOrder = coefficients->getFilterOrder();
58
59 if (newOrder != order)
60 {
61 memory.malloc (jmax (order, newOrder, static_cast<size_t> (3)) + 1);
62 state = snapPointerToAlignment (memory.getData(), sizeof (SampleType));
63 order = newOrder;
64 }
65
66 for (size_t i = 0; i < order; ++i)
67 state[i] = resetToValue;
68}
69
70template <typename SampleType>
71void Filter<SampleType>::prepare (const ProcessSpec&) noexcept { reset(); }
72
73template <typename SampleType>
74template <typename ProcessContext, bool bypassed>
75void Filter<SampleType>::processInternal (const ProcessContext& context) noexcept
76{
77 static_assert (std::is_same<typename ProcessContext::SampleType, SampleType>::value,
78 "The sample-type of the IIR filter must match the sample-type supplied to this process callback");
79 check();
80
81 auto&& inputBlock = context.getInputBlock();
82 auto&& outputBlock = context.getOutputBlock();
83
84 // This class can only process mono signals. Use the ProcessorDuplicator class
85 // to apply this filter on a multi-channel audio stream.
86 jassert (inputBlock.getNumChannels() == 1);
87 jassert (outputBlock.getNumChannels() == 1);
88
89 auto numSamples = inputBlock.getNumSamples();
90 auto* src = inputBlock .getChannelPointer (0);
91 auto* dst = outputBlock.getChannelPointer (0);
92 auto* coeffs = coefficients->getRawCoefficients();
93
94 switch (order)
95 {
96 case 1:
97 {
98 auto b0 = coeffs[0];
99 auto b1 = coeffs[1];
100 auto a1 = coeffs[2];
101
102 auto lv1 = state[0];
103
104 for (size_t i = 0; i < numSamples; ++i)
105 {
106 auto input = src[i];
107 auto output = input * b0 + lv1;
108
109 dst[i] = bypassed ? input : output;
110
111 lv1 = (input * b1) - (output * a1);
112 }
113
114 util::snapToZero (lv1); state[0] = lv1;
115 }
116 break;
117
118 case 2:
119 {
120 auto b0 = coeffs[0];
121 auto b1 = coeffs[1];
122 auto b2 = coeffs[2];
123 auto a1 = coeffs[3];
124 auto a2 = coeffs[4];
125
126 auto lv1 = state[0];
127 auto lv2 = state[1];
128
129 for (size_t i = 0; i < numSamples; ++i)
130 {
131 auto input = src[i];
132 auto output = (input * b0) + lv1;
133 dst[i] = bypassed ? input : output;
134
135 lv1 = (input * b1) - (output* a1) + lv2;
136 lv2 = (input * b2) - (output* a2);
137 }
138
139 util::snapToZero (lv1); state[0] = lv1;
140 util::snapToZero (lv2); state[1] = lv2;
141 }
142 break;
143
144 case 3:
145 {
146 auto b0 = coeffs[0];
147 auto b1 = coeffs[1];
148 auto b2 = coeffs[2];
149 auto b3 = coeffs[3];
150 auto a1 = coeffs[4];
151 auto a2 = coeffs[5];
152 auto a3 = coeffs[6];
153
154 auto lv1 = state[0];
155 auto lv2 = state[1];
156 auto lv3 = state[2];
157
158 for (size_t i = 0; i < numSamples; ++i)
159 {
160 auto input = src[i];
161 auto output = (input * b0) + lv1;
162 dst[i] = bypassed ? input : output;
163
164 lv1 = (input * b1) - (output* a1) + lv2;
165 lv2 = (input * b2) - (output* a2) + lv3;
166 lv3 = (input * b3) - (output* a3);
167 }
168
169 util::snapToZero (lv1); state[0] = lv1;
170 util::snapToZero (lv2); state[1] = lv2;
171 util::snapToZero (lv3); state[2] = lv3;
172 }
173 break;
174
175 default:
176 {
177 for (size_t i = 0; i < numSamples; ++i)
178 {
179 auto input = src[i];
180 auto output= (input * coeffs[0]) + state[0];
181 dst[i] = bypassed ? input : output;
182
183 for (size_t j = 0; j < order - 1; ++j)
184 state[j] = (input * coeffs[j + 1]) - (output* coeffs[order + j + 1]) + state[j + 1];
185
186 state[order - 1] = (input * coeffs[order]) - (output* coeffs[order * 2]);
187 }
188
189 snapToZero();
190 }
191 }
192}
193
194template <typename SampleType>
195SampleType JUCE_VECTOR_CALLTYPE Filter<SampleType>::processSample (SampleType sample) noexcept
196{
197 check();
198 auto* c = coefficients->getRawCoefficients();
199
200 auto output= (c[0] * sample) + state[0];
201
202 for (size_t j = 0; j < order - 1; ++j)
203 state[j] = (c[j + 1] * sample) - (c[order + j + 1] * output) + state[j + 1];
204
205 state[order - 1] = (c[order] * sample) - (c[order * 2] * output);
206
207 return output;
208}
209
210template <typename SampleType>
211void Filter<SampleType>::snapToZero() noexcept
212{
213 for (size_t i = 0; i < order; ++i)
214 util::snapToZero (state[i]);
215}
216
217template <typename SampleType>
218void Filter<SampleType>::check()
219{
220 jassert (coefficients != nullptr);
221
222 if (order != coefficients->getFilterOrder())
223 reset();
224}
225
226#endif
227
228} // namespace IIR
229} // namespace dsp
230} // namespace juce
231
232/** @}*/
Filter()
Creates a filter.