rotary_core/
buf.rs

1//! Trait for dealing with abstract channel buffers.
2
3use crate::channel::{Channel, ChannelMut};
4use crate::sample::Sample;
5
6mod skip;
7pub use self::skip::Skip;
8
9mod limit;
10pub use self::limit::Limit;
11
12mod chunk;
13pub use self::chunk::Chunk;
14
15mod tail;
16pub use self::tail::Tail;
17
18/// Trait used to describe a buffer that knows exactly how many frames it has
19/// regardless of if it's sized or not.
20///
21/// # Examples
22///
23/// ```rust
24/// use rotary::ExactSizeBuf;
25///
26/// fn test<T>(buf: T) where T: ExactSizeBuf {
27///     assert_eq!(buf.frames(), 4);
28/// }
29///
30/// test(rotary::interleaved![[0i16; 4]; 4]);
31/// test(rotary::sequential![[0i16; 4]; 4]);
32/// test(rotary::dynamic![[0i16; 4]; 4]);
33/// test(rotary::wrap::interleaved([0i16; 16], 4));
34/// test(rotary::wrap::sequential([0i16; 16], 4));
35/// ```
36pub trait ExactSizeBuf {
37    /// The number of frames in a buffer.
38    ///
39    /// # Examples
40    ///
41    /// ```rust
42    /// use rotary::ExactSizeBuf;
43    ///
44    /// fn test<T>(buf: T) where T: ExactSizeBuf {
45    ///     assert_eq!(buf.frames(), 4);
46    /// }
47    ///
48    /// test(rotary::interleaved![[0i16; 4]; 4]);
49    /// test(rotary::sequential![[0i16; 4]; 4]);
50    /// test(rotary::dynamic![[0i16; 4]; 4]);
51    /// test(rotary::wrap::interleaved([0i16; 16], 4));
52    /// test(rotary::wrap::sequential([0i16; 16], 4));
53    /// ```
54    fn frames(&self) -> usize;
55}
56
57/// Trait implemented for buffers that can be resized.
58pub trait ResizableBuf {
59    /// Resize the number of frames in the buffer.
60    fn resize(&mut self, frames: usize);
61
62    /// Resize the buffer to match the given topology.
63    fn resize_topology(&mut self, channels: usize, frames: usize);
64}
65
66/// A trait describing an immutable audio buffer.
67pub trait Buf<T> {
68    /// A typical number of frames in the buffer, if known.
69    fn frames_hint(&self) -> Option<usize>;
70
71    /// The number of channels in the buffer.
72    fn channels(&self) -> usize;
73
74    /// Return a handler to the buffer associated with the channel.
75    ///
76    /// Note that we don't access the buffer for the underlying channel directly
77    /// as a linear buffer like `&[T]`, because the underlying representation
78    /// might be different.
79    ///
80    /// We must instead make use of the various utility functions found on
81    /// [Channel] to copy data out of the channel.
82    ///
83    /// # Panics
84    ///
85    /// Panics if the specified channel is out of bound as reported by
86    /// [Buf::channels].
87    fn channel(&self, channel: usize) -> Channel<'_, T>;
88
89    /// Construct a new buffer where `n` frames are skipped.
90    ///
91    /// # Examples
92    ///
93    /// ```rust
94    /// use rotary::{Buf as _, BufMut as _};
95    ///
96    /// let mut from = rotary::interleaved![[0.0f32; 4]; 2];
97    /// *from.frame_mut(0, 2).unwrap() = 1.0;
98    /// *from.frame_mut(0, 3).unwrap() = 1.0;
99    ///
100    /// let mut to = rotary::Interleaved::<f32>::with_topology(2, 4);
101    ///
102    /// to.channel_mut(0).copy_from((&from).skip(2).channel(0));
103    /// assert_eq!(to.as_slice(), &[1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
104    /// ```
105    ///
106    /// Test with a mutable buffer.
107    ///
108    /// ```rust
109    /// use rotary::{Buf as _, BufMut as _};
110    ///
111    /// let mut buffer = rotary::Interleaved::with_topology(2, 4);
112    ///
113    /// (&mut buffer).skip(2).channel_mut(0).copy_from_slice(&[1.0, 1.0]);
114    ///
115    /// assert_eq!(buffer.as_slice(), &[0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0])
116    /// ```
117    fn skip(self, n: usize) -> Skip<Self>
118    where
119        Self: Sized,
120    {
121        Skip::new(self, n)
122    }
123
124    /// Construct a new buffer where `n` frames are skipped.
125    ///
126    /// # Examples
127    ///
128    /// ```rust
129    /// use rotary::Buf as _;
130    /// use rotary::buf;
131    ///
132    /// let from = rotary::interleaved![[1.0f32; 4]; 2];
133    /// let mut to = rotary::interleaved![[0.0f32; 4]; 2];
134    ///
135    /// buf::copy(from, (&mut to).tail(2));
136    ///
137    /// assert_eq!(to.as_slice(), &[0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0]);
138    /// ```
139    fn tail(self, n: usize) -> Tail<Self>
140    where
141        Self: Sized,
142    {
143        Tail::new(self, n)
144    }
145
146    /// Limit the channel buffer to `limit` number of frames.
147    ///
148    /// # Examples
149    ///
150    /// ```rust
151    /// use rotary::{Buf as _, BufMut as _};
152    ///
153    /// let from = rotary::interleaved![[1.0f32; 4]; 2];
154    /// let mut to = rotary::Interleaved::<f32>::with_topology(2, 4);
155    ///
156    /// to.channel_mut(0).copy_from(from.limit(2).channel(0));
157    /// assert_eq!(to.as_slice(), &[1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
158    /// ```
159    fn limit(self, limit: usize) -> Limit<Self>
160    where
161        Self: Sized,
162    {
163        Limit::new(self, limit)
164    }
165
166    /// Construct a range of frames corresponds to the chunk with `len` and
167    /// position `n`.
168    ///
169    /// Which is the range `n * len .. n * len + len`.
170    ///
171    /// # Examples
172    ///
173    /// ```rust
174    /// use rotary::{Buf as _, BufMut as _};
175    ///
176    /// let from = rotary::interleaved![[1.0f32; 4]; 2];
177    /// let mut to = rotary::interleaved![[0.0f32; 4]; 2];
178    ///
179    /// (&mut to).chunk(1, 2).channel_mut(0).copy_from(from.channel(0));
180    /// assert_eq!(to.as_slice(), &[0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
181    /// ```
182    fn chunk(self, n: usize, len: usize) -> Chunk<Self>
183    where
184        Self: Sized,
185    {
186        Chunk::new(self, n, len)
187    }
188}
189
190impl<B> ExactSizeBuf for &B
191where
192    B: ?Sized + ExactSizeBuf,
193{
194    fn frames(&self) -> usize {
195        (**self).frames()
196    }
197}
198
199impl<B, T> Buf<T> for &B
200where
201    B: Buf<T>,
202{
203    fn frames_hint(&self) -> Option<usize> {
204        (**self).frames_hint()
205    }
206
207    fn channels(&self) -> usize {
208        (**self).channels()
209    }
210
211    fn channel(&self, channel: usize) -> Channel<'_, T> {
212        (**self).channel(channel)
213    }
214}
215
216/// A trait describing a mutable audio buffer.
217pub trait BufMut<T>: Buf<T> {
218    /// Return a mutable handler to the buffer associated with the channel.
219    ///
220    /// # Panics
221    ///
222    /// Panics if the specified channel is out of bound as reported by
223    /// [Buf::channels].
224    fn channel_mut(&mut self, channel: usize) -> ChannelMut<'_, T>;
225}
226
227impl<B> ExactSizeBuf for &mut B
228where
229    B: ?Sized + ExactSizeBuf,
230{
231    fn frames(&self) -> usize {
232        (**self).frames()
233    }
234}
235
236impl<B, T> Buf<T> for &mut B
237where
238    B: ?Sized + Buf<T>,
239{
240    fn frames_hint(&self) -> Option<usize> {
241        (**self).frames_hint()
242    }
243
244    fn channels(&self) -> usize {
245        (**self).channels()
246    }
247
248    fn channel(&self, channel: usize) -> Channel<'_, T> {
249        (**self).channel(channel)
250    }
251}
252
253impl<B> ResizableBuf for &mut B
254where
255    B: ?Sized + ResizableBuf,
256{
257    fn resize(&mut self, frames: usize) {
258        (**self).resize(frames);
259    }
260
261    fn resize_topology(&mut self, channels: usize, frames: usize) {
262        (**self).resize_topology(channels, frames);
263    }
264}
265
266impl<B, T> BufMut<T> for &mut B
267where
268    B: ?Sized + BufMut<T>,
269{
270    fn channel_mut(&mut self, channel: usize) -> ChannelMut<'_, T> {
271        (**self).channel_mut(channel)
272    }
273}
274
275impl<T> Buf<T> for Vec<Vec<T>> {
276    fn frames_hint(&self) -> Option<usize> {
277        Some(self.get(0)?.len())
278    }
279
280    fn channels(&self) -> usize {
281        self.len()
282    }
283
284    fn channel(&self, channel: usize) -> Channel<'_, T> {
285        Channel::linear(&self[channel])
286    }
287}
288
289impl<T> ResizableBuf for Vec<Vec<T>>
290where
291    T: Sample,
292{
293    fn resize(&mut self, frames: usize) {
294        for buf in self.iter_mut() {
295            buf.resize(frames, T::ZERO);
296        }
297    }
298
299    fn resize_topology(&mut self, channels: usize, frames: usize) {
300        for buf in self.iter_mut() {
301            buf.resize(frames, T::ZERO);
302        }
303
304        for _ in self.len()..channels {
305            self.push(vec![T::ZERO; frames]);
306        }
307    }
308}
309
310impl<T> BufMut<T> for Vec<Vec<T>> {
311    fn channel_mut(&mut self, channel: usize) -> ChannelMut<'_, T> {
312        ChannelMut::linear(&mut self[channel])
313    }
314}
315
316impl<T> Buf<T> for [Vec<T>] {
317    fn frames_hint(&self) -> Option<usize> {
318        Some(self.get(0)?.len())
319    }
320
321    fn channels(&self) -> usize {
322        self.as_ref().len()
323    }
324
325    fn channel(&self, channel: usize) -> Channel<'_, T> {
326        Channel::linear(&self.as_ref()[channel])
327    }
328}