OpenShot Library | OpenShotAudio  0.2.1
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 
31 namespace juce
32 {
33 namespace dsp
34 {
35 namespace IIR
36 {
37 
38 #ifndef DOXYGEN
39 
40 //==============================================================================
41 template <typename SampleType>
43  : coefficients (new Coefficients<typename Filter<SampleType>::NumericType> (1, 0, 1, 0))
44 {
45  reset();
46 }
47 
48 template <typename SampleType>
49 Filter<SampleType>::Filter (CoefficientsPtr c) : coefficients (std::move (c))
50 {
51  reset();
52 }
53 
54 template <typename SampleType>
55 void 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 
70 template <typename SampleType>
71 void Filter<SampleType>::prepare (const ProcessSpec&) noexcept { reset(); }
72 
73 template <typename SampleType>
74 template <typename ProcessContext, bool bypassed>
75 void 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 
194 template <typename SampleType>
195 SampleType 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 
210 template <typename SampleType>
211 void Filter<SampleType>::snapToZero() noexcept
212 {
213  for (size_t i = 0; i < order; ++i)
214  util::snapToZero (state[i]);
215 }
216 
217 template <typename SampleType>
218 void 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 /** @}*/
Array< NumericType > coefficients
The raw coefficients.
void reset()
Resets the filter&#39;s processing pipeline, ready to start a new stream of data.
STL namespace.
void prepare(const ProcessSpec &) noexcept
Called before processing starts.
void snapToZero() noexcept
Ensure that the state variables are rounded to zero if the state variables are denormals.
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
Processes a single sample, without any locking.
Filter()
Creates a filter.