OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
juce_IIRFilter_Impl.h
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
27namespace juce
28{
29namespace dsp
30{
31namespace IIR
32{
33
34#ifndef DOXYGEN
35
36//==============================================================================
37template <typename SampleType>
39 : coefficients (new Coefficients<typename Filter<SampleType>::NumericType> (1, 0, 1, 0))
40{
41 reset();
42}
43
44template <typename SampleType>
45Filter<SampleType>::Filter (CoefficientsPtr c) : coefficients (std::move (c))
46{
47 reset();
48}
49
50template <typename SampleType>
52{
53 auto newOrder = coefficients->getFilterOrder();
54
55 if (newOrder != order)
56 {
57 memory.malloc (jmax (order, newOrder, static_cast<size_t> (3)) + 1);
58 state = snapPointerToAlignment (memory.getData(), sizeof (SampleType));
59 order = newOrder;
60 }
61
62 for (size_t i = 0; i < order; ++i)
63 state[i] = resetToValue;
64}
65
66template <typename SampleType>
67void Filter<SampleType>::prepare (const ProcessSpec&) noexcept { reset(); }
68
69template <typename SampleType>
70template <typename ProcessContext, bool bypassed>
71void Filter<SampleType>::processInternal (const ProcessContext& context) noexcept
72{
73 static_assert (std::is_same<typename ProcessContext::SampleType, SampleType>::value,
74 "The sample-type of the IIR filter must match the sample-type supplied to this process callback");
75 check();
76
77 auto&& inputBlock = context.getInputBlock();
78 auto&& outputBlock = context.getOutputBlock();
79
80 // This class can only process mono signals. Use the ProcessorDuplicator class
81 // to apply this filter on a multi-channel audio stream.
82 jassert (inputBlock.getNumChannels() == 1);
83 jassert (outputBlock.getNumChannels() == 1);
84
85 auto numSamples = inputBlock.getNumSamples();
86 auto* src = inputBlock .getChannelPointer (0);
87 auto* dst = outputBlock.getChannelPointer (0);
88 auto* coeffs = coefficients->getRawCoefficients();
89
90 switch (order)
91 {
92 case 1:
93 {
94 auto b0 = coeffs[0];
95 auto b1 = coeffs[1];
96 auto a1 = coeffs[2];
97
98 auto lv1 = state[0];
99
100 for (size_t i = 0; i < numSamples; ++i)
101 {
102 auto input = src[i];
103 auto output = input * b0 + lv1;
104
105 dst[i] = bypassed ? input : output;
106
107 lv1 = (input * b1) - (output * a1);
108 }
109
110 util::snapToZero (lv1); state[0] = lv1;
111 }
112 break;
113
114 case 2:
115 {
116 auto b0 = coeffs[0];
117 auto b1 = coeffs[1];
118 auto b2 = coeffs[2];
119 auto a1 = coeffs[3];
120 auto a2 = coeffs[4];
121
122 auto lv1 = state[0];
123 auto lv2 = state[1];
124
125 for (size_t i = 0; i < numSamples; ++i)
126 {
127 auto input = src[i];
128 auto output = (input * b0) + lv1;
129 dst[i] = bypassed ? input : output;
130
131 lv1 = (input * b1) - (output* a1) + lv2;
132 lv2 = (input * b2) - (output* a2);
133 }
134
135 util::snapToZero (lv1); state[0] = lv1;
136 util::snapToZero (lv2); state[1] = lv2;
137 }
138 break;
139
140 case 3:
141 {
142 auto b0 = coeffs[0];
143 auto b1 = coeffs[1];
144 auto b2 = coeffs[2];
145 auto b3 = coeffs[3];
146 auto a1 = coeffs[4];
147 auto a2 = coeffs[5];
148 auto a3 = coeffs[6];
149
150 auto lv1 = state[0];
151 auto lv2 = state[1];
152 auto lv3 = state[2];
153
154 for (size_t i = 0; i < numSamples; ++i)
155 {
156 auto input = src[i];
157 auto output = (input * b0) + lv1;
158 dst[i] = bypassed ? input : output;
159
160 lv1 = (input * b1) - (output* a1) + lv2;
161 lv2 = (input * b2) - (output* a2) + lv3;
162 lv3 = (input * b3) - (output* a3);
163 }
164
165 util::snapToZero (lv1); state[0] = lv1;
166 util::snapToZero (lv2); state[1] = lv2;
167 util::snapToZero (lv3); state[2] = lv3;
168 }
169 break;
170
171 default:
172 {
173 for (size_t i = 0; i < numSamples; ++i)
174 {
175 auto input = src[i];
176 auto output= (input * coeffs[0]) + state[0];
177 dst[i] = bypassed ? input : output;
178
179 for (size_t j = 0; j < order - 1; ++j)
180 state[j] = (input * coeffs[j + 1]) - (output* coeffs[order + j + 1]) + state[j + 1];
181
182 state[order - 1] = (input * coeffs[order]) - (output* coeffs[order * 2]);
183 }
184
185 snapToZero();
186 }
187 }
188}
189
190template <typename SampleType>
192{
193 check();
194 auto* c = coefficients->getRawCoefficients();
195
196 auto output= (c[0] * sample) + state[0];
197
198 for (size_t j = 0; j < order - 1; ++j)
199 state[j] = (c[j + 1] * sample) - (c[order + j + 1] * output) + state[j + 1];
200
201 state[order - 1] = (c[order] * sample) - (c[order * 2] * output);
202
203 return output;
204}
205
206template <typename SampleType>
208{
209 for (size_t i = 0; i < order; ++i)
210 util::snapToZero (state[i]);
211}
212
213template <typename SampleType>
215{
216 jassert (coefficients != nullptr);
217
218 if (order != coefficients->getFilterOrder())
219 reset();
220}
221
222#endif
223
224} // namespace IIR
225} // namespace dsp
226} // namespace juce
void prepare(const ProcessSpec &) noexcept
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
typename Coefficients< NumericType >::Ptr CoefficientsPtr
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType