audio_core/interleaved_buf_mut.rs
1use core::ptr;
2
3use crate::InterleavedBuf;
4
5/// A trait describing a buffer that is interleaved and mutable.
6///
7/// This allows for accessing the raw underlying interleaved buffer.
8pub trait InterleavedBufMut: InterleavedBuf {
9 /// Access the underlying interleaved mutable buffer.
10 ///
11 /// # Examples
12 ///
13 /// ```
14 /// use audio::{InterleavedBuf, InterleavedBufMut, Buf, Channel};
15 /// use audio::wrap;
16 ///
17 /// fn test(mut buffer: impl Buf<Sample = i16> + InterleavedBufMut<Sample = i16>) {
18 /// buffer.as_interleaved_mut().copy_from_slice(&[1, 1, 2, 2, 3, 3, 4, 4]);
19 ///
20 /// assert_eq! {
21 /// buffer.get_channel(0).unwrap().iter().collect::<Vec<_>>(),
22 /// &[1, 2, 3, 4],
23 /// };
24 ///
25 /// assert_eq! {
26 /// buffer.get_channel(1).unwrap().iter().collect::<Vec<_>>(),
27 /// &[1, 2, 3, 4],
28 /// };
29 ///
30 /// assert_eq!(buffer.as_interleaved(), &[1, 1, 2, 2, 3, 3, 4, 4]);
31 /// }
32 ///
33 /// test(audio::interleaved![[0; 4]; 2]);
34 /// let mut buf = [0; 8];
35 /// test(wrap::interleaved(&mut buf, 2));
36 /// ```
37 fn as_interleaved_mut(&mut self) -> &mut [Self::Sample];
38
39 /// Access a pointer to the underlying interleaved mutable buffer.
40 ///
41 /// The length of the buffer is unspecified, unless preceded by a call to
42 /// [try_reserve]. Assuming the call doesn't panic, the pointed to buffer is
43 /// guaranteed to be both allocated and initialized up until the number of
44 /// frames as specified as argument to [try_reserve].
45 ///
46 /// [try_reserve]: crate::ResizableBuf::try_reserve
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// use audio::{Buf, Channel, ResizableBuf, InterleavedBufMut};
52 /// # unsafe fn fill_with_ones(buf: std::ptr::NonNull<i16>, len: usize) -> (usize, usize) {
53 /// # let buf = std::slice::from_raw_parts_mut(buf.as_ptr(), len);
54 /// #
55 /// # for (o, b) in buf.iter_mut().zip(std::iter::repeat(1)) {
56 /// # *o = b;
57 /// # }
58 /// #
59 /// # (2, len / 2)
60 /// # }
61 ///
62 /// fn test(mut buffer: impl InterleavedBufMut<Sample = i16> + ResizableBuf) {
63 /// assert!(buffer.try_reserve(16));
64 /// // Note: call fills the buffer with ones.
65 /// // Safety: We've initialized exactly 16 frames before calling this
66 /// // function.
67 /// unsafe {
68 /// let (channels, frames) = fill_with_ones(buffer.as_interleaved_mut_ptr(), 16);
69 /// buffer.set_interleaved_topology(channels, frames);
70 /// }
71 /// }
72 ///
73 /// let mut buf = audio::buf::Interleaved::new();
74 /// test(&mut buf);
75 ///
76 /// assert_eq! {
77 /// buf.get_channel(0).unwrap().iter().collect::<Vec<_>>(),
78 /// &[1, 1, 1, 1, 1, 1, 1, 1],
79 /// };
80 /// assert_eq! {
81 /// buf.get_channel(1).unwrap().iter().collect::<Vec<_>>(),
82 /// &[1, 1, 1, 1, 1, 1, 1, 1],
83 /// };
84 /// ```
85 fn as_interleaved_mut_ptr(&mut self) -> ptr::NonNull<Self::Sample>;
86
87 /// Specify the topology of the underlying interleaved buffer.
88 ///
89 /// # Safety
90 ///
91 /// The caller must ensure that the topology of the underlying buffer has
92 /// been updated to match the specified parameters.
93 ///
94 /// # Examples
95 ///
96 /// ```
97 /// use audio::{Buf, Channel, ResizableBuf, InterleavedBufMut};
98 /// # unsafe fn fill_with_ones(buf: std::ptr::NonNull<i16>, len: usize) -> (usize, usize) {
99 /// # let buf = std::slice::from_raw_parts_mut(buf.as_ptr(), len);
100 /// #
101 /// # for (o, b) in buf.iter_mut().zip(std::iter::repeat(1)) {
102 /// # *o = b;
103 /// # }
104 /// #
105 /// # (2, len / 2)
106 /// # }
107 ///
108 /// fn test(mut buffer: impl InterleavedBufMut<Sample = i16> + ResizableBuf) {
109 /// assert!(buffer.try_reserve(16));
110 /// // Note: call fills the buffer with ones.
111 /// // Safety: We've initialized exactly 16 frames before calling this
112 /// // function.
113 /// unsafe {
114 /// let (channels, frames) = fill_with_ones(buffer.as_interleaved_mut_ptr(), 16);
115 /// buffer.set_interleaved_topology(channels, frames);
116 /// };
117 /// }
118 ///
119 /// let mut buf = audio::buf::Interleaved::new();
120 /// test(&mut buf);
121 ///
122 /// assert_eq! {
123 /// buf.get_channel(0).unwrap().iter().collect::<Vec<_>>(),
124 /// &[1, 1, 1, 1, 1, 1, 1, 1],
125 /// };
126 /// assert_eq! {
127 /// buf.get_channel(1).unwrap().iter().collect::<Vec<_>>(),
128 /// &[1, 1, 1, 1, 1, 1, 1, 1],
129 /// };
130 /// ```
131 unsafe fn set_interleaved_topology(&mut self, channels: usize, frames: usize);
132}
133
134impl<B> InterleavedBufMut for &mut B
135where
136 B: ?Sized + InterleavedBufMut,
137{
138 #[inline]
139 fn as_interleaved_mut(&mut self) -> &mut [Self::Sample] {
140 (**self).as_interleaved_mut()
141 }
142
143 #[inline]
144 fn as_interleaved_mut_ptr(&mut self) -> ptr::NonNull<Self::Sample> {
145 (**self).as_interleaved_mut_ptr()
146 }
147
148 #[inline]
149 unsafe fn set_interleaved_topology(&mut self, channels: usize, frames: usize) {
150 (**self).set_interleaved_topology(channels, frames);
151 }
152}