Mozzi  version v1.1.0 sound synthesis library for Arduino
RollingAverage.h
1 #ifndef ROLLINGAVERAGE_H
2 #define ROLLINGAVERAGE_H
3
4 /*
5  * RollingAverage.h
6  *
7  * Copyright 2013 Tim Barrass.
8  *
9  * This file is part of Mozzi.
10  *
12  *
13  */
14 /*
15  Draws on Arduino Smoothing example,
16  Created 22 April 2007
17  By David A. Mellis <dam@mellis.org>
18  modified 9 Apr 2012
19  by Tom Igoe
20  http://www.arduino.cc/en/Tutorial/Smoothing
21 */
22
23 #include "mozzi_utils.h" // for trailingZeros()
24
25
26 /** @ingroup sensortools
27  Calculates a running average over a
28  specified number of the most recent readings.
29  Like Smooth(), this is good for smoothing analog inputs in updateControl().
30  @tparam WINDOW_LENGTH the number of readings to include in the rolling average.
31  It must be a power of two (unless you're averaging floats). The higher the
32  number, the more the readings will be smoothed, but the slower the output
33  will respond to the input.
34 */
35
36 template <class T, int WINDOW_LENGTH>
37 class
39
40 public:
41
42  /** Constructor.
43  @tparam T the type of numbers to average, eg. int, unsigned int, float etc. It will be relatively slow with
44  floating point numbers, as it will use a divide operation for the averaging.
45  Nevertheless, there might be a time when it's useful.
46  @tparam WINDOW_LENGTH the number of readings to keep track of. It must be a power of two (unless
47  you're averaging floats). The higher the number, the more the readings will be
48  smoothed, but the slower the output will respond to the input.
49  @note Watch out for overflows!
50  */
52  {
53  // initialize all the readings to 0:
56  }
57
58
59  /** Give the average of the last WINDOW_LENGTH.
60  @param input a control signal such as an analog input which needs smoothing.
61  @return the smoothed result.
62  @note unsigned int timing 5.7us
63  */
64  T next(T input)
65  {
67  }
68
69
70 protected:
71
72  inline
74  // out with the old
76  // in with the new
77  total += input;
79
80  // advance and wrap index
81  ++index &= WINDOW_LENGTH -1;
83  }
84
85
86 private:
88  unsigned int index; // the index of the current reading
89  long total; // the running total
90  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
91
92 };
93
94 // no need to show the specialisations
95 /** @cond */
96
97 /** unsigned int partial specialisation of RollingAverage template.
98 This is needed because unsigned types need to remind (unsigned) for rshift.
99 */
100 template <int WINDOW_LENGTH>
101 class RollingAverage <unsigned int, WINDOW_LENGTH>
102 {
103 public:
104  /** Constructor.
105  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
106  The higher the number, the more the readings will be smoothed, but the slower the output will
107  respond to the input.
108  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
109  However, watch out for overflows if you are averaging a long number types!
110  */
111  RollingAverage():index(0),total(0), WINDOW_LENGTH_AS_RSHIFT(trailingZerosConst(WINDOW_LENGTH))
112  {
113  // initialize all the readings to 0:
116  }
117
118  /** Give the average of the last WINDOW_LENGTH.
119  @param a control signal such as an analog input which needs smoothing.
120  @return the smoothed result.
121  @note timing for int 6us
122  */
123  unsigned int next(unsigned int input)
124  {
125  // calculate the average:
126  // this unsigned cast is the only difference between the int and unsigned int specialisations
127  // it tells the shift not to sign extend in from the left
129  }
130
131 protected:
132
133
134  inline
135  unsigned int add(unsigned int input){
136  // out with the old
138  // in with the new
139  total += input;
141
142  // advance and wrap index
143  ++index &= WINDOW_LENGTH -1;
145  }
146
147
148 private:
150  unsigned int index; // the index of the current reading
151  long total; // the running total
152  const uint8_t WINDOW_LENGTH_AS_RSHIFT;
153
154 };
155
156
157
158 /** float partial specialisation of RollingAverage template*/
159 template <int WINDOW_LENGTH>
160 class RollingAverage <float, WINDOW_LENGTH>
161 {
162 public:
163  /** Constructor.
164  @tparam WINDOW_LENGTH A power of two, the number of readings to keep track of.
165  The higher the number, the more the readings will be smoothed, but the slower the output will
166  respond to the input.
167  @note The internal total of all the values being averaged is held in a long (4 uint8_t) integer, to avoid overflowing.
168  However, watch out for overflows if you are averaging a long number types!
169  */
170  RollingAverage():index(0),total(0.0)
171  {
172  // initialize all the readings to 0:
175  }
176
177  /** Give the average of the last WINDOW_LENGTH.
178  @param a control signal such as an analog input which needs smoothing.
179  @return the smoothed result.
180  @note timing for float 37us
181  */
182  float next(float input)
183  {
184  // out with the old
186  // in with the new
187  total += input;
189
190  // advance and wrap index
191  ++index &= WINDOW_LENGTH -1;
192
193  // calculate the average:
195  }
196
197 private:
199  unsigned int index; // the index of the current reading
200  float total; // the running total
201
202 };
203
204
205 // no need to show the specialisations
206 /** @endcond
207 */
208
209 /**
210 @example 03.Sensors/Knob_LDR_x2_WavePacket/Knob_LDR_x2_WavePacket.ino
211 This example demonstrates the RollingAverage class.
212 */
213
214 #endif // #ifndef ROLLINGAVERAGE_H
Calculates a running average over a specified number of the most recent readings. ...
T next(T input)
Give the average of the last WINDOW_LENGTH.
RollingAverage()
Constructor.