@@ -19,36 +19,13 @@ April 2025: modified for different buffer sizes under the suggestion
1919of Meebleeps (https://github.com/sensorium/Mozzi/issues/281)
2020*/
2121
22- // TODO: remove this define from here, put a default value in config
23- #define MOZZI_OUTPUT_BUFFER_SIZE 256
24-
25- // This is to get the correct cound for audioticks() (there might be a smarter way...)
26- #if (MOZZI_OUTPUT_BUFFER_SIZE == 256)
27- #define COUNT_LSHIFT 8
28- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 128)
29- #define COUNT_LSHIFT 7
30- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 64)
31- #define COUNT_LSHIFT 6
32- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 32)
33- #define COUNT_LSHIFT 5
34- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 16)
35- #define COUNT_LSHIFT 4
36- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 8)
37- #define COUNT_LSHIFT 3
38- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 4)
39- #define COUNT_LSHIFT 2
40- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 2)
41- #define COUNT_LSHIFT 1
42- #elif (MOZZI_OUTPUT_BUFFER_SIZE == 1)
43- #define COUNT_LSHIFT 0
44- #endif
45-
46-
47-
48- /* * Circular buffer object. Has a fixed number of cells, set to 256.
22+
23+
24+ /* * Circular buffer object. Has a fixed number of cells, set by BUFFER_SIZE.
4925@tparam ITEM_TYPE the kind of data to store, eg. int, int8_t etc.
26+ @tparam BUFFER_SIZE the size of the circular buffer
5027*/
51- template <class ITEM_TYPE >
28+ template <class ITEM_TYPE , int16_t BUFFER_SIZE >
5229class CircularBuffer
5330{
5431
@@ -93,33 +70,26 @@ class CircularBuffer
9370 }
9471
9572private:
96- ITEM_TYPE items[MOZZI_OUTPUT_BUFFER_SIZE ];
73+ ITEM_TYPE items[BUFFER_SIZE ];
9774 uint8_t start; /* index of oldest itement */
9875 uint8_t end; /* index at which to write new itement */
9976 uint8_t s_msb;
10077 uint8_t e_msb;
10178 unsigned long num_buffers_read;
79+ static constexpr unsigned long COUNT_LSHIFT =
80+ (BUFFER_SIZE == 256 ) ? 8 :
81+ (BUFFER_SIZE == 128 ) ? 7 :
82+ (BUFFER_SIZE == 64 ) ? 6 :
83+ (BUFFER_SIZE == 32 ) ? 5 :
84+ (BUFFER_SIZE == 16 ) ? 4 :
85+ (BUFFER_SIZE == 8 ) ? 3 :
86+ (BUFFER_SIZE == 4 ) ? 2 :
87+ (BUFFER_SIZE == 2 ) ? 1 : 0 ;
10288
103- #if (MOZZI_OUTPUT_BUFFER_SIZE == 256)
104- inline
105- void cbIncrStart () {
106- start++;
107- if (start == 0 ) {
108- s_msb ^= 1 ;
109- num_buffers_read++;
110- }
111- }
112-
113- inline
114- void cbIncrEnd () {
115- end++;
116- if (end == 0 ) e_msb ^= 1 ;
117- }
118- #else // if circular buffer length is != 256, use less efficient version for to manage start/end index buffer index
11989 inline
12090 void cbIncrStart () {
12191 start++;
122- if (start == MOZZI_OUTPUT_BUFFER_SIZE )
92+ if (start == BUFFER_SIZE )
12393 {
12494 start = 0 ;
12595 s_msb ^= 1 ;
@@ -131,16 +101,88 @@ class CircularBuffer
131101 void cbIncrEnd ()
132102 {
133103 end++;
134- if (end == MOZZI_OUTPUT_BUFFER_SIZE )
104+ if (end == BUFFER_SIZE )
135105 {
136106 end = 0 ;
137107 e_msb ^= 1 ;
138108 }
139109 }
140- #endif
141110
142111
143112};
144113
145114
146- #undef COUNT_LSHIFT // avoid macro spil
115+
116+ /* * Circular buffer object. Specialization for size of 256.
117+ Note: Lot of duplication but C++ does not allow for specialization of the
118+ function member only (partial specialization).
119+ @tparam ITEM_TYPE the kind of data to store, eg. int, int8_t etc.
120+ */
121+ template <class ITEM_TYPE >
122+ class CircularBuffer <ITEM_TYPE , 256 >
123+ {
124+ public:
125+ /* * Constructor
126+ */
127+ CircularBuffer (): start(0 ),end(0 ),s_msb(0 ),e_msb(0 )
128+ {
129+ }
130+
131+ inline
132+ bool isFull () {
133+ return end == start && e_msb != s_msb;
134+ }
135+
136+ inline
137+ bool isEmpty () {
138+ return end == start && e_msb == s_msb;
139+ }
140+
141+ inline
142+ void write (ITEM_TYPE in) {
143+ items[end] = in;
144+ // if (isFull()) cbIncrStart(); /* full, overwrite moves start pointer */
145+ cbIncrEnd ();
146+ }
147+
148+ inline
149+ ITEM_TYPE read () {
150+ ITEM_TYPE out = items[start];
151+ cbIncrStart ();
152+ return out;
153+ }
154+
155+ inline
156+ unsigned long count () {
157+ return (num_buffers_read << 8 ) + start;
158+ }
159+ inline
160+ ITEM_TYPE * address () {
161+ return items;
162+ }
163+
164+ private:
165+ ITEM_TYPE items[256 ];
166+ uint8_t start; /* index of oldest itement */
167+ uint8_t end; /* index at which to write new itement */
168+ uint8_t s_msb;
169+ uint8_t e_msb;
170+ unsigned long num_buffers_read;
171+
172+
173+ inline
174+ void cbIncrStart () {
175+ start++;
176+ if (start == 0 ) {
177+ s_msb ^= 1 ;
178+ num_buffers_read++;
179+ }
180+ }
181+
182+ inline
183+ void cbIncrEnd () {
184+ end++;
185+ if (end == 0 ) e_msb ^= 1 ;
186+ }
187+ };
188+
0 commit comments