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