VCV Rack API v2
Loading...
Searching...
No Matches
ringbuffer.hpp
Go to the documentation of this file.
1#pragma once
2#include <atomic>
3
4#include <dsp/common.hpp>
5
6
7namespace rack {
8namespace dsp {
9
10
17template <typename T, size_t S>
18struct RingBuffer {
19 std::atomic<size_t> start{0};
20 std::atomic<size_t> end{0};
21 T data[S];
22
25 void push(T t) {
26 size_t i = end % S;
27 data[i] = t;
28 end++;
29 }
33 void pushBuffer(const T* t, int n) {
34 size_t i = end % S;
35 size_t e1 = i + n;
36 size_t e2 = (e1 < S) ? e1 : S;
37 std::memcpy(&data[i], t, sizeof(T) * (e2 - i));
38 if (e1 > S) {
39 std::memcpy(data, &t[S - i], sizeof(T) * (e1 - S));
40 }
41 end += n;
42 }
45 T shift() {
46 size_t i = start % S;
47 T t = data[i];
48 start++;
49 return t;
50 }
54 void shiftBuffer(T* t, size_t n) {
55 size_t i = start % S;
56 size_t s1 = i + n;
57 size_t s2 = (s1 < S) ? s1 : S;
58 std::memcpy(t, &data[i], sizeof(T) * (s2 - i));
59 if (s1 > S) {
60 std::memcpy(&t[S - i], data, sizeof(T) * (s1 - S));
61 }
62 start += n;
63 }
64 void clear() {
65 start = end.load();
66 }
67 bool empty() const {
68 return start >= end;
69 }
70 bool full() const {
71 return end - start >= S;
72 }
73 size_t size() const {
74 return end - start;
75 }
76 size_t capacity() const {
77 return S - size();
78 }
79};
80
84template <typename T, size_t S>
86 std::atomic<size_t> start{0};
87 std::atomic<size_t> end{0};
88 T data[2 * S];
89
90 void push(T t) {
91 size_t i = end % S;
92 data[i] = t;
93 data[i + S] = t;
94 end++;
95 }
96 T shift() {
97 size_t i = start % S;
98 T t = data[i];
99 start++;
100 return t;
101 }
102 void clear() {
103 start = end.load();
104 }
105 bool empty() const {
106 return start >= end;
107 }
108 bool full() const {
109 return end - start >= S;
110 }
111 size_t size() const {
112 return end - start;
113 }
114 size_t capacity() const {
115 return S - size();
116 }
121 T* endData() {
122 size_t i = end % S;
123 return &data[i];
124 }
125 void endIncr(size_t n) {
126 size_t i = end % S;
127 size_t e1 = i + n;
128 size_t e2 = (e1 < S) ? e1 : S;
129 // Copy data forward
130 std::memcpy(&data[S + i], &data[i], sizeof(T) * (e2 - i));
131
132 if (e1 > S) {
133 // Copy data backward from the doubled block to the main block
134 std::memcpy(data, &data[S], sizeof(T) * (e1 - S));
135 }
136 end += n;
137 }
141 const T* startData() const {
142 size_t i = start % S;
143 return &data[i];
144 }
145 void startIncr(size_t n) {
146 start += n;
147 }
148};
149
157template <typename T, size_t S, size_t N>
159 size_t start = 0;
160 size_t end = 0;
161 T data[N];
162
164 // move end block to beginning
165 // may overlap, but memmove handles that correctly
166 size_t s = size();
167 std::memmove(data, &data[start], sizeof(T) * s);
168 start = 0;
169 end = s;
170 }
171 void push(T t) {
172 if (end + 1 > N) {
173 returnBuffer();
174 }
175 data[end++] = t;
176 }
177 T shift() {
178 return data[start++];
179 }
180 bool empty() const {
181 return start == end;
182 }
183 bool full() const {
184 return end - start == S;
185 }
186 size_t size() const {
187 return end - start;
188 }
189 size_t capacity() const {
190 return S - size();
191 }
194 T* endData(size_t n) {
195 if (end + n > N) {
196 returnBuffer();
197 }
198 return &data[end];
199 }
203 void endIncr(size_t n) {
204 end += n;
205 }
209 const T* startData() const {
210 return &data[start];
211 }
212 void startIncr(size_t n) {
213 // This is valid as long as n < S
214 start += n;
215 }
216};
217
218
219} // namespace dsp
220} // namespace rack
Root namespace for the Rack API.
Definition AudioDisplay.hpp:9
A cyclic buffer which maintains a valid linear array of size S by sliding along a larger block of siz...
Definition ringbuffer.hpp:158
T data[N]
Definition ringbuffer.hpp:161
void endIncr(size_t n)
Actually increments the end position Must be called after endData(), and n must be at most the n pass...
Definition ringbuffer.hpp:203
size_t end
Definition ringbuffer.hpp:160
T shift()
Definition ringbuffer.hpp:177
const T * startData() const
Returns a pointer to S consecutive elements for consumption If any data is consumed,...
Definition ringbuffer.hpp:209
void push(T t)
Definition ringbuffer.hpp:171
void startIncr(size_t n)
Definition ringbuffer.hpp:212
bool empty() const
Definition ringbuffer.hpp:180
size_t size() const
Definition ringbuffer.hpp:186
size_t capacity() const
Definition ringbuffer.hpp:189
T * endData(size_t n)
Returns a pointer to S consecutive elements for appending, requesting to append n elements.
Definition ringbuffer.hpp:194
size_t start
Definition ringbuffer.hpp:159
void returnBuffer()
Definition ringbuffer.hpp:163
bool full() const
Definition ringbuffer.hpp:183
A cyclic buffer which maintains a valid linear array of size S by keeping a copy of the buffer in adj...
Definition ringbuffer.hpp:85
void clear()
Definition ringbuffer.hpp:102
void endIncr(size_t n)
Definition ringbuffer.hpp:125
T shift()
Definition ringbuffer.hpp:96
std::atomic< size_t > start
Definition ringbuffer.hpp:86
size_t size() const
Definition ringbuffer.hpp:111
const T * startData() const
Returns a pointer to S consecutive elements for consumption If any data is consumed,...
Definition ringbuffer.hpp:141
T data[2 *S]
Definition ringbuffer.hpp:88
bool full() const
Definition ringbuffer.hpp:108
void startIncr(size_t n)
Definition ringbuffer.hpp:145
void push(T t)
Definition ringbuffer.hpp:90
size_t capacity() const
Definition ringbuffer.hpp:114
T * endData()
Returns a pointer to S consecutive elements for appending.
Definition ringbuffer.hpp:121
std::atomic< size_t > end
Definition ringbuffer.hpp:87
bool empty() const
Definition ringbuffer.hpp:105
Lock-free queue with fixed size and no allocations.
Definition ringbuffer.hpp:18
std::atomic< size_t > start
Definition ringbuffer.hpp:19
size_t size() const
Definition ringbuffer.hpp:73
void pushBuffer(const T *t, int n)
Copies an array to the end of the buffer.
Definition ringbuffer.hpp:33
T data[S]
Definition ringbuffer.hpp:21
size_t capacity() const
Definition ringbuffer.hpp:76
bool empty() const
Definition ringbuffer.hpp:67
void push(T t)
Adds an element to the end of the buffer.
Definition ringbuffer.hpp:25
void shiftBuffer(T *t, size_t n)
Removes and copies an array from the start of the buffer.
Definition ringbuffer.hpp:54
bool full() const
Definition ringbuffer.hpp:70
void clear()
Definition ringbuffer.hpp:64
std::atomic< size_t > end
Definition ringbuffer.hpp:20
T shift()
Removes and returns an element from the start of the buffer.
Definition ringbuffer.hpp:45