31template <
typename NumericType>
35 static_assert (
Num % 2 == 0,
"Must supply an even number of coefficients");
42 coefficients.clearQuick();
43 coefficients.ensureStorageAllocated ((
int)
jmax ((
size_t) 8,
Num));
45 for (
size_t i = 0; i <
Num; ++i)
47 coefficients.add (values[i] *
a0Inv);
53template <
typename SampleType>
60template <
typename SampleType>
61Filter<SampleType>::Filter (CoefficientsPtr c) : coefficients (
std::
move (c))
66template <
typename SampleType>
67void Filter<SampleType>::reset (SampleType resetToValue)
69 auto newOrder = coefficients->getFilterOrder();
71 if (newOrder != order)
73 memory.malloc (jmax (order, newOrder,
static_cast<size_t> (3)) + 1);
78 for (
size_t i = 0; i < order; ++i)
79 state[i] = resetToValue;
82template <
typename SampleType>
83void Filter<SampleType>::prepare (
const ProcessSpec&)
noexcept { reset(); }
85template <
typename SampleType>
86template <
typename ProcessContext,
bool bypassed>
87void Filter<SampleType>::processInternal (
const ProcessContext& context)
noexcept
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");
93 auto&& inputBlock = context.getInputBlock();
94 auto&& outputBlock = context.getOutputBlock();
98 jassert (inputBlock.getNumChannels() == 1);
99 jassert (outputBlock.getNumChannels() == 1);
101 auto numSamples = inputBlock.getNumSamples();
102 auto* src = inputBlock .getChannelPointer (0);
103 auto* dst = outputBlock.getChannelPointer (0);
104 auto* coeffs = coefficients->getRawCoefficients();
116 for (
size_t i = 0; i < numSamples; ++i)
119 auto output = input * b0 + lv1;
121 dst[i] = bypassed ? input : output;
123 lv1 = (input * b1) - (output * a1);
126 util::snapToZero (lv1); state[0] = lv1;
141 for (
size_t i = 0; i < numSamples; ++i)
144 auto output = (input * b0) + lv1;
145 dst[i] = bypassed ? input : output;
147 lv1 = (input * b1) - (output* a1) + lv2;
148 lv2 = (input * b2) - (output* a2);
151 util::snapToZero (lv1); state[0] = lv1;
152 util::snapToZero (lv2); state[1] = lv2;
170 for (
size_t i = 0; i < numSamples; ++i)
173 auto output = (input * b0) + lv1;
174 dst[i] = bypassed ? input : output;
176 lv1 = (input * b1) - (output* a1) + lv2;
177 lv2 = (input * b2) - (output* a2) + lv3;
178 lv3 = (input * b3) - (output* a3);
181 util::snapToZero (lv1); state[0] = lv1;
182 util::snapToZero (lv2); state[1] = lv2;
183 util::snapToZero (lv3); state[2] = lv3;
189 for (
size_t i = 0; i < numSamples; ++i)
192 auto output= (input * coeffs[0]) + state[0];
193 dst[i] = bypassed ? input : output;
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];
198 state[order - 1] = (input * coeffs[order]) - (output* coeffs[order * 2]);
206template <
typename SampleType>
207SampleType JUCE_VECTOR_CALLTYPE Filter<SampleType>::processSample (SampleType sample)
noexcept
210 auto* c = coefficients->getRawCoefficients();
212 auto output = (c[0] *
sample) + state[0];
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];
217 state[order - 1] = (c[order] *
sample) - (c[order * 2] * output);
222template <
typename SampleType>
223void Filter<SampleType>::snapToZero() noexcept
225 for (
size_t i = 0; i < order; ++i)
226 util::snapToZero (state[i]);
229template <
typename SampleType>
230void Filter<SampleType>::check()
232 jassert (coefficients !=
nullptr);
234 if (order != coefficients->getFilterOrder())
Filter()
Creates a filter.
Classes for IIR filter processing.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Type * snapPointerToAlignment(Type *basePointer, IntegerType alignmentBytes) noexcept
A handy function to round up a pointer to the nearest multiple of a given number of bytes.