OpenShot Audio Library | OpenShotAudio  0.3.0
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 
27 namespace juce
28 {
29 namespace dsp
30 {
31 namespace IIR
32 {
33 
34 #ifndef DOXYGEN
35 
36 //==============================================================================
37 template <typename SampleType>
39  : coefficients (new Coefficients<typename Filter<SampleType>::NumericType> (1, 0, 1, 0))
40 {
41  reset();
42 }
43 
44 template <typename SampleType>
46 {
47  reset();
48 }
49 
50 template <typename SampleType>
51 void Filter<SampleType>::reset (SampleType resetToValue)
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 
66 template <typename SampleType>
67 void Filter<SampleType>::prepare (const ProcessSpec&) noexcept { reset(); }
68 
69 template <typename SampleType>
70 template <typename ProcessContext, bool bypassed>
71 void 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 
190 template <typename SampleType>
191 SampleType JUCE_VECTOR_CALLTYPE Filter<SampleType>::processSample (SampleType sample) noexcept
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 
206 template <typename SampleType>
208 {
209  for (size_t i = 0; i < order; ++i)
210  util::snapToZero (state[i]);
211 }
212 
213 template <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 malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
ElementType * getData() const noexcept
Definition: juce_Uuid.h:140
typename Coefficients< NumericType >::Ptr CoefficientsPtr
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
void prepare(const ProcessSpec &) noexcept
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept