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, Clone)]
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
263/// A memory-efficient buffer of samples with up to `MAX_CHANNELS` channels. Each
264/// channel has a length of `frames`.
265#[derive(Debug, Clone)]
266pub struct VarChannelBuffer<T: Clone + Copy + Default, const MAX_CHANNELS: usize> {
267    buffer: Vec<T>,
268    channels: NonZeroUsize,
269    frames: usize,
270}
271
272impl<T: Clone + Copy + Default, const MAX_CHANNELS: usize> VarChannelBuffer<T, MAX_CHANNELS> {
273    pub fn new(channels: NonZeroUsize, frames: usize) -> Self {
274        assert!(channels.get() <= MAX_CHANNELS);
275
276        let buffer_len = frames * channels.get();
277
278        let mut buffer = Vec::new();
279        buffer.reserve_exact(buffer_len);
280        buffer.resize(buffer_len, Default::default());
281
282        Self {
283            buffer,
284            channels,
285            frames,
286        }
287    }
288
289    pub fn frames(&self) -> usize {
290        self.frames
291    }
292
293    pub fn num_channels(&self) -> NonZeroUsize {
294        self.channels
295    }
296
297    pub fn channels(&self, num_channels: usize, frames: usize) -> ArrayVec<&[T], MAX_CHANNELS> {
298        let frames = frames.min(self.frames);
299        let channels = num_channels.min(self.channels.get());
300
301        let mut res = ArrayVec::new();
302
303        // SAFETY:
304        //
305        // * The constructor has set the size of the buffer to `self.frames * self.channels`,
306        // and we have constrained `channels` and `frames` above, so this is always
307        // within range.
308        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
309        unsafe {
310            for ch_i in 0..channels {
311                res.push_unchecked(core::slice::from_raw_parts(
312                    self.buffer.as_ptr().add(ch_i * self.frames),
313                    frames,
314                ));
315            }
316        }
317
318        res
319    }
320
321    pub fn channels_mut(
322        &mut self,
323        num_channels: usize,
324        frames: usize,
325    ) -> ArrayVec<&mut [T], MAX_CHANNELS> {
326        let frames = frames.min(self.frames);
327        let channels = num_channels.min(self.channels.get());
328
329        let mut res = ArrayVec::new();
330
331        // SAFETY:
332        //
333        // * The constructor has set the size of the buffer to `self.frames * self.channels`,
334        // and we have constrained `channels` and `frames` above, so this is always
335        // within range.
336        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
337        // * None of these slices overlap, and `self` is borrowed mutably in this method,
338        // so all mutability rules are being upheld.
339        unsafe {
340            for ch_i in 0..channels {
341                res.push_unchecked(core::slice::from_raw_parts_mut(
342                    self.buffer.as_mut_ptr().add(ch_i * self.frames),
343                    frames,
344                ));
345            }
346        }
347
348        res
349    }
350}
351
352/// A memory-efficient buffer of samples with variable number of instances each with up to
353/// `MAX_CHANNELS` channels. Each channel has a length of `frames`.
354#[derive(Debug, Clone)]
355pub struct InstanceBuffer<T: Clone + Copy + Default, const MAX_CHANNELS: usize> {
356    buffer: Vec<T>,
357    num_instances: usize,
358    channels: NonZeroUsize,
359    frames: usize,
360}
361
362impl<T: Clone + Copy + Default, const MAX_CHANNELS: usize> InstanceBuffer<T, MAX_CHANNELS> {
363    pub fn new(num_instances: usize, channels: NonZeroUsize, frames: usize) -> Self {
364        assert!(channels.get() <= MAX_CHANNELS);
365
366        let buffer_len = frames * channels.get() * num_instances;
367
368        let mut buffer = Vec::new();
369        buffer.reserve_exact(buffer_len);
370        buffer.resize(buffer_len, Default::default());
371
372        Self {
373            buffer,
374            num_instances,
375            channels,
376            frames,
377        }
378    }
379
380    pub fn frames(&self) -> usize {
381        self.frames
382    }
383
384    pub fn num_channels(&self) -> NonZeroUsize {
385        self.channels
386    }
387
388    pub fn num_instances(&self) -> usize {
389        self.num_instances
390    }
391
392    pub fn instance(
393        &self,
394        instance_index: usize,
395        channels: usize,
396        frames: usize,
397    ) -> Option<ArrayVec<&[T], MAX_CHANNELS>> {
398        if instance_index >= self.num_instances {
399            return None;
400        }
401
402        let frames = frames.min(self.frames);
403        let channels = channels.min(self.channels.get());
404
405        let start_frame = instance_index * self.frames * self.channels.get();
406
407        let mut res = ArrayVec::new();
408
409        // SAFETY:
410        //
411        // * The constructor has set the size of the buffer to
412        // `self.frames * self.channels * self.num_instances`, and we have constrained
413        // `instance_index`, `channels` and `frames` above, so this is always within range.
414        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
415        unsafe {
416            for ch_i in 0..channels {
417                res.push_unchecked(core::slice::from_raw_parts(
418                    self.buffer.as_ptr().add(start_frame + (ch_i * self.frames)),
419                    frames,
420                ));
421            }
422        }
423
424        Some(res)
425    }
426
427    pub fn instance_mut(
428        &mut self,
429        instance_index: usize,
430        channels: usize,
431        frames: usize,
432    ) -> Option<ArrayVec<&mut [T], MAX_CHANNELS>> {
433        if instance_index >= self.num_instances {
434            return None;
435        }
436
437        let frames = frames.min(self.frames);
438        let channels = channels.min(self.channels.get());
439
440        let start_frame = instance_index * self.frames * self.channels.get();
441
442        let mut res = ArrayVec::new();
443
444        // SAFETY:
445        //
446        // * The constructor has set the size of the buffer to
447        // `self.frames * self.channels * self.num_instances`, and we have constrained
448        // `instance_index`, `channels` and `frames` above, so this is always within range.
449        // * The constructor has ensured that `self.channels <= MAX_CHANNELS`.
450        // * None of these slices overlap, and `self` is borrowed mutably in this method,
451        // so all mutability rules are being upheld.
452        unsafe {
453            for ch_i in 0..channels {
454                res.push_unchecked(core::slice::from_raw_parts_mut(
455                    self.buffer
456                        .as_mut_ptr()
457                        .add(start_frame + (ch_i * self.frames)),
458                    frames,
459                ));
460            }
461        }
462
463        Some(res)
464    }
465}