Skip to main content

meadow_dsp_essentials/
buffer.rs

1use alloc::vec::Vec;
2use core::num::NonZeroUsize;
3
4use arrayvec::ArrayVec;
5
6/// A memory-efficient buffer of samples with `CHANNELS` channels. Each channel
7/// has a length of `frames`.
8pub struct ChannelBuffer<T: Clone + Copy + Default, const CHANNELS: usize> {
9    buffer: Vec<T>,
10    frames: usize,
11}
12
13impl<T: Clone + Copy + Default, const CHANNELS: usize> ChannelBuffer<T, CHANNELS> {
14    pub const fn empty() -> Self {
15        assert!(CHANNELS > 0);
16
17        Self {
18            buffer: Vec::new(),
19            frames: 0,
20        }
21    }
22
23    pub fn new(frames: usize) -> Self {
24        assert!(CHANNELS > 0);
25
26        let buffer_len = frames * CHANNELS;
27
28        let mut buffer = Vec::new();
29        buffer.reserve_exact(buffer_len);
30        buffer.resize(buffer_len, Default::default());
31
32        Self { buffer, frames }
33    }
34
35    pub fn frames(&self) -> usize {
36        self.frames
37    }
38
39    /// Get an immutable reference to the first channel.
40    #[inline]
41    pub fn first(&self) -> &[T] {
42        // SAFETY:
43        //
44        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
45        unsafe { core::slice::from_raw_parts(self.buffer.as_ptr(), self.frames) }
46    }
47
48    /// Get a mutable reference to the first channel.
49    #[inline]
50    pub fn first_mut(&mut self) -> &mut [T] {
51        // SAFETY:
52        //
53        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
54        // * `self` is borrowed mutably in this method, so all mutability rules are
55        // being upheld.
56        unsafe { core::slice::from_raw_parts_mut(self.buffer.as_mut_ptr(), self.frames) }
57    }
58
59    /// Get an immutable reference to the first channel with the given number of
60    /// frames.
61    ///
62    /// The length of the returned slice will be either `frames` or the number of
63    /// frames in this buffer, whichever is smaller.
64    #[inline]
65    pub fn first_with_frames(&self, frames: usize) -> &[T] {
66        let frames = frames.min(self.frames);
67
68        // SAFETY:
69        //
70        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
71        // and we have constrained `frames` above, so this is always within range.
72        unsafe { core::slice::from_raw_parts(self.buffer.as_ptr(), frames) }
73    }
74
75    /// Get a mutable reference to the first channel with the given number of
76    /// frames.
77    ///
78    /// The length of the returned slice will be either `frames` or the number of
79    /// frames in this buffer, whichever is smaller.
80    #[inline]
81    pub fn first_with_frames_mut(&mut self, frames: usize) -> &mut [T] {
82        let frames = frames.min(self.frames);
83
84        // SAFETY:
85        //
86        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
87        // and we have constrained `frames` above, so this is always within range.
88        // * `self` is borrowed mutably in this method, so all mutability rules are
89        // being upheld.
90        unsafe { core::slice::from_raw_parts_mut(self.buffer.as_mut_ptr(), frames) }
91    }
92
93    /// Get an immutable reference to the first given number of channels in this buffer.
94    pub fn channels<const NUM_CHANNELS: usize>(&self) -> [&[T]; NUM_CHANNELS] {
95        assert!(NUM_CHANNELS <= CHANNELS);
96
97        // SAFETY:
98        //
99        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
100        // and we have constrained NUM_CHANNELS above, so this is always within range.
101        unsafe {
102            core::array::from_fn(|ch_i| {
103                core::slice::from_raw_parts(
104                    self.buffer.as_ptr().add(ch_i * self.frames),
105                    self.frames,
106                )
107            })
108        }
109    }
110
111    /// Get a mutable reference to the first given number of channels in this buffer.
112    pub fn channels_mut<const NUM_CHANNELS: usize>(&mut self) -> [&mut [T]; NUM_CHANNELS] {
113        assert!(NUM_CHANNELS <= CHANNELS);
114
115        // SAFETY:
116        //
117        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
118        // and we have constrained NUM_CHANNELS above, so this is always within range.
119        // * None of these slices overlap, and `self` is borrowed mutably in this method,
120        // so all mutability rules are being upheld.
121        unsafe {
122            core::array::from_fn(|ch_i| {
123                core::slice::from_raw_parts_mut(
124                    self.buffer.as_mut_ptr().add(ch_i * self.frames),
125                    self.frames,
126                )
127            })
128        }
129    }
130
131    /// Get an immutable reference to the first given number of channels with the
132    /// given number of frames.
133    ///
134    /// The length of the returned slices will be either `frames` or the number of
135    /// frames in this buffer, whichever is smaller.
136    pub fn channels_with_frames<const NUM_CHANNELS: usize>(
137        &self,
138        frames: usize,
139    ) -> [&[T]; NUM_CHANNELS] {
140        assert!(NUM_CHANNELS <= CHANNELS);
141
142        let frames = frames.min(self.frames);
143
144        // SAFETY:
145        //
146        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
147        // and we have constrained NUM_CHANNELS and `frames` above, so this is always
148        // within range.
149        unsafe {
150            core::array::from_fn(|ch_i| {
151                core::slice::from_raw_parts(self.buffer.as_ptr().add(ch_i * self.frames), frames)
152            })
153        }
154    }
155
156    /// Get a mutable reference to the first given number of channels with the given
157    /// number of frames.
158    ///
159    /// The length of the returned slices will be either `frames` or the number of
160    /// frames in this buffer, whichever is smaller.
161    pub fn channels_with_frames_mut<const NUM_CHANNELS: usize>(
162        &mut self,
163        frames: usize,
164    ) -> [&mut [T]; NUM_CHANNELS] {
165        assert!(NUM_CHANNELS <= CHANNELS);
166
167        let frames = frames.min(self.frames);
168
169        // SAFETY:
170        //
171        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
172        // and we have constrained NUM_CHANNELS and `frames` above, so this is always
173        // within range.
174        // * None of these slices overlap, and `self` is borrowed mutably in this method,
175        // so all mutability rules are being upheld.
176        unsafe {
177            core::array::from_fn(|ch_i| {
178                core::slice::from_raw_parts_mut(
179                    self.buffer.as_mut_ptr().add(ch_i * self.frames),
180                    frames,
181                )
182            })
183        }
184    }
185
186    /// Get an immutable reference to all channels in this buffer.
187    pub fn all(&self) -> [&[T]; CHANNELS] {
188        // SAFETY:
189        //
190        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
191        unsafe {
192            core::array::from_fn(|ch_i| {
193                core::slice::from_raw_parts(
194                    self.buffer.as_ptr().add(ch_i * self.frames),
195                    self.frames,
196                )
197            })
198        }
199    }
200
201    /// Get a mutable reference to all channels in this buffer.
202    pub fn all_mut(&mut self) -> [&mut [T]; CHANNELS] {
203        // SAFETY:
204        //
205        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`.
206        // * None of these slices overlap, and `self` is borrowed mutably in this method,
207        // so all mutability rules are being upheld.
208        unsafe {
209            core::array::from_fn(|ch_i| {
210                core::slice::from_raw_parts_mut(
211                    self.buffer.as_mut_ptr().add(ch_i * self.frames),
212                    self.frames,
213                )
214            })
215        }
216    }
217
218    /// Get an immutable reference to all channels with the given number of frames.
219    ///
220    /// The length of the returned slices will be either `frames` or the number of
221    /// frames in this buffer, whichever is smaller.
222    pub fn all_with_frames(&self, frames: usize) -> [&[T]; CHANNELS] {
223        let frames = frames.min(self.frames);
224
225        // SAFETY:
226        //
227        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
228        // and we have constrained `frames` above, so this is always within range.
229        unsafe {
230            core::array::from_fn(|ch_i| {
231                core::slice::from_raw_parts(self.buffer.as_ptr().add(ch_i * self.frames), frames)
232            })
233        }
234    }
235
236    /// Get a mutable reference to all channels with the given number of frames.
237    ///
238    /// The length of the returned slices will be either `frames` or the number of
239    /// frames in this buffer, whichever is smaller.
240    pub fn all_with_frames_mut(&mut self, frames: usize) -> [&mut [T]; CHANNELS] {
241        let frames = frames.min(self.frames);
242
243        // SAFETY:
244        //
245        // * The constructor has set the size of the buffer to `self.frames * CHANNELS`,
246        // and we have constrained `frames` above, so this is always within range.
247        // * None of these slices overlap, and `self` is borrowed mutably in this method,
248        // so all mutability rules are being upheld.
249        unsafe {
250            core::array::from_fn(|ch_i| {
251                core::slice::from_raw_parts_mut(
252                    self.buffer.as_mut_ptr().add(ch_i * self.frames),
253                    frames,
254                )
255            })
256        }
257    }
258}
259
260/// A memory-efficient buffer of samples with up to `MAX_CHANNELS` channels. Each
261/// channel has a length of `frames`.
262pub struct VarChannelBuffer<T: Clone + Copy + Default, const MAX_CHANNELS: usize> {
263    buffer: Vec<T>,
264    channels: NonZeroUsize,
265    frames: usize,
266}
267
268impl<T: Clone + Copy + Default, const MAX_CHANNELS: usize> VarChannelBuffer<T, MAX_CHANNELS> {
269    pub fn new(channels: NonZeroUsize, frames: usize) -> Self {
270        assert!(channels.get() <= MAX_CHANNELS);
271
272        let buffer_len = frames * channels.get();
273
274        let mut buffer = Vec::new();
275        buffer.reserve_exact(buffer_len);
276        buffer.resize(buffer_len, Default::default());
277
278        Self {
279            buffer,
280            channels,
281            frames,
282        }
283    }
284
285    pub fn frames(&self) -> usize {
286        self.frames
287    }
288
289    pub fn num_channels(&self) -> NonZeroUsize {
290        self.channels
291    }
292
293    pub fn channels(&self, num_channels: usize, frames: usize) -> ArrayVec<&[T], MAX_CHANNELS> {
294        let frames = frames.min(self.frames);
295        let channels = num_channels.min(self.channels.get());
296
297        let mut res = ArrayVec::new();
298
299        // SAFETY:
300        //
301        // * The constructor has set the size of the buffer to `self.frames * self.channels`,
302        // and we have constrained `channels` and `frames` above, so this is always
303        // within range.
304        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
305        unsafe {
306            for ch_i in 0..channels {
307                res.push_unchecked(core::slice::from_raw_parts(
308                    self.buffer.as_ptr().add(ch_i * self.frames),
309                    frames,
310                ));
311            }
312        }
313
314        res
315    }
316
317    pub fn channels_mut(
318        &mut self,
319        num_channels: usize,
320        frames: usize,
321    ) -> ArrayVec<&mut [T], MAX_CHANNELS> {
322        let frames = frames.min(self.frames);
323        let channels = num_channels.min(self.channels.get());
324
325        let mut res = ArrayVec::new();
326
327        // SAFETY:
328        //
329        // * The constructor has set the size of the buffer to `self.frames * self.channels`,
330        // and we have constrained `channels` and `frames` above, so this is always
331        // within range.
332        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
333        // * None of these slices overlap, and `self` is borrowed mutably in this method,
334        // so all mutability rules are being upheld.
335        unsafe {
336            for ch_i in 0..channels {
337                res.push_unchecked(core::slice::from_raw_parts_mut(
338                    self.buffer.as_mut_ptr().add(ch_i * self.frames),
339                    frames,
340                ));
341            }
342        }
343
344        res
345    }
346}
347
348/// A memory-efficient buffer of samples with variable number of instances each with up to
349/// `MAX_CHANNELS` channels. Each channel has a length of `frames`.
350pub struct InstanceBuffer<T: Clone + Copy + Default, const MAX_CHANNELS: usize> {
351    buffer: Vec<T>,
352    num_instances: usize,
353    channels: NonZeroUsize,
354    frames: usize,
355}
356
357impl<T: Clone + Copy + Default, const MAX_CHANNELS: usize> InstanceBuffer<T, MAX_CHANNELS> {
358    pub fn new(num_instances: usize, channels: NonZeroUsize, frames: usize) -> Self {
359        assert!(channels.get() <= MAX_CHANNELS);
360
361        let buffer_len = frames * channels.get() * num_instances;
362
363        let mut buffer = Vec::new();
364        buffer.reserve_exact(buffer_len);
365        buffer.resize(buffer_len, Default::default());
366
367        Self {
368            buffer,
369            num_instances,
370            channels,
371            frames,
372        }
373    }
374
375    pub fn frames(&self) -> usize {
376        self.frames
377    }
378
379    pub fn num_channels(&self) -> NonZeroUsize {
380        self.channels
381    }
382
383    pub fn num_instances(&self) -> usize {
384        self.num_instances
385    }
386
387    pub fn instance(
388        &self,
389        instance_index: usize,
390        channels: usize,
391        frames: usize,
392    ) -> Option<ArrayVec<&[T], MAX_CHANNELS>> {
393        if instance_index >= self.num_instances {
394            return None;
395        }
396
397        let frames = frames.min(self.frames);
398        let channels = channels.min(self.channels.get());
399
400        let start_frame = instance_index * self.frames * self.channels.get();
401
402        let mut res = ArrayVec::new();
403
404        // SAFETY:
405        //
406        // * The constructor has set the size of the buffer to
407        // `self.frames * self.channels * self.num_instances`, and we have constrained
408        // `instance_index`, `channels` and `frames` above, so this is always within range.
409        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
410        unsafe {
411            for ch_i in 0..channels {
412                res.push_unchecked(core::slice::from_raw_parts(
413                    self.buffer.as_ptr().add(start_frame + (ch_i * self.frames)),
414                    frames,
415                ));
416            }
417        }
418
419        Some(res)
420    }
421
422    pub fn instance_mut(
423        &mut self,
424        instance_index: usize,
425        channels: usize,
426        frames: usize,
427    ) -> Option<ArrayVec<&mut [T], MAX_CHANNELS>> {
428        if instance_index >= self.num_instances {
429            return None;
430        }
431
432        let frames = frames.min(self.frames);
433        let channels = channels.min(self.channels.get());
434
435        let start_frame = instance_index * self.frames * self.channels.get();
436
437        let mut res = ArrayVec::new();
438
439        // SAFETY:
440        //
441        // * The constructor has set the size of the buffer to
442        // `self.frames * self.channels * self.num_instances`, and we have constrained
443        // `instance_index`, `channels` and `frames` above, so this is always within range.
444        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
445        // * None of these slices overlap, and `self` is borrowed mutably in this method,
446        // so all mutability rules are being upheld.
447        unsafe {
448            for ch_i in 0..channels {
449                res.push_unchecked(core::slice::from_raw_parts_mut(
450                    self.buffer
451                        .as_mut_ptr()
452                        .add(start_frame + (ch_i * self.frames)),
453                    frames,
454                ));
455            }
456        }
457
458        Some(res)
459    }
460}