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