Skip to main content

rill_core/buffer/
ring.rs

1//! # Кольцевой буфер для задержек и эффектов
2//!
3//! [`RingBuffer`] реализует классический кольцевой буфер (циклический буфер)
4//! с фиксированным размером. Идеально подходит для эффектов задержки,
5//! реверберации, хоров и т.д.
6//!
7//! ## Особенности
8//! - Lock-free, wait-free для производителя
9//! - Фиксированный размер (должен быть степенью двойки)
10//! - Поддержка чтения с задержкой
11//! - Интерполяция для дробных задержек
12//! - Все `unsafe` операции инкапсулированы и документированы
13
14use std::fmt;
15use std::sync::atomic::{AtomicUsize, Ordering};
16
17use super::storage::AtomicCell;
18use crate::math::Transcendental;
19
20// =============================================================================
21// Основная структура
22// =============================================================================
23
24/// Кольцевой буфер с фиксированным размером
25///
26/// # Пример
27/// ```
28/// use rill_core::buffer::RingBuffer;
29///
30/// let mut buffer = RingBuffer::<f32, 4>::new();
31/// buffer.write(1.0);
32/// buffer.write(2.0);
33/// buffer.write(3.0);
34/// buffer.write(4.0);
35///
36/// assert_eq!(buffer.read_delayed(0), 4.0); // последний записанный
37/// assert_eq!(buffer.read_delayed(1), 3.0);
38/// assert_eq!(buffer.read_delayed(2), 2.0);
39/// assert_eq!(buffer.read_delayed(3), 1.0);
40/// ```
41#[repr(C, align(64))]
42pub struct RingBuffer<T: Transcendental, const N: usize> {
43    /// Данные буфера (атомарные ячейки для lock-free доступа)
44    data: [AtomicCell<T>; N],
45
46    /// Индекс записи (только producer)
47    head: AtomicUsize,
48
49    /// Индекс чтения (только consumer)
50    tail: AtomicUsize,
51
52    /// Маска для быстрого вычисления (N-1)
53    mask: usize,
54
55    /// Флаг, указывающий, что буфер полон
56    full: AtomicUsize,
57}
58
59impl<T: Transcendental, const N: usize> RingBuffer<T, N> {
60    /// Создать новый кольцевой буфер
61    ///
62    /// # Panics
63    /// Паникует, если N не является степенью двойки
64    pub fn new() -> Self {
65        assert!(N.is_power_of_two(), "RingBuffer size must be power of two");
66
67        // Инициализируем данные нулями с помощью AtomicCell
68        let data = [const { AtomicCell::new(T::ZERO) }; N];
69
70        Self {
71            data,
72            head: AtomicUsize::new(0),
73            tail: AtomicUsize::new(0),
74            mask: N - 1,
75            full: AtomicUsize::new(0),
76        }
77    }
78
79    /// Записать семпл (всегда успешно, перезаписывает старые данные)
80    ///
81    /// # Safety
82    /// Эта операция безопасна, потому что:
83    /// 1. `head` уникален для производителя
84    /// 2. Производитель никогда не читает из своей позиции
85    /// 3. Атомарные операции гарантируют видимость
86    pub fn write(&mut self, sample: T) {
87        let head = self.head.load(Ordering::Relaxed);
88        self.data[head].store(sample);
89
90        let next_head = (head + 1) & self.mask;
91        self.head.store(next_head, Ordering::Release);
92
93        // Если после записи head догнал tail, значит буфер полон
94        if next_head == self.tail.load(Ordering::Acquire) {
95            self.full.store(1, Ordering::Release);
96        }
97    }
98
99    /// Записать массив семплов
100    pub fn write_slice(&mut self, samples: &[T]) {
101        for &sample in samples {
102            self.write(sample);
103        }
104    }
105
106    /// Прочитать семпл (если есть)
107    ///
108    /// # Returns
109    /// * `Some(sample)` - семпл успешно прочитан
110    /// * `None` - буфер пуст
111    pub fn read(&mut self) -> Option<T> {
112        let tail = self.tail.load(Ordering::Relaxed);
113
114        if tail == self.head.load(Ordering::Acquire) && self.full.load(Ordering::Acquire) == 0 {
115            return None;
116        }
117
118        // Безопасно: мы единственный потребитель для этой позиции
119        let sample = self.data[tail].load();
120
121        let next_tail = (tail + 1) & self.mask;
122        self.tail.store(next_tail, Ordering::Release);
123        self.full.store(0, Ordering::Release);
124
125        Some(sample)
126    }
127
128    /// Прочитать семпл с задержкой (без изменения указателей)
129    ///
130    /// # Arguments
131    /// * `delay` - задержка в семплах (0 = последний записанный)
132    ///
133    /// # Panics
134    /// Паникует, если `delay >= len()`
135    pub fn read_delayed(&self, delay: usize) -> T {
136        assert!(delay < self.len(), "Delay must be less than buffer length");
137
138        let head = self.head.load(Ordering::Acquire);
139        // Для delay=0 читаем последний записанный (head-1)
140        // Для delay=1 читаем предпоследний (head-2) и т.д.
141        let read_pos = (head + self.capacity() - delay - 1) & self.mask;
142
143        self.data[read_pos].load()
144    }
145
146    /// Прочитать с интерполяцией (для дробных задержек)
147    ///
148    /// # Arguments
149    /// * `delay_frac` - задержка в семплах с дробной частью
150    ///
151    /// # Returns
152    /// Интерполированное значение (линейная интерполяция)
153    pub fn read_interpolated(&self, delay_frac: f32) -> T
154    where
155        T: From<f32> + Into<f32>,
156    {
157        let delay_int = delay_frac.floor() as usize;
158        let frac = delay_frac.fract();
159
160        // If fractional part is zero, no interpolation needed
161        if frac == 0.0 {
162            return self.read_delayed(delay_int);
163        }
164
165        let s1: f32 = self.read_delayed(delay_int).into();
166        // Interpolate towards the newer sample (delay_int - 1)
167        let len = self.len();
168        let prev = if delay_int == 0 {
169            len - 1
170        } else {
171            delay_int - 1
172        };
173        let s2: f32 = self.read_delayed(prev).into();
174
175        T::from(s1 * (1.0 - frac) + s2 * frac)
176    }
177
178    /// Прочитать последовательность с интерполяцией
179    ///
180    /// # Arguments
181    /// * `start_delay` - начальная задержка
182    /// * `output` - буфер для записи результата
183    pub fn read_sequence_interpolated(&self, start_delay: f32, output: &mut [T])
184    where
185        T: From<f32> + Into<f32>,
186    {
187        let len = self.len();
188        for i in 0..output.len() {
189            let delay = start_delay + i as f32;
190            if delay < len as f32 {
191                output[i] = self.read_interpolated(delay);
192            } else {
193                output[i] = T::ZERO;
194            }
195        }
196    }
197
198    /// Текущий размер (количество элементов в буфере)
199    pub fn len(&self) -> usize {
200        let head = self.head.load(Ordering::Acquire);
201        let tail = self.tail.load(Ordering::Acquire);
202
203        if self.full.load(Ordering::Acquire) == 1 {
204            N
205        } else if head >= tail {
206            head - tail
207        } else {
208            N - tail + head
209        }
210    }
211
212    /// Вместимость буфера
213    pub const fn capacity(&self) -> usize {
214        N
215    }
216
217    /// Проверить, пуст ли буфер
218    pub fn is_empty(&self) -> bool {
219        self.head.load(Ordering::Acquire) == self.tail.load(Ordering::Acquire)
220            && self.full.load(Ordering::Acquire) == 0
221    }
222
223    /// Проверить, полон ли буфер
224    pub fn is_full(&self) -> bool {
225        self.full.load(Ordering::Acquire) == 1
226    }
227
228    /// Очистить буфер (сбросить указатели)
229    pub fn clear(&mut self) {
230        self.head.store(0, Ordering::Relaxed);
231        self.tail.store(0, Ordering::Relaxed);
232        self.full.store(0, Ordering::Relaxed);
233
234        // Опционально: обнуляем данные для безопасности
235        for i in 0..N {
236            self.data[i].store(T::ZERO);
237        }
238    }
239
240    /// Сбросить буфер без обнуления данных (быстрее)
241    pub fn reset(&mut self) {
242        self.head.store(0, Ordering::Relaxed);
243        self.tail.store(0, Ordering::Relaxed);
244        self.full.store(0, Ordering::Relaxed);
245    }
246}
247
248// =============================================================================
249// Реализация Default
250// =============================================================================
251
252impl<T: Transcendental, const N: usize> Default for RingBuffer<T, N> {
253    fn default() -> Self {
254        Self::new()
255    }
256}
257
258// =============================================================================
259// Реализация Debug
260// =============================================================================
261
262impl<T: Transcendental + fmt::Debug, const N: usize> fmt::Debug for RingBuffer<T, N> {
263    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
264        // Читаем текущее состояние атомарно
265        let head = self.head.load(Ordering::Relaxed);
266        let tail = self.tail.load(Ordering::Relaxed);
267        let full = self.full.load(Ordering::Relaxed);
268        let len = self.len();
269
270        // Собираем несколько первых элементов для отладки
271        let mut preview = Vec::with_capacity(4);
272        for i in 0..4.min(N) {
273            let val = self.data[i].load();
274            preview.push(val);
275        }
276
277        f.debug_struct("RingBuffer")
278            .field("head", &head)
279            .field("tail", &tail)
280            .field("full", &full)
281            .field("len", &len)
282            .field("capacity", &N)
283            .field("preview", &preview)
284            .finish()
285    }
286}
287
288// =============================================================================
289// Реализация Send/Sync (безопасно, так как AtomicCell управляет синхронизацией)
290// =============================================================================
291#[allow(unsafe_code)]
292unsafe impl<T: Transcendental + Send, const N: usize> Send for RingBuffer<T, N> {}
293#[allow(unsafe_code)]
294unsafe impl<T: Transcendental + Sync, const N: usize> Sync for RingBuffer<T, N> {}
295
296// =============================================================================
297// Итератор для кольцевого буфера
298// =============================================================================
299
300/// Итератор по элементам кольцевого буфера (от самого старого к самому новому)
301pub struct RingBufferIter<'a, T: Transcendental, const N: usize> {
302    buffer: &'a RingBuffer<T, N>,
303    pos: usize,
304    end: usize,
305}
306
307// rill-core/src/buffer/ring.rs - исправляем итератор
308impl<'a, T: Transcendental, const N: usize> RingBufferIter<'a, T, N> {
309    fn new(buffer: &'a RingBuffer<T, N>) -> Self {
310        let tail = buffer.tail.load(Ordering::Acquire);
311        let head = buffer.head.load(Ordering::Acquire);
312        let full = buffer.full.load(Ordering::Acquire);
313
314        // Определяем реальную длину
315        let len = if full == 1 {
316            N
317        } else if head >= tail {
318            head - tail
319        } else {
320            N - tail + head
321        };
322
323        // Вычисляем end как tail + len (с учётом переполнения)
324        let end = tail + len;
325
326        Self {
327            buffer,
328            pos: tail,
329            end,
330        }
331    }
332}
333
334impl<'a, T: Transcendental, const N: usize> Iterator for RingBufferIter<'a, T, N> {
335    type Item = T;
336
337    fn next(&mut self) -> Option<Self::Item> {
338        if self.pos >= self.end {
339            None
340        } else {
341            let idx = self.pos & self.buffer.mask;
342            let value = self.buffer.data[idx].load();
343            self.pos += 1;
344            Some(value)
345        }
346    }
347}
348
349impl<'a, T: Transcendental, const N: usize> ExactSizeIterator for RingBufferIter<'a, T, N> {
350    fn len(&self) -> usize {
351        self.end - self.pos
352    }
353}
354
355impl<T: Transcendental, const N: usize> RingBuffer<T, N> {
356    /// Получить итератор по элементам буфера (от самого старого к самому новому)
357    pub fn iter(&self) -> RingBufferIter<'_, T, N> {
358        RingBufferIter::new(self)
359    }
360}
361
362// =============================================================================
363// Тесты
364// =============================================================================
365
366#[cfg(test)]
367mod tests {
368    use super::*;
369
370    #[test]
371    fn test_ring_buffer_basic() {
372        let mut buffer = RingBuffer::<f32, 4>::new();
373
374        buffer.write(1.0);
375        buffer.write(2.0);
376        buffer.write(3.0);
377        buffer.write(4.0);
378
379        assert!(buffer.is_full());
380        assert_eq!(buffer.len(), 4);
381
382        assert_eq!(buffer.read(), Some(1.0));
383        assert_eq!(buffer.read(), Some(2.0));
384        assert_eq!(buffer.read(), Some(3.0));
385        assert_eq!(buffer.read(), Some(4.0));
386        assert_eq!(buffer.read(), None);
387        assert!(buffer.is_empty());
388    }
389
390    #[test]
391    fn test_ring_buffer_wraparound() {
392        let mut buffer = RingBuffer::<f32, 4>::new();
393
394        // Записываем 10 семплов
395        for i in 0..10 {
396            buffer.write(i as f32);
397        }
398
399        // После 10 записей должны быть последние 4 значения
400        assert_eq!(buffer.read_delayed(0), 9.0);
401        assert_eq!(buffer.read_delayed(1), 8.0);
402        assert_eq!(buffer.read_delayed(2), 7.0);
403        assert_eq!(buffer.read_delayed(3), 6.0);
404    }
405
406    #[test]
407    fn test_ring_buffer_interpolated() {
408        let mut buffer = RingBuffer::<f32, 4>::new();
409
410        buffer.write(1.0);
411        buffer.write(2.0);
412        buffer.write(3.0);
413        buffer.write(4.0);
414
415        let val = buffer.read_interpolated(1.5);
416        assert!((val - 3.5).abs() < 0.001);
417    }
418
419    #[test]
420    fn test_ring_buffer_clear() {
421        let mut buffer = RingBuffer::<f32, 4>::new();
422
423        buffer.write(1.0);
424        buffer.write(2.0);
425
426        assert!(!buffer.is_empty());
427        assert_eq!(buffer.len(), 2);
428
429        buffer.clear();
430        assert!(buffer.is_empty());
431        assert_eq!(buffer.len(), 0);
432    }
433
434    #[test]
435    fn test_ring_buffer_reset() {
436        let mut buffer = RingBuffer::<f32, 4>::new();
437
438        buffer.write(1.0);
439        buffer.write(2.0);
440        buffer.write(3.0);
441
442        assert_eq!(buffer.len(), 3);
443
444        buffer.reset();
445        assert!(buffer.is_empty());
446        assert_eq!(buffer.len(), 0);
447    }
448
449    #[test]
450    fn test_ring_buffer_iterator() {
451        let mut buffer = RingBuffer::<f32, 4>::new();
452
453        buffer.write(1.0);
454        buffer.write(2.0);
455        buffer.write(3.0);
456        buffer.write(4.0);
457
458        let collected: Vec<f32> = buffer.iter().collect();
459        assert_eq!(collected, vec![1.0, 2.0, 3.0, 4.0]);
460    }
461
462    #[test]
463    fn test_ring_buffer_read_sequence() {
464        let mut buffer = RingBuffer::<f32, 4>::new();
465
466        buffer.write(1.0);
467        buffer.write(2.0);
468        buffer.write(3.0);
469        buffer.write(4.0);
470
471        let mut output = [0.0; 4];
472        buffer.read_sequence_interpolated(0.0, &mut output);
473        assert_eq!(output, [4.0, 3.0, 2.0, 1.0]);
474    }
475
476    #[test]
477    #[should_panic(expected = "Delay must be less than buffer length")]
478    fn test_ring_buffer_invalid_delay() {
479        let buffer = RingBuffer::<f32, 4>::new();
480        let _ = buffer.read_delayed(4);
481    }
482
483    #[test]
484    fn test_ring_buffer_write_slice() {
485        let mut buffer = RingBuffer::<f32, 4>::new();
486
487        buffer.write_slice(&[1.0, 2.0, 3.0, 4.0]);
488
489        assert_eq!(buffer.read(), Some(1.0));
490        assert_eq!(buffer.read(), Some(2.0));
491        assert_eq!(buffer.read(), Some(3.0));
492        assert_eq!(buffer.read(), Some(4.0));
493    }
494}