Skip to content

Commit ff7b782

Browse files
committed
Modified CircularBuffer to have the buffer size as a template
parameter hence allowing for differently sized bufers to be used (for instance with audio input)
1 parent 3d6c5ea commit ff7b782

1 file changed

Lines changed: 91 additions & 49 deletions

File tree

CircularBuffer.h

Lines changed: 91 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,13 @@ April 2025: modified for different buffer sizes under the suggestion
1919
of 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>
5229
class CircularBuffer
5330
{
5431

@@ -93,33 +70,26 @@ class CircularBuffer
9370
}
9471

9572
private:
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

Comments
 (0)