Skip to main content

rill_core/buffer/
buffer_trait.rs

1//! # Buffer trait — abstract audio buffer
2//!
3//! Defines the common interface for all buffer types used in the signal
4//! graph: per-port fixed buffers, heap-allocated buffers, TapeLoop.
5//!
6//! Buffer size is an internal implementation detail — the trait is not
7//! parameterised by size.
8
9use core::ops::{Deref, DerefMut};
10
11/// Common interface for audio buffers of arbitrary size.
12///
13/// Enables storing buffers of different types and sizes in a single graph
14/// resource registry (`GraphResources`).
15pub trait Buffer<T> {
16    /// Number of samples in the buffer.
17    fn len(&self) -> usize;
18
19    /// Whether the buffer is empty.
20    fn is_empty(&self) -> bool {
21        self.len() == 0
22    }
23
24    /// Read-only access to the buffer data.
25    fn as_slice(&self) -> &[T];
26
27    /// Mutable access to the buffer data.
28    fn as_mut_slice(&mut self) -> &mut [T];
29
30    /// Fill the entire buffer with a value.
31    fn fill(&mut self, value: T)
32    where
33        T: Copy;
34
35    /// Copy data from a slice. Copies `min(src.len(), self.len())` samples.
36    fn copy_from(&mut self, src: &[T])
37    where
38        T: Copy;
39}
40
41// ============================================================================
42// FixedBuffer — compile-time fixed size, stack-allocated
43// ============================================================================
44
45/// Fixed-size buffer on the stack — default per-port buffer.
46#[derive(Debug, Clone)]
47pub struct FixedBuffer<T, const SIZE: usize> {
48    data: [T; SIZE],
49}
50
51impl<T: Copy + Default, const SIZE: usize> FixedBuffer<T, SIZE> {
52    /// Create a new buffer filled with `T::default()`.
53    pub fn new() -> Self {
54        Self {
55            data: [T::default(); SIZE],
56        }
57    }
58
59    /// Create a buffer from a fixed-size array.
60    pub fn from_array(data: [T; SIZE]) -> Self {
61        Self { data }
62    }
63
64    /// Create a buffer from a slice, truncating or padding with `T::default()` as needed.
65    pub fn from_slice(slice: &[T]) -> Self
66    where
67        T: Copy,
68    {
69        let mut data = [T::default(); SIZE];
70        let len = slice.len().min(SIZE);
71        data[..len].copy_from_slice(&slice[..len]);
72        Self { data }
73    }
74
75    /// Return a reference to the inner array.
76    pub fn as_array(&self) -> &[T; SIZE] {
77        &self.data
78    }
79
80    /// Return a mutable reference to the inner array.
81    pub fn as_mut_array(&mut self) -> &mut [T; SIZE] {
82        &mut self.data
83    }
84}
85
86impl<T: Copy + Default, const SIZE: usize> Default for FixedBuffer<T, SIZE> {
87    fn default() -> Self {
88        Self::new()
89    }
90}
91
92impl<T, const SIZE: usize> Deref for FixedBuffer<T, SIZE> {
93    type Target = [T; SIZE];
94    fn deref(&self) -> &Self::Target {
95        &self.data
96    }
97}
98
99impl<T, const SIZE: usize> DerefMut for FixedBuffer<T, SIZE> {
100    fn deref_mut(&mut self) -> &mut Self::Target {
101        &mut self.data
102    }
103}
104
105impl<T: Copy + Default, const SIZE: usize> From<[T; SIZE]> for FixedBuffer<T, SIZE> {
106    fn from(data: [T; SIZE]) -> Self {
107        Self::from_array(data)
108    }
109}
110
111impl<T: Default + Copy, const SIZE: usize> Buffer<T> for FixedBuffer<T, SIZE> {
112    fn len(&self) -> usize {
113        SIZE
114    }
115
116    fn as_slice(&self) -> &[T] {
117        &self.data
118    }
119
120    fn as_mut_slice(&mut self) -> &mut [T] {
121        &mut self.data
122    }
123
124    fn fill(&mut self, value: T)
125    where
126        T: Copy,
127    {
128        self.data.fill(value);
129    }
130
131    fn copy_from(&mut self, src: &[T])
132    where
133        T: Copy,
134    {
135        let len = src.len().min(SIZE);
136        self.data[..len].copy_from_slice(&src[..len]);
137    }
138}
139
140// ============================================================================
141// HeapBuffer — runtime-sized, heap-allocated
142// ============================================================================
143
144/// Heap-allocated buffer with runtime-determined size.
145///
146/// Used for resources whose size is determined from data
147/// (loaded samples, configuration).
148#[derive(Debug, Clone)]
149pub struct HeapBuffer<T> {
150    data: Vec<T>,
151}
152
153impl<T: Default + Copy> HeapBuffer<T> {
154    /// Create a new buffer with `size` samples, all initialized to `T::default()`.
155    pub fn new(size: usize) -> Self {
156        Self {
157            data: vec![T::default(); size],
158        }
159    }
160
161    /// Create a buffer from an existing `Vec`, taking ownership.
162    pub fn from_vec(data: Vec<T>) -> Self {
163        Self { data }
164    }
165}
166
167impl<T: Default + Copy> Buffer<T> for HeapBuffer<T> {
168    fn len(&self) -> usize {
169        self.data.len()
170    }
171
172    fn as_slice(&self) -> &[T] {
173        &self.data
174    }
175
176    fn as_mut_slice(&mut self) -> &mut [T] {
177        &mut self.data
178    }
179
180    fn fill(&mut self, value: T)
181    where
182        T: Copy,
183    {
184        self.data.fill(value);
185    }
186
187    fn copy_from(&mut self, src: &[T])
188    where
189        T: Copy,
190    {
191        let len = src.len().min(self.data.len());
192        self.data[..len].copy_from_slice(&src[..len]);
193    }
194}