1use crate::buffer::Buffer;
2use crate::math::Transcendental;
3use std::fmt;
4
5#[repr(C, align(64))]
20pub struct RingBuffer<T: Transcendental, const N: usize> {
21 data: [T; N],
22 head: usize,
23 tail: usize,
24 mask: usize,
25 full: bool,
26}
27
28impl<T: Transcendental, const N: usize> RingBuffer<T, N> {
29 pub fn new() -> Self {
34 assert!(N.is_power_of_two(), "RingBuffer size must be power of two");
35 Self {
36 data: [T::ZERO; N],
37 head: 0,
38 tail: 0,
39 mask: N - 1,
40 full: false,
41 }
42 }
43
44 pub fn write(&mut self, sample: T) {
46 self.data[self.head] = sample;
47 let next_head = (self.head + 1) & self.mask;
48 self.head = next_head;
49 if next_head == self.tail {
50 self.full = true;
51 }
52 }
53
54 pub fn write_slice(&mut self, samples: &[T])
56 where
57 T: Copy,
58 {
59 for &sample in samples {
60 self.write(sample);
61 }
62 }
63
64 pub fn read(&mut self) -> Option<T> {
66 if self.tail == self.head && !self.full {
67 return None;
68 }
69 let sample = self.data[self.tail];
70 self.tail = (self.tail + 1) & self.mask;
71 self.full = false;
72 Some(sample)
73 }
74
75 pub fn read_delayed(&self, delay: usize) -> T {
80 assert!(delay < self.len(), "Delay must be less than buffer length");
81 let read_pos = (self.head + self.capacity() - delay - 1) & self.mask;
82 self.data[read_pos]
83 }
84
85 pub fn read_interpolated(&self, delay_frac: f32) -> T
87 where
88 T: From<f32> + Into<f32>,
89 {
90 let delay_int = delay_frac.floor() as usize;
91 let frac = delay_frac.fract();
92 if frac == 0.0 {
93 return self.read_delayed(delay_int);
94 }
95 let s1: f32 = self.read_delayed(delay_int).into();
96 let prev = if delay_int == 0 {
97 self.len() - 1
98 } else {
99 delay_int - 1
100 };
101 let s2: f32 = self.read_delayed(prev).into();
102 T::from(s1 * (1.0 - frac) + s2 * frac)
103 }
104
105 pub fn read_sequence_interpolated(&self, start_delay: f32, output: &mut [T])
108 where
109 T: From<f32> + Into<f32>,
110 {
111 let len = self.len();
112 for (i, out) in output.iter_mut().enumerate() {
113 let delay = start_delay + i as f32;
114 *out = if delay < len as f32 {
115 self.read_interpolated(delay)
116 } else {
117 T::ZERO
118 };
119 }
120 }
121
122 pub fn len(&self) -> usize {
124 if self.full {
125 N
126 } else if self.head >= self.tail {
127 self.head - self.tail
128 } else {
129 N - self.tail + self.head
130 }
131 }
132
133 pub const fn capacity(&self) -> usize {
135 N
136 }
137 pub fn is_empty(&self) -> bool {
139 self.head == self.tail && !self.full
140 }
141 pub fn is_full(&self) -> bool {
143 self.full
144 }
145
146 pub fn clear(&mut self) {
148 self.data.fill(T::ZERO);
149 self.head = 0;
150 self.tail = 0;
151 self.full = false;
152 }
153
154 pub fn reset(&mut self) {
156 self.head = 0;
157 self.tail = 0;
158 self.full = false;
159 }
160}
161
162impl<T: Transcendental, const N: usize> Default for RingBuffer<T, N> {
163 fn default() -> Self {
164 Self::new()
165 }
166}
167
168impl<T: Transcendental, const N: usize> Buffer<T> for RingBuffer<T, N> {
169 fn capacity(&self) -> usize {
170 N
171 }
172 fn len(&self) -> usize {
173 RingBuffer::len(self)
174 }
175 fn is_empty(&self) -> bool {
176 RingBuffer::is_empty(self)
177 }
178 fn is_full(&self) -> bool {
179 RingBuffer::is_full(self)
180 }
181 fn as_slice(&self) -> &[T] {
182 &self.data
183 }
184 fn as_mut_slice(&mut self) -> &mut [T] {
185 &mut self.data
186 }
187 fn fill(&mut self, value: T) {
188 self.data.fill(value);
189 }
190 fn copy_from(&mut self, src: &[T]) {
191 let len = src.len().min(N);
192 self.data[..len].copy_from_slice(&src[..len]);
193 }
194 fn clear(&mut self) {
195 RingBuffer::clear(self);
196 }
197}
198
199impl<T: Transcendental + fmt::Debug, const N: usize> fmt::Debug for RingBuffer<T, N> {
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 let mut preview = Vec::with_capacity(4);
202 for i in 0..4.min(N) {
203 preview.push(self.data[i]);
204 }
205 f.debug_struct("RingBuffer")
206 .field("head", &self.head)
207 .field("tail", &self.tail)
208 .field("full", &self.full)
209 .field("len", &self.len())
210 .field("capacity", &N)
211 .field("preview", &preview)
212 .finish()
213 }
214}
215
216pub struct RingBufferIter<'a, T: Transcendental, const N: usize> {
222 buffer: &'a RingBuffer<T, N>,
223 pos: usize,
224 end: usize,
225}
226
227impl<'a, T: Transcendental, const N: usize> RingBufferIter<'a, T, N> {
228 fn new(buffer: &'a RingBuffer<T, N>) -> Self {
229 let tail = buffer.tail;
230 let head = buffer.head;
231 let len = if buffer.full {
232 N
233 } else if head >= tail {
234 head - tail
235 } else {
236 N - tail + head
237 };
238 Self {
239 buffer,
240 pos: tail,
241 end: tail + len,
242 }
243 }
244}
245
246impl<'a, T: Transcendental, const N: usize> Iterator for RingBufferIter<'a, T, N> {
247 type Item = T;
248 fn next(&mut self) -> Option<Self::Item> {
249 if self.pos >= self.end {
250 None
251 } else {
252 let idx = self.pos & self.buffer.mask;
253 let value = self.buffer.data[idx];
254 self.pos += 1;
255 Some(value)
256 }
257 }
258}
259
260impl<'a, T: Transcendental, const N: usize> ExactSizeIterator for RingBufferIter<'a, T, N> {
261 fn len(&self) -> usize {
262 self.end - self.pos
263 }
264}
265
266impl<T: Transcendental, const N: usize> RingBuffer<T, N> {
267 pub fn iter(&self) -> RingBufferIter<'_, T, N> {
269 RingBufferIter::new(self)
270 }
271}
272
273#[cfg(test)]
278mod tests {
279 use super::*;
280
281 #[test]
282 fn test_ring_buffer_basic() {
283 let mut buffer = RingBuffer::<f32, 4>::new();
284 buffer.write(1.0);
285 buffer.write(2.0);
286 buffer.write(3.0);
287 buffer.write(4.0);
288 assert!(buffer.is_full());
289 assert_eq!(buffer.len(), 4);
290 assert_eq!(buffer.read(), Some(1.0));
291 assert_eq!(buffer.read(), Some(2.0));
292 assert_eq!(buffer.read(), Some(3.0));
293 assert_eq!(buffer.read(), Some(4.0));
294 assert_eq!(buffer.read(), None);
295 assert!(buffer.is_empty());
296 }
297
298 #[test]
299 fn test_ring_buffer_wraparound() {
300 let mut buffer = RingBuffer::<f32, 4>::new();
301 for i in 0..10 {
302 buffer.write(i as f32);
303 }
304 assert_eq!(buffer.read_delayed(0), 9.0);
305 assert_eq!(buffer.read_delayed(1), 8.0);
306 assert_eq!(buffer.read_delayed(2), 7.0);
307 assert_eq!(buffer.read_delayed(3), 6.0);
308 }
309
310 #[test]
311 fn test_ring_buffer_interpolated() {
312 let mut buffer = RingBuffer::<f32, 4>::new();
313 buffer.write(1.0);
314 buffer.write(2.0);
315 buffer.write(3.0);
316 buffer.write(4.0);
317 let val = buffer.read_interpolated(1.5);
318 assert!((val - 3.5).abs() < 0.001);
319 }
320
321 #[test]
322 fn test_ring_buffer_clear() {
323 let mut buffer = RingBuffer::<f32, 4>::new();
324 buffer.write(1.0);
325 buffer.write(2.0);
326 assert!(!buffer.is_empty());
327 buffer.clear();
328 assert!(buffer.is_empty());
329 }
330
331 #[test]
332 fn test_ring_buffer_iterator() {
333 let mut buffer = RingBuffer::<f32, 4>::new();
334 buffer.write(1.0);
335 buffer.write(2.0);
336 buffer.write(3.0);
337 buffer.write(4.0);
338 let collected: Vec<f32> = buffer.iter().collect();
339 assert_eq!(collected, vec![1.0, 2.0, 3.0, 4.0]);
340 }
341
342 #[test]
343 fn test_ring_buffer_read_sequence() {
344 let mut buffer = RingBuffer::<f32, 4>::new();
345 buffer.write(1.0);
346 buffer.write(2.0);
347 buffer.write(3.0);
348 buffer.write(4.0);
349 let mut output = [0.0; 4];
350 buffer.read_sequence_interpolated(0.0, &mut output);
351 assert_eq!(output, [4.0, 3.0, 2.0, 1.0]);
352 }
353
354 #[test]
355 #[should_panic(expected = "Delay must be less than buffer length")]
356 fn test_ring_buffer_invalid_delay() {
357 let buffer = RingBuffer::<f32, 4>::new();
358 let _ = buffer.read_delayed(4);
359 }
360
361 #[test]
362 fn test_ring_buffer_write_slice() {
363 let mut buffer = RingBuffer::<f32, 4>::new();
364 buffer.write_slice(&[1.0, 2.0, 3.0, 4.0]);
365 assert_eq!(buffer.read(), Some(1.0));
366 assert_eq!(buffer.read(), Some(2.0));
367 assert_eq!(buffer.read(), Some(3.0));
368 assert_eq!(buffer.read(), Some(4.0));
369 }
370}