Arduino Filters master
Filter library for Arduino
IIRFilter.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <AH/STL/type_traits>
6
9
26template <uint8_t NB, uint8_t NA, class T>
28 public:
45 NonNormalizingIIRFilter(const AH::Array<T, NB> &b_coefficients,
46 const AH::Array<T, NA> &a_coefficients)
47 : a0(a_coefficients[0]) {
48 for (uint8_t i = 0; i < 2 * NB - 1; ++i)
49 this->b_coefficients[i] = b_coefficients[(2 * NB - 1 - i) % NB];
50 for (uint8_t i = 0; i < 2 * MA - 1; ++i)
51 this->a_coefficients[i] = a_coefficients[(2 * MA - 2 - i) % MA + 1];
52 }
53
55 : NonNormalizingIIRFilter{tf.b, tf.a} {}
56
65 T operator()(T input) {
66 // Save the new input to the ring buffer.
67 x[index_b] = input;
68
69 // Calculate the offset to the shifted coefficients.
70 T *b_coeff_shift = b_coefficients.end() - NB - index_b;
71 T *a_coeff_shift = a_coefficients.end() - MA - index_a;
72
73 // Multiply and accumulate the inputs and their respective coefficients.
74 T acc = {};
75 for (uint8_t i = 0; i < NB; i++)
76 acc += x[i] * b_coeff_shift[i];
77
78 // Multiply and accumulate the inputs and their respective coefficients.
79 for (uint8_t i = 0; i < MA; i++)
80 acc -= y[i] * a_coeff_shift[i];
81
82 // Save the current output
83 acc /= a0;
84 y[index_a] = acc;
85
86 // Increment and wrap around the index of the ring buffer.
87 index_b++;
88 if (index_b == NB)
89 index_b = 0;
90
91 index_a++;
92 if (index_a == MA)
93 index_a = 0;
94
95 return acc;
96 }
97
98 private:
99 constexpr static uint8_t MA = NA - 1;
100 uint8_t index_b = 0, index_a = 0;
101 AH::Array<T, NB> x = {};
102 AH::Array<T, MA> y = {};
103 AH::Array<T, 2 * NB - 1> b_coefficients;
104 AH::Array<T, 2 * MA - 1> a_coefficients;
105 T a0;
106};
107
126template <uint8_t NB, uint8_t NA, class T>
128 public:
145 NormalizingIIRFilter(const AH::Array<T, NB> &b_coefficients,
146 const AH::Array<T, NA> &a_coefficients) {
147 T a0 = a_coefficients[0];
148 for (uint8_t i = 0; i < 2 * NB - 1; ++i)
149 this->b_coefficients[i] =
150 b_coefficients[(2 * NB - 1 - i) % NB] / a0;
151 for (uint8_t i = 0; i < 2 * MA - 1; ++i)
152 this->a_coefficients[i] =
153 a_coefficients[(2 * MA - 2 - i) % MA + 1] / a0;
154 }
155
157 : NormalizingIIRFilter{tf.b, tf.a} {}
158
167 T operator()(T input) {
168 // Save the new input to the ring buffer.
169 x[index_b] = input;
170
171 // Calculate the offset to the shifted coefficients.
172 T *b_coeff_shift = b_coefficients.end() - NB - index_b;
173 T *a_coeff_shift = a_coefficients.end() - MA - index_a;
174
175 // Multiply and accumulate the inputs and their respective coefficients.
176 T acc = {};
177 for (uint8_t i = 0; i < NB; i++)
178 acc += x[i] * b_coeff_shift[i];
179
180 // Multiply and accumulate the inputs and their respective coefficients.
181 for (uint8_t i = 0; i < MA; i++)
182 acc -= y[i] * a_coeff_shift[i];
183
184 // Save the current output
185 y[index_a] = acc;
186
187 // Increment and wrap around the index of the ring buffer.
188 index_b++;
189 if (index_b == NB)
190 index_b = 0;
191
192 index_a++;
193 if (index_a == MA)
194 index_a = 0;
195
196 return acc;
197 }
198
199 private:
200 constexpr static uint8_t MA = NA - 1;
201 uint8_t index_b = 0, index_a = 0;
202 AH::Array<T, NB> x = {};
203 AH::Array<T, MA> y = {};
204 AH::Array<T, 2 * NB - 1> b_coefficients;
205 AH::Array<T, 2 * MA - 1> a_coefficients;
206};
207
209
212template <uint8_t NB, uint8_t NA, class T>
214 typename std::conditional<std::is_floating_point<T>::value,
217
220
235template <uint8_t NB, uint8_t NA = NB, class T = float>
236class IIRFilter : public IIRImplementation<NB, NA, T> {
237 public:
254 IIRFilter(const AH::Array<T, NB> &b_coefficients,
255 const AH::Array<T, NA> &a_coefficients)
256 : IIRImplementation<NB, NA, T>{b_coefficients, a_coefficients} {}
257
259 : IIRImplementation<NB, NA, T>{tf} {}
260
269 T operator()(T input) {
271 }
272};
273
275template <size_t NB, size_t NA, class T = float>
277 return tf;
278}
279
281template <size_t NB, size_t NA, class T = float>
282IIRFilter<NB, NA, T> makeIIRFilter(const AH::Array<T, NB> &b_coefficients,
283 const AH::Array<T, NA> &a_coefficients) {
284 return {b_coefficients, a_coefficients};
285}
286
287
typename std::conditional< std::is_floating_point< T >::value, NormalizingIIRFilter< NB, NA, T >, NonNormalizingIIRFilter< NB, NA, T > >::type IIRImplementation
Select the NormalizingIIRFilter implementation if T is a floating point type, NonNormalizingIIRFilter...
Definition: IIRFilter.hpp:216
Generic Infinite Impulse Response filter class.
Definition: IIRFilter.hpp:236
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: IIRFilter.hpp:269
IIRFilter(const AH::Array< T, NB > &b_coefficients, const AH::Array< T, NA > &a_coefficients)
Construct a new IIR Filter object.
Definition: IIRFilter.hpp:254
IIRFilter(const TransferFunction< NB, NA, T > &tf)
Definition: IIRFilter.hpp:258
Infinite Impulse Response filter implementation that does not normalize the coefficients upon initial...
Definition: IIRFilter.hpp:27
AH::Array< T, 2 *NB - 1 > b_coefficients
Numerator coefficients.
Definition: IIRFilter.hpp:103
AH::Array< T, NB > x
Previous inputs.
Definition: IIRFilter.hpp:101
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: IIRFilter.hpp:65
NonNormalizingIIRFilter(const TransferFunction< NB, NA, T > &tf)
Definition: IIRFilter.hpp:54
AH::Array< T, MA > y
Previous outputs.
Definition: IIRFilter.hpp:102
static constexpr uint8_t MA
Definition: IIRFilter.hpp:99
NonNormalizingIIRFilter(const AH::Array< T, NB > &b_coefficients, const AH::Array< T, NA > &a_coefficients)
Construct a new Non-Normalizing IIR Filter object.
Definition: IIRFilter.hpp:45
AH::Array< T, 2 *MA - 1 > a_coefficients
Denominator coefficients.
Definition: IIRFilter.hpp:104
Infinite Impulse Response filter implementation that normalizes the coefficients upon initialization.
Definition: IIRFilter.hpp:127
NormalizingIIRFilter(const AH::Array< T, NB > &b_coefficients, const AH::Array< T, NA > &a_coefficients)
Construct a new Normalizing IIR Filter object.
Definition: IIRFilter.hpp:145
AH::Array< T, 2 *NB - 1 > b_coefficients
Definition: IIRFilter.hpp:204
AH::Array< T, NB > x
Definition: IIRFilter.hpp:202
T operator()(T input)
Update the internal state with the new input and return the new output .
Definition: IIRFilter.hpp:167
AH::Array< T, MA > y
Definition: IIRFilter.hpp:203
static constexpr uint8_t MA
Definition: IIRFilter.hpp:200
NormalizingIIRFilter(const TransferFunction< NB, NA, T > &tf)
Definition: IIRFilter.hpp:156
AH::Array< T, 2 *MA - 1 > a_coefficients
Definition: IIRFilter.hpp:205
IIRFilter< NB, NA, T > makeIIRFilter(const TransferFunction< NB, NA, T > &tf)
Create an IIRFilter from the given transfer function.
Definition: IIRFilter.hpp:276
Class for transfer function coefficients.