Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
EMA.hpp
Go to the documentation of this file.
1/* ✔ */
2
3#pragma once
4
5#include <stdint.h>
6#include <AH/STL/limits>
7#include <AH/STL/type_traits>
8
10
12
56template <uint8_t K,
57 class input_t = uint_fast16_t,
58 class state_t = typename std::make_unsigned<input_t>::type>
59class EMA {
60 public:
62 EMA(input_t initial = input_t{0}) { reset(initial); }
63
70 void reset(input_t value = input_t(0)) {
71 state_t value_s = static_cast<state_t>(value);
72 state = zero + (value_s << K) - value_s;
73 }
74
83 state += static_cast<state_t>(input);
84 state_t output = (state + half) >> K;
85 output -= zero >> K;
86 state -= output;
87 return static_cast<input_t>(output);
88 }
89
92 return filter(input);
93 }
94
95 constexpr static state_t
96 max_state = std::numeric_limits<state_t>::max(),
97 half_state = max_state / 2 + 1,
98 zero = std::is_unsigned<input_t>::value ? state_t{0} : half_state,
99 half = K > 0 ? state_t{1} << (K - 1) : state_t{0};
100
101 static_assert(std::is_unsigned<state_t>::value,
102 "state type should be unsigned");
103
104 static_assert(max_state >= std::numeric_limits<input_t>::max(),
105 "state type cannot be narrower than input type");
106
121 template <class T>
122 constexpr static bool supports_range(T min, T max) {
123 using sstate_t = typename std::make_signed<state_t>::type;
124 return min <= max &&
125 min >= std::numeric_limits<input_t>::min() &&
127 (std::is_unsigned<input_t>::value
128 ? state_t(max) <= (max_state >> K)
129 : min >= -static_cast<sstate_t>(max_state >> (K + 1)) - 1 &&
130 max <= static_cast<sstate_t>(max_state >> (K + 1)));
131 }
132
133 private:
135};
136
137// -------------------------------------------------------------------------- //
138
153class EMA_f {
154 public:
165 EMA_f(float pole) : alpha(1 - pole) {}
166
174 float filter(float value) {
175 filtered += (value - filtered) * alpha;
176 return filtered;
177 }
178
180 float operator()(float value) { return filter(value); }
181
182 private:
183 float alpha;
184 float filtered = 0;
185};
186
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
A class for single-pole infinite impulse response filters or exponential moving average filters.
Definition EMA.hpp:153
float operator()(float value)
Filter the input: Given , calculate .
Definition EMA.hpp:180
float filter(float value)
Filter the input: Given , calculate .
Definition EMA.hpp:174
float alpha
Definition EMA.hpp:183
EMA_f(float pole)
Create an exponential moving average filter with a pole at the given location.
Definition EMA.hpp:165
Exponential moving average filter.
Definition EMA.hpp:59
void reset(input_t value=input_t(0))
Reset the filter to the given value.
Definition EMA.hpp:70
static constexpr 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:122
state_t state
Definition EMA.hpp:134
input_t filter(input_t input)
Filter the input: Given , calculate .
Definition EMA.hpp:82
EMA(input_t initial=input_t{0})
Constructor: initialize filter to zero or optional given value.
Definition EMA.hpp:62
input_t operator()(input_t input)
Filter the input: Given , calculate .
Definition EMA.hpp:91
An array wrapper for easy copying, comparing, and iterating.
Definition Array.hpp:32