Mozzi  version v2.0
sound synthesis library for Arduino
OverSample.h
1 /*
2  * OverSample.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2013-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 OVERSAMPLE_H
13 #define OVERSAMPLE_H
14 
15 #include "RollingAverage.h"
16 
17 
18 /** @ingroup sensortools
19  Enables the resolution of analog inputs to be increased by oversampling and decimation.
20  Noise should be added to the input before it's digitised, then a succession of input readings are summed and
21  finally divided to give a number with greater resolution than the ADC.
22  Often, noise in the Arduino system will be enough, but there are other practical methods described in
23  [Enhancing ADC Resolution by Oversampling](http://www.atmel.com/images/doc8003.pdf‎),
24  as well as an explanation of the overall approach.
25  @tparam RESOLUTION_INCREASE_BITS how many extra bits of resolution to produce.
26  The window length and the memory it needs increases quickly as the oversampling resolution increases.
27  1 bit = 4 unsigned ints (analog input between 0-1023) = 8 uint8_ts,
28  2 bits = 16 unsigned ints = 32 uint8_ts,
29  3 bits = 64 unsigned ints = 128 uint8_ts,
30  More than 3 bits increase in resolution would require either using longs to store the readings,
31  which would need 1024 uint8_ts for a 4 bit increase and 4096 uint8_ts for 5 bits (do any avr's have that much room?),
32  or the average reading would have to be no more than 128 (for 4 bits increase), because 256 readings would be needed,
33  and the sum of all 256 readings would have to fit into an int. (32767 / 256 = 128).
34  Changing OverSample to use unsigned ints could enable an average reading of 256, but isn't tested properly yet.
35  @note The higher the resolution, the more lag there will be.
36  It's almost a RollingAverage filter, with the difference that
37  OverSample doesn't divide by as much as you would for an average.
38 */
39 
40 
41 template <class T, const uint8_t RESOLUTION_INCREASE_BITS>
42 class OverSample: public RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>
43 {
44 
45 public:
46  using RollingAverage<T, (1<<(RESOLUTION_INCREASE_BITS*2))>::add;
47 
48  /** Oversample and decimate the input to increase resolution by RESOLUTION_INCREASE_BITS;
49  @param input an analog input to oversample.
50  @return the higher resolution result.
51  @note timing 5.7us
52  */
53  T next(T input)
54  {
55  return add(input)>>RESOLUTION_INCREASE_BITS;
56  }
57 
58 };
59 
60 
61 /**
62 @example 05.Control_Filters/Thermistor_OverSample/Thermistor_OverSample.ino
63 This is an example demonstrating the OverSample class.
64 */
65 
66 #endif // #ifndef OVERSAMPLE_H