Control Surface master
MIDI Control Surface library for Arduino
EMA.hpp
Go to the documentation of this file.
1/* ✔ */
2
3#pragma once
4
6AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
7
8#include <stdint.h>
9#include <AH/STL/limits>
10#include <AH/STL/type_traits>
11
55template <uint8_t K,
56 class input_t = uint_fast16_t,
57 class state_t = typename std::make_unsigned<input_t>::type>
58class EMA {
59 public:
61 EMA(input_t initial = input_t(0))
62 : state(zero + (state_t(initial) << K) - initial) {}
63
70 void reset(input_t value = input_t(0)) {
71 state = zero + (state_t(value) << K) - value;
72 }
73
81 input_t filter(input_t input) {
82 state += state_t(input);
83 state_t output = (state + half) >> K;
84 output -= zero >> K;
85 state -= output;
86 return input_t(output);
87 }
88
90 input_t operator()(input_t input) {
91 return filter(input);
92 }
93
94 constexpr static state_t
97 zero = std::is_unsigned<input_t>::value ? state_t(0) : half_state,
98 half = K > 0 ? state_t(1) << (K - 1) : state_t(0);
99
100 static_assert(std::is_unsigned<state_t>::value,
101 "state type should be unsigned");
102
104 "state type cannot be narrower than input type");
105
120 template <class T>
121 constexpr static bool supports_range(T min, T max) {
122 using sstate_t = typename std::make_signed<state_t>::type;
123 return min <= max &&
126 (std::is_unsigned<input_t>::value
127 ? state_t(max) <= (max_state >> K)
128 : min >= -sstate_t(max_state >> (K + 1)) - 1 &&
129 max <= sstate_t(max_state >> (K + 1)));
130 }
131
132 private:
133 state_t state;
134};
135
136// -------------------------------------------------------------------------- //
137
152class EMA_f {
153 public:
164 EMA_f(float pole) : alpha(1 - pole) {}
165
173 float filter(float value) {
174 filtered += (value - filtered) * alpha;
175 return filtered;
176 }
177
179 float operator()(float value) { return filter(value); }
180
181 private:
182 float alpha;
183 float filtered = 0;
184};
185
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:36
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
A class for single-pole infinite impulse response filters or exponential moving average filters.
Definition: EMA.hpp:152
float operator()(float value)
Filter the input: Given , calculate .
Definition: EMA.hpp:179
float filter(float value)
Filter the input: Given , calculate .
Definition: EMA.hpp:173
float alpha
Definition: EMA.hpp:182
EMA_f(float pole)
Create an exponential moving average filter with a pole at the given location.
Definition: EMA.hpp:164
float filtered
Definition: EMA.hpp:183
Exponential moving average filter.
Definition: EMA.hpp:58
constexpr static state_t max_state
Definition: EMA.hpp:95
constexpr static bool supports_range(T min, T max)
Verify the input range to make sure it's compatible with the shift factor and the width of the state ...
Definition: EMA.hpp:121
void reset(input_t value=input_t(0))
Reset the filter to the given value.
Definition: EMA.hpp:70
state_t state
Definition: EMA.hpp:133
input_t filter(input_t input)
Filter the input: Given , calculate .
Definition: EMA.hpp:81
constexpr static state_t half
Definition: EMA.hpp:98
EMA(input_t initial=input_t(0))
Constructor: initialize filter to zero or optional given value.
Definition: EMA.hpp:61
constexpr static state_t zero
Definition: EMA.hpp:97
input_t operator()(input_t input)
Filter the input: Given , calculate .
Definition: EMA.hpp:90
constexpr static state_t half_state
Definition: EMA.hpp:96
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Return the smaller of two numbers/objects.
Definition: MinMaxFix.hpp:15
constexpr auto max(const T &a, const U &b) -> decltype(a< b ? b :a)
Return the larger of two numbers/objects.
Definition: MinMaxFix.hpp:22