Mozzi  version v2.0
sound synthesis library for Arduino
Smooth.h
1 /*
2  * Smooth.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
12 #ifndef SMOOTH_H_
13 #define SMOOTH_H_
14 
15 #include "Arduino.h"
16 #include "mozzi_fixmath.h"
17 
34 template <class T>
35 class Smooth
36 {
37 private:
38  long last_out;
39  Q0n16 a;
40 
41 public:
47  Smooth(float smoothness)
48  {
49  setSmoothness(smoothness);
50  }
51 
58  {}
59 
60 
65  inline
66  T next(T in)
67  {
68  long out = ((((((long)in - (last_out>>8)) * a))>>8) + last_out);
69  last_out = out;
70  return (T)(out>>8);
71  }
72 
73 
78  inline
79  T operator()(T n) {
80  return next(n);
81  }
82 
83 
89  inline
90  void setSmoothness(float smoothness)
91  {
92  a=float_to_Q0n16(1.f-smoothness);
93  }
94 
95 };
96 
97  // doxygen can ignore the specialisations
99 
101 template <>
102 class Smooth <uint8_t>
103 {
104 private:
105  unsigned int last_out;
106  Q0n8 a;
107 
108 public:
114  Smooth(float smoothness)
115  {
116  setSmoothness(smoothness);
117  }
118 
123  inline
124  uint8_t next(uint8_t in)
125  {
126  unsigned int out = (((((int)in - (last_out>>8)) * a)) + last_out);
127  last_out = out;
128  return (uint8_t)(out>>8);
129  }
130 
131 
136  inline
137  uint8_t operator()(uint8_t n) {
138  return next(n);
139  }
140 
141 
147  inline
148  void setSmoothness(float smoothness)
149  {
150  a=float_to_Q0n8(1.f-smoothness);
151  }
152 
153 };
154 
155 
157 template <>
158 class Smooth <int8_t>
159 {
160 private:
161  int last_out;
162  Q0n8 a;
163 
164 public:
170  Smooth(float smoothness)
171  {
172  setSmoothness(smoothness);
173  }
174 
175 
180  inline
181  int8_t next(int8_t in)
182  {
183  int out = (((((int)in - (last_out>>8)) * a)) + last_out);
184  last_out = out;
185  return (int8_t)(out>>8);
186  }
187 
188 
193  inline
194  int8_t operator()(int8_t n) {
195  return next(n);
196  }
197 
198 
204  inline
205  void setSmoothness(float smoothness)
206  {
207  a=float_to_Q0n8(1.f-smoothness);
208  }
209 
210 };
211 
213 template <>
214 class Smooth <float>
215 {
216 private:
217  float last_out;
218  float a;
219 
220 public:
226  Smooth(float smoothness)
227  {
228  setSmoothness(smoothness);
229  }
230 
235  inline
236  float next(float in)
237  {
238  float out = last_out + a * (in - last_out);
239  //float out = (in - last_out * a) + last_out;
240  last_out = out;
241  return out;
242  }
243 
244 
249  inline
250  float operator()(float n) {
251  return next(n);
252  }
253 
254 
260  inline
261  void setSmoothness(float smoothness)
262  {
263  a=1.f-smoothness;
264  }
265 
266 };
267 
268 
272 /* Specialization for UFix */
273 template<int8_t NI, int8_t NF>
274 class Smooth<UFix<NI,NF>>
275 {
276 private:
277  typedef UFix<NI, NF> internal_type;
278  internal_type last_out;
279  UFix<0,16> a;
280 
281 public:
282 
283 
289  template<typename T>
290  Smooth(T smoothness)
291  {
292  setSmoothness(smoothness);
293  }
294 
301  {}
302 
303 
308  inline
309  internal_type next(internal_type in)
310  {
311  internal_type out = last_out + a * (in - last_out); // With FixMath, the syntax is actually the same than with floats :)
312  last_out = out;
313  return out;
314  }
315 
316 
317 
318  inline
319  internal_type operator()(internal_type n) {
320  return next(n);
321  }
322 
328  inline
329  void setSmoothness(float smoothness)
330  {
331  a=internal_type(1.f-smoothness);
332  }
333 
339  template<int8_t _NF>
340  void setSmoothness(UFix<0,_NF> smoothness)
341  {
342  a = UFix<1,0>(1) - smoothness;
343  }
344 
345 };
346 
347 
348 
349 
350 /* Specialization for SFix */
351 template<int8_t NI, int8_t NF>
352 class Smooth<SFix<NI,NF>>
353 {
354 private:
355  typedef SFix<NI, NF> internal_type;
356  internal_type last_out;
357  UFix<0,16> a;
358 
359 public:
360 
361 
367  template<typename T>
368  Smooth(T smoothness)
369  {
370  setSmoothness(smoothness);
371  }
372 
379  {}
380 
381 
386  inline
387  internal_type next(internal_type in)
388  {
389  internal_type out = last_out + a * (in - last_out);
390  last_out = out;
391  return out;
392  }
393 
394 
395 
396  inline
397  internal_type operator()(internal_type n) {
398  return next(n);
399  }
400 
406  inline
407  void setSmoothness(float smoothness)
408  {
409  a=internal_type(1.f-smoothness);
410  }
411 
417  template<int8_t _NF>
418  void setSmoothness(UFix<0,_NF> smoothness)
419  {
420  a = UFix<1,0>(1) - smoothness;
421  }
422 
423 };
424 
430 #endif /* SMOOTH_H_ */
void setSmoothness(float smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:407
internal_type next(internal_type in)
Filters the input and returns the filtered value.
Definition: Smooth.h:387
void setSmoothness(UFix< 0, _NF > smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:418
Smooth(T smoothness)
Constructor.
Definition: Smooth.h:368
Smooth()
Constructor.
Definition: Smooth.h:378
void setSmoothness(UFix< 0, _NF > smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:340
internal_type next(internal_type in)
Filters the input and returns the filtered value.
Definition: Smooth.h:309
Smooth(T smoothness)
Constructor.
Definition: Smooth.h:290
void setSmoothness(float smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:329
Smooth()
Constructor.
Definition: Smooth.h:300
A simple infinite impulse response low pass filter for smoothing control or audio signals.
Definition: Smooth.h:36
T operator()(T n)
Filters the input and returns the filtered value.
Definition: Smooth.h:79
void setSmoothness(float smoothness)
Sets how much smoothing the filter will apply to its input.
Definition: Smooth.h:90
T next(T in)
Filters the input and returns the filtered value.
Definition: Smooth.h:66
Smooth(float smoothness)
Constructor.
Definition: Smooth.h:47
Smooth()
Constructor.
Definition: Smooth.h:57
Q0n8 float_to_Q0n8(float a)
Convert float to Q0n8 fix.
uint8_t Q0n8
unsigned fractional number using 8 fractional bits, represents 0.0 to 0.996
Definition: mozzi_fixmath.h:33
uint16_t Q0n16
unsigned fractional number using 16 fractional bits, represents 0.0 to 0.999
Definition: mozzi_fixmath.h:35
Q0n16 float_to_Q0n16(float a)
Convert float to Q0n16 fix.