audio_channel_buffer/
var_buffer.rs

1use alloc::vec::Vec;
2use core::num::NonZeroUsize;
3use core::ops::{Index, IndexMut, Range};
4use core::pin::Pin;
5
6use arrayvec::ArrayVec;
7
8use crate::{VarChannelBufferRef, VarChannelBufferRefMut};
9
10/// A memory-efficient buffer of samples with a fixed runtime number of channels each
11/// with a fixed runtime number of frames (samples in a single channel of audio).
12///
13/// This version uses an owned `Vec` as its data source.
14#[derive(Debug)]
15pub struct VarChannelBuffer<T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize> {
16    data: Pin<Vec<T>>,
17    offsets: ArrayVec<*mut T, MAX_CHANNELS>,
18    frames: usize,
19}
20
21impl<T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize>
22    VarChannelBuffer<T, MAX_CHANNELS>
23{
24    const _COMPILE_TIME_ASSERTS: () = {
25        assert!(MAX_CHANNELS > 0);
26    };
27
28    /// Create an empty [`VarChannelBuffer`] with no allocated capacity.
29    pub fn empty() -> Self {
30        let _ = Self::_COMPILE_TIME_ASSERTS;
31
32        let mut data = Pin::new(Vec::<T>::new());
33
34        let mut offsets = ArrayVec::new();
35        offsets.push(data.as_mut_ptr());
36
37        Self {
38            data,
39            offsets,
40            frames: 0,
41        }
42    }
43
44    /// Create a new [`VarChannelBuffer`] allocated with the given number of channels
45    /// each allocated with the given number of frames (samples in a single channel
46    /// of audio).
47    ///
48    /// All data will be initialized with the default value.
49    ///
50    /// # Panics
51    /// Panics if `channels.get() > MAX_CHANNELS`.
52    pub fn new(channels: NonZeroUsize, frames: usize) -> Self {
53        let _ = Self::_COMPILE_TIME_ASSERTS;
54
55        assert!(channels.get() <= MAX_CHANNELS);
56
57        let buffer_len = channels.get() * frames;
58
59        let mut data = Vec::<T>::new();
60        data.reserve_exact(buffer_len);
61        data.resize(buffer_len, Default::default());
62
63        let mut data = Pin::new(data);
64
65        let mut offsets = ArrayVec::new();
66        // SAFETY:
67        // * All of these pointers point to valid memory in the slice.
68        // * We have constrained `channels` above.
69        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
70        unsafe {
71            for ch_i in 0..channels.get() {
72                offsets.push_unchecked(data.as_mut_ptr().add(ch_i * frames));
73            }
74        }
75
76        Self {
77            data,
78            offsets,
79            frames,
80        }
81    }
82
83    /// Create a new [`VarChannelBuffer`] allocated with the given number of channels
84    /// each allocated with the given number of frames (samples in a single channel
85    /// of audio).
86    ///
87    /// No data will be initialized.
88    ///
89    /// # Safety
90    /// Any data must be initialized before reading.
91    ///
92    /// # Panics
93    /// Panics if `channels.get() > MAX_CHANNELS`.
94    pub unsafe fn new_uninit(channels: NonZeroUsize, frames: usize) -> Self {
95        let _ = Self::_COMPILE_TIME_ASSERTS;
96
97        assert!(channels.get() <= MAX_CHANNELS);
98
99        let buffer_len = channels.get() * frames;
100
101        let mut data = Vec::<T>::new();
102        data.reserve_exact(buffer_len);
103        data.set_len(buffer_len);
104
105        let mut data = Pin::new(data);
106
107        let mut offsets = ArrayVec::new();
108        // SAFETY:
109        // * All of these pointers point to valid memory in the slice.
110        // * We have constrained `channels` above.
111        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
112        unsafe {
113            for ch_i in 0..channels.get() {
114                offsets.push_unchecked(data.as_mut_ptr().add(ch_i * frames));
115            }
116        }
117
118        Self {
119            data,
120            offsets,
121            frames,
122        }
123    }
124
125    /// The number of channels in this buffer.
126    pub fn channels(&self) -> NonZeroUsize {
127        // SAFETY: The constructors ensure that there is at least one element in `offsets`.
128        unsafe { NonZeroUsize::new_unchecked(self.offsets.len()) }
129    }
130
131    /// The number of frames (samples in a single channel of audio) that are allocated
132    /// in this buffer.
133    pub fn frames(&self) -> usize {
134        self.frames
135    }
136
137    #[inline(always)]
138    /// Get an immutable reference to the channel at `index`. The slice will have a length
139    /// of `self.frames()`.
140    ///
141    /// Returns `None` if `index` is out of bounds.
142    pub fn channel(&self, index: usize) -> Option<&[T]> {
143        if index < self.offsets.len() {
144            // SAFETY:
145            // We haved checked that `index` is within bounds.
146            unsafe { Some(self.channel_unchecked(index)) }
147        } else {
148            None
149        }
150    }
151
152    #[inline(always)]
153    /// Get an immutable reference to the channel at `index`. The slice will have a length
154    /// of `self.frames()`.
155    ///
156    /// # Safety
157    /// `index` must be less than `self.channels()`
158    pub unsafe fn channel_unchecked(&self, index: usize) -> &[T] {
159        // SAFETY:
160        //
161        // * The constructors ensure that the pointed-to data vec has a length of at
162        // least `frames * self.channels()`.
163        // * The caller upholds that `index` is within bounds.
164        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
165        // of the struct.
166        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
167        core::slice::from_raw_parts(*self.offsets.get_unchecked(index), self.frames)
168    }
169
170    #[inline(always)]
171    /// Get a mutable reference to the channel at `index`. The slice will have a length
172    /// of `self.frames()`.
173    ///
174    /// Returns `None` if `index` is out of bounds.
175    pub fn channel_mut(&mut self, index: usize) -> Option<&mut [T]> {
176        if index < self.offsets.len() {
177            // SAFETY:
178            // We haved checked that `index` is within bounds.
179            unsafe { Some(self.channel_unchecked_mut(index)) }
180        } else {
181            None
182        }
183    }
184
185    #[inline(always)]
186    /// Get a mutable reference to the channel at `index`. The slice will have a length
187    /// of `self.frames()`.
188    ///
189    /// # Safety
190    /// `index` must be less than `self.channels()`
191    pub unsafe fn channel_unchecked_mut(&mut self, index: usize) -> &mut [T] {
192        // SAFETY:
193        //
194        // * The constructors ensure that the pointed-to data vec has a length of at
195        // least `frames * self.channels()`.
196        // * The caller upholds that `index` is within bounds.
197        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
198        // of the struct.
199        // * `self` is borrowed as mutable, ensuring that no other references to the
200        // data Vec can exist.
201        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
202        core::slice::from_raw_parts_mut(*self.offsets.get_unchecked(index), self.frames)
203    }
204
205    /// Get all channels as immutable slices. Each slice will have a length of `self.frames()`.
206    #[inline]
207    pub fn as_slices(&self) -> ArrayVec<&[T], MAX_CHANNELS> {
208        let mut v = ArrayVec::new();
209
210        // SAFETY:
211        //
212        // * The constructors ensure that the pointed-to data vec has a length of at
213        // least `frames * self.channels()`.
214        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
215        // of the struct.
216        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
217        unsafe {
218            for ptr in self.offsets.iter() {
219                v.push_unchecked(core::slice::from_raw_parts(*ptr, self.frames));
220            }
221        }
222
223        v
224    }
225
226    /// Get all channels as mutable slices. Each slice will have a length of `self.frames()`.
227    #[inline]
228    pub fn as_mut_slices(&mut self) -> ArrayVec<&mut [T], MAX_CHANNELS> {
229        let mut v = ArrayVec::new();
230
231        // SAFETY:
232        //
233        // * The constructors ensure that the pointed-to data vec has a length of at
234        // least `frames * self.channels()`.
235        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
236        // of the struct.
237        // * `self` is borrowed as mutable, and none of these slices overlap, so all
238        // mutability rules are being upheld.
239        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
240        unsafe {
241            for ptr in self.offsets.iter() {
242                v.push_unchecked(core::slice::from_raw_parts_mut(*ptr, self.frames));
243            }
244        }
245
246        v
247    }
248
249    /// Get all channels as immutable slices with the given length in frames.
250    ///
251    /// If `frames > self.frames()`, then each slice will have a length of `self.frames()`
252    /// instead.
253    #[inline]
254    pub fn as_slices_with_length(&self, frames: usize) -> ArrayVec<&[T], MAX_CHANNELS> {
255        let frames = frames.min(self.frames);
256        let mut v = ArrayVec::new();
257
258        // SAFETY:
259        //
260        // * The constructors ensure that the pointed-to data vec has a length of at
261        // least `frames * self.channels()`.
262        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
263        // of the struct.
264        // * We have constrained `frames` above.
265        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
266        unsafe {
267            for ptr in self.offsets.iter() {
268                v.push_unchecked(core::slice::from_raw_parts(*ptr, frames));
269            }
270        }
271
272        v
273    }
274
275    /// Get all channels as mutable slices with the given length in frames.
276    ///
277    /// If `frames > self.frames()`, then each slice will have a length of `self.frames()`
278    /// instead.
279    #[inline]
280    pub fn as_mut_slices_with_length(&mut self, frames: usize) -> ArrayVec<&mut [T], MAX_CHANNELS> {
281        let frames = frames.min(self.frames);
282        let mut v = ArrayVec::new();
283
284        // SAFETY:
285        //
286        // * The constructors ensure that the pointed-to data vec has a length of at
287        // least `frames * self.channels()`.
288        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
289        // of the struct.
290        // * We have constrained `frames` above.
291        // * `self` is borrowed as mutable, and none of these slices overlap, so all
292        // mutability rules are being upheld.
293        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
294        unsafe {
295            for ptr in self.offsets.iter() {
296                v.push_unchecked(core::slice::from_raw_parts_mut(*ptr, frames));
297            }
298        }
299
300        v
301    }
302
303    /// Get all channels as immutable slices in the given range.
304    ///
305    /// If all or part of the range falls out of bounds, then only the part that falls
306    /// within range will be returned.
307    #[inline]
308    pub fn as_slices_with_range(&self, range: Range<usize>) -> ArrayVec<&[T], MAX_CHANNELS> {
309        let start_frame = range.start.min(self.frames);
310        let frames = range.end.min(self.frames) - start_frame;
311
312        let mut v = ArrayVec::new();
313
314        // SAFETY:
315        //
316        // * The constructors ensure that the pointed-to data vec has a length of at
317        // least `frames * self.channels()`.
318        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
319        // of the struct.
320        // * We have constrained the given range above.
321        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
322        unsafe {
323            for ptr in self.offsets.iter() {
324                v.push_unchecked(core::slice::from_raw_parts(ptr.add(start_frame), frames));
325            }
326        }
327
328        v
329    }
330
331    /// Get all channels as mutable slices in the given range.
332    ///
333    /// If all or part of the range falls out of bounds, then only the part that falls
334    /// within range will be returned.
335    #[inline]
336    pub fn as_mut_slices_with_range(
337        &mut self,
338        range: Range<usize>,
339    ) -> ArrayVec<&mut [T], MAX_CHANNELS> {
340        let start_frame = range.start.min(self.frames);
341        let frames = range.end.min(self.frames) - start_frame;
342
343        let mut v = ArrayVec::new();
344
345        // SAFETY:
346        //
347        // * The constructors ensure that the pointed-to data vec has a length of at
348        // least `frames * self.channels()`.
349        // * The Vec is pinned and cannot be moved, so the pointers are valid for the lifetime
350        // of the struct.
351        // * We have constrained the given range above.
352        // * `self` is borrowed as mutable, and none of these slices overlap, so all
353        // mutability rules are being upheld.
354        // * We have asserted at compile-time that `MAX_CHANNELS` is non-zero.
355        unsafe {
356            for ptr in self.offsets.iter() {
357                v.push_unchecked(core::slice::from_raw_parts_mut(
358                    ptr.add(start_frame),
359                    frames,
360                ));
361            }
362        }
363
364        v
365    }
366
367    /// Get the entire contents of the buffer as a single immutable slice.
368    pub fn raw(&self) -> &[T] {
369        &self.data
370    }
371
372    /// Get the entire contents of the buffer as a single mutable slice.
373    pub fn raw_mut(&mut self) -> &mut [T] {
374        &mut self.data
375    }
376
377    /// Clear all data with the default value.
378    pub fn clear(&mut self) {
379        self.raw_mut().fill(T::default());
380    }
381
382    /// Clear all data in each channel up to `frames` with the default value.
383    pub fn clear_frames(&mut self, frames: usize) {
384        for ch in self.as_mut_slices_with_length(frames) {
385            ch.fill(T::default());
386        }
387    }
388
389    #[inline(always)]
390    pub fn as_ref<'a>(&'a self) -> VarChannelBufferRef<'a, T, MAX_CHANNELS> {
391        // SAFETY:
392        // * The constructors have the same invariants as `VarChannelBufferRef`.
393        // * `ArrayVec<*const T; MAX_CHANNELS>` and `ArrayVec<*mut T; MAX_CHANNELS>`
394        // are interchangeable bit-for-bit.
395        unsafe {
396            VarChannelBufferRef::from_raw(
397                &self.data,
398                core::mem::transmute_copy(&self.offsets),
399                self.frames,
400            )
401        }
402    }
403
404    #[inline(always)]
405    pub fn as_mut<'a>(&'a mut self) -> VarChannelBufferRefMut<'a, T, MAX_CHANNELS> {
406        // SAFETY: The constructors have the same invariants as `VarChannelBufferRefMut`.
407        unsafe {
408            VarChannelBufferRefMut::from_raw(&mut self.data, self.offsets.clone(), self.frames)
409        }
410    }
411}
412
413impl<T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize> Index<usize>
414    for VarChannelBuffer<T, MAX_CHANNELS>
415{
416    type Output = [T];
417
418    #[inline(always)]
419    fn index(&self, index: usize) -> &Self::Output {
420        self.channel(index).unwrap()
421    }
422}
423
424impl<T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize> IndexMut<usize>
425    for VarChannelBuffer<T, MAX_CHANNELS>
426{
427    #[inline(always)]
428    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
429        self.channel_mut(index).unwrap()
430    }
431}
432
433impl<T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize> Default
434    for VarChannelBuffer<T, MAX_CHANNELS>
435{
436    fn default() -> Self {
437        Self::empty()
438    }
439}
440
441impl<'a, T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize>
442    Into<VarChannelBufferRef<'a, T, MAX_CHANNELS>> for &'a VarChannelBuffer<T, MAX_CHANNELS>
443{
444    #[inline(always)]
445    fn into(self) -> VarChannelBufferRef<'a, T, MAX_CHANNELS> {
446        self.as_ref()
447    }
448}
449
450impl<'a, T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize>
451    Into<VarChannelBufferRefMut<'a, T, MAX_CHANNELS>>
452    for &'a mut VarChannelBuffer<T, MAX_CHANNELS>
453{
454    #[inline(always)]
455    fn into(self) -> VarChannelBufferRefMut<'a, T, MAX_CHANNELS> {
456        self.as_mut()
457    }
458}
459
460impl<T: Clone + Copy + Default + Sized + Unpin, const MAX_CHANNELS: usize> Into<Vec<T>>
461    for VarChannelBuffer<T, MAX_CHANNELS>
462{
463    fn into(self) -> Vec<T> {
464        Pin::<Vec<T>>::into_inner(self.data)
465    }
466}
467
468impl<T: Clone + Copy + Default + Sized + Unpin, const CHANNELS: usize> Clone
469    for VarChannelBuffer<T, CHANNELS>
470{
471    fn clone(&self) -> Self {
472        // SAFETY: We initialize all the data below.
473        let mut new_self = unsafe { Self::new_uninit(self.channels(), self.frames) };
474
475        new_self.raw_mut().copy_from_slice(self.raw());
476
477        new_self
478    }
479}
480
481// # SAFETY: All the stored pointers are valid for the lifetime of the struct, and
482// the public API prevents misuse of the pointers.
483unsafe impl<T: Clone + Copy + Default + Sized + Unpin, const CHANNELS: usize> Send
484    for VarChannelBuffer<T, CHANNELS>
485{
486}
487// # SAFETY: All the stored pointers are valid for the lifetime of the struct, and
488// the public API prevents misuse of the pointers.
489unsafe impl<T: Clone + Copy + Default + Sized + Unpin, const CHANNELS: usize> Sync
490    for VarChannelBuffer<T, CHANNELS>
491{
492}