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}