firewheel_core/dsp/
buffer.rs

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