audio_core/
buf.rs

1//! Trait for dealing with abstract channel buffers.
2
3use crate::Channel;
4
5#[macro_use]
6mod macros;
7
8mod skip;
9pub use self::skip::Skip;
10
11mod limit;
12pub use self::limit::Limit;
13
14mod tail;
15pub use self::tail::Tail;
16
17/// The base trait available to all audio buffers.
18///
19/// This provides information which is available to all buffers, such as the
20/// number of channels.
21///
22/// ```
23/// let buf = audio::interleaved![[0; 4]; 2];
24/// assert_eq!(buf.channels(), 2);
25/// ```
26///
27/// It also carries a number of slicing combinators, wuch as [skip][Buf::skip]
28/// and [limit][Buf::limit] which allows an audio buffer to be sliced as needed.
29///
30///
31/// ```
32/// use audio::{Buf, ExactSizeBuf};
33///
34/// let buf = audio::interleaved![[0; 4]; 2];
35///
36/// assert_eq!(buf.channels(), 2);
37/// assert_eq!(buf.limit(2).frames(), 2);
38/// ```
39pub trait Buf {
40    /// The type of a single sample.
41    type Sample;
42
43    /// The type of the channel container.
44    type Channel<'this>: Channel<Sample = Self::Sample>
45    where
46        Self: 'this;
47
48    /// An iterator over available channels.
49    type IterChannels<'this>: Iterator<Item = Self::Channel<'this>>
50    where
51        Self: 'this;
52
53    /// A typical number of frames for each channel in the buffer, if known.
54    ///
55    /// If you only want to support buffers which have exact sizes use
56    /// [ExactSizeBuf][crate::ExactSizeBuf].
57    ///
58    /// This is only a best effort hint. We can't require any [Buf] to know the
59    /// exact number of frames, because we want to be able to implement it for
60    /// types which does not keep track of the exact number of frames it expects
61    /// each channel to have such as `Vec<Vec<i16>>`.
62    ///
63    /// ```
64    /// use audio::Buf;
65    ///
66    /// fn test(buf: impl Buf) {
67    ///     assert_eq!(buf.channels(), 2);
68    ///     assert_eq!(buf.frames_hint(), Some(4));
69    /// }
70    ///
71    /// test(audio::wrap::dynamic(vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]]));
72    /// ```
73    ///
74    /// But it should be clear that such a buffer supports a variable number of
75    /// frames in each channel.
76    ///
77    /// ```
78    /// use audio::{Buf, Channel};
79    ///
80    /// fn test(buf: impl Buf<Sample = i16>) {
81    ///     assert_eq!(buf.channels(), 2);
82    ///     assert_eq!(buf.frames_hint(), Some(4));
83    ///
84    ///     assert_eq!(buf.get_channel(0).map(|c| c.len()), Some(4));
85    ///     assert_eq!(buf.get_channel(1).map(|c| c.len()), Some(2));
86    /// }
87    ///
88    /// test(audio::wrap::dynamic(vec![vec![1, 2, 3, 4], vec![5, 6]]));
89    /// ```
90    fn frames_hint(&self) -> Option<usize>;
91
92    /// The number of channels in the buffer.
93    ///
94    /// # Examples
95    ///
96    /// ```
97    /// use audio::{Buf, Channel};
98    ///
99    /// fn test(buf: impl Buf<Sample = i16>) {
100    ///     assert_eq!(buf.channels(), 2);
101    ///
102    ///     assert_eq! {
103    ///         buf.get_channel(0).unwrap().iter().collect::<Vec<_>>(),
104    ///         &[1, 2, 3, 4],
105    ///     }
106    ///
107    ///     assert_eq! {
108    ///         buf.get_channel(1).unwrap().iter().collect::<Vec<_>>(),
109    ///         &[5, 6, 7, 8],
110    ///     }
111    /// }
112    ///
113    /// test(audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]]);
114    /// test(audio::wrap::interleaved(&[1, 5, 2, 6, 3, 7, 4, 8], 2));
115    /// test(audio::wrap::dynamic(vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]]));
116    /// ```
117    fn channels(&self) -> usize;
118
119    /// Return a handler to the buffer associated with the channel.
120    ///
121    /// Note that we don't access the buffer for the underlying channel directly
122    /// as a linear buffer like `&[T]`, because the underlying representation
123    /// might be different.
124    ///
125    /// We must instead make use of the various utility functions found on
126    /// [Channel] to copy data out of the channel.
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// use audio::{Buf, Channel};
132    ///
133    /// fn test(buf: impl Buf<Sample = i16>) {
134    ///     let chan = buf.get_channel(1).unwrap();
135    ///     chan.iter().eq([5, 6, 7, 8]);
136    /// }
137    ///
138    /// test(audio::dynamic![[1, 2, 3, 4], [5, 6, 7, 8]]);
139    /// test(audio::sequential![[1, 2, 3, 4], [5, 6, 7, 8]]);
140    /// test(audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]]);
141    /// ```
142    fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>>;
143
144    /// Construct an iterator over all the channels in the audio buffer.
145    ///
146    /// # Examples
147    ///
148    /// ```
149    /// use audio::{Buf, Channel};
150    ///
151    /// fn test(buf: impl Buf<Sample = i16>) {
152    ///     let chan = buf.iter_channels().nth(1).unwrap();
153    ///     chan.iter().eq([5, 6, 7, 8]);
154    /// }
155    ///
156    /// test(audio::dynamic![[1, 2, 3, 4], [5, 6, 7, 8]]);
157    /// test(audio::sequential![[1, 2, 3, 4], [5, 6, 7, 8]]);
158    /// test(audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]]);
159    /// ```
160    fn iter_channels(&self) -> Self::IterChannels<'_>;
161
162    /// Construct a wrapper around this buffer that skips the first `n` frames.
163    ///
164    /// # Examples
165    ///
166    /// ```
167    /// use audio::Buf;
168    /// use audio::buf;
169    ///
170    /// let from = audio::interleaved![[0, 0, 1, 1], [0; 4]];
171    /// let mut to = audio::buf::Interleaved::with_topology(2, 4);
172    ///
173    /// buf::copy(from.skip(2), &mut to);
174    ///
175    /// assert_eq!(to.as_slice(), &[1, 0, 1, 0, 0, 0, 0, 0]);
176    /// ```
177    ///
178    /// With a mutable buffer.
179    ///
180    /// ```
181    /// use audio::Buf;
182    /// use audio::{buf, wrap};
183    ///
184    /// let from = wrap::interleaved(&[1, 1, 1, 1, 1, 1, 1, 1], 2);
185    /// let mut to = audio::buf::Interleaved::with_topology(2, 4);
186    ///
187    /// buf::copy(from, (&mut to).skip(2));
188    ///
189    /// assert_eq!(to.as_slice(), &[0, 0, 0, 0, 1, 1, 1, 1])
190    /// ```
191    fn skip(self, n: usize) -> Skip<Self>
192    where
193        Self: Sized,
194    {
195        Skip::new(self, n)
196    }
197
198    /// Construct a wrapper around this buffer that skips to the last `n` frames.
199    ///
200    /// # Examples
201    ///
202    /// ```
203    /// use audio::Buf;
204    /// use audio::buf;
205    ///
206    /// let from = audio::interleaved![[1; 4]; 2];
207    /// let mut to = audio::interleaved![[0; 4]; 2];
208    ///
209    /// buf::copy(from, (&mut to).tail(2));
210    ///
211    /// assert_eq!(to.as_slice(), &[0, 0, 0, 0, 1, 1, 1, 1]);
212    /// ```
213    ///
214    /// The [tail][Buf::tail] of a buffer adjusts all functions associated with
215    /// the [Buf]:
216    ///
217    /// ```
218    /// use audio::{Buf, ExactSizeBuf};
219    ///
220    /// let buf = audio::interleaved![[1, 2, 3, 4]; 2];
221    ///
222    /// assert_eq!((&buf).tail(0).channels(), 2);
223    /// assert_eq!((&buf).tail(0).frames_hint(), Some(0));
224    ///
225    /// assert_eq!((&buf).tail(1).channels(), 2);
226    /// assert_eq!((&buf).tail(1).frames_hint(), Some(1));
227    ///
228    /// assert_eq!((&buf).tail(5).channels(), 2);
229    /// assert_eq!((&buf).tail(5).frames_hint(), Some(4));
230    ///
231    /// for chan in buf.tail(2).iter_channels() {
232    ///     assert!(chan.iter().eq([3, 4]));
233    /// }
234    /// ```
235    fn tail(self, n: usize) -> Tail<Self>
236    where
237        Self: Sized,
238    {
239        Tail::new(self, n)
240    }
241
242    /// Construct a wrapper around this buffer which stops after `limit` frames.
243    ///
244    /// # Examples
245    ///
246    /// ```
247    /// use audio::Buf;
248    /// use audio::buf;
249    ///
250    /// let from = audio::interleaved![[1; 4]; 2];
251    /// let mut to = audio::buf::Interleaved::with_topology(2, 4);
252    ///
253    /// buf::copy(from, (&mut to).limit(2));
254    ///
255    /// assert_eq!(to.as_slice(), &[1, 1, 1, 1, 0, 0, 0, 0]);
256    /// ```
257    ///
258    /// The [limit][Buf::limit] of a buffer adjusts all functions associated
259    /// with the [Buf]:
260    ///
261    /// ```
262    /// use audio::Buf;
263    ///
264    /// let buf = audio::interleaved![[1, 2, 3, 4]; 2];
265    ///
266    /// assert_eq!((&buf).limit(0).channels(), 2);
267    /// assert_eq!((&buf).limit(0).frames_hint(), Some(0));
268    ///
269    /// assert_eq!((&buf).limit(1).channels(), 2);
270    /// assert_eq!((&buf).limit(1).frames_hint(), Some(1));
271    ///
272    /// assert_eq!((&buf).limit(5).channels(), 2);
273    /// assert_eq!((&buf).limit(5).frames_hint(), Some(4));
274    ///
275    /// for chan in buf.limit(2).iter_channels() {
276    ///     assert!(chan.iter().eq([1, 2]));
277    /// }
278    /// ```
279    fn limit(self, limit: usize) -> Limit<Self>
280    where
281        Self: Sized,
282    {
283        Limit::new(self, limit)
284    }
285}
286
287impl<B> Buf for &B
288where
289    B: ?Sized + Buf,
290{
291    type Sample = B::Sample;
292
293    type Channel<'a>
294        = B::Channel<'a>
295    where
296        Self: 'a;
297
298    type IterChannels<'a>
299        = B::IterChannels<'a>
300    where
301        Self: 'a;
302
303    #[inline]
304    fn frames_hint(&self) -> Option<usize> {
305        (**self).frames_hint()
306    }
307
308    #[inline]
309    fn channels(&self) -> usize {
310        (**self).channels()
311    }
312
313    #[inline]
314    fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>> {
315        (**self).get_channel(channel)
316    }
317
318    #[inline]
319    fn iter_channels(&self) -> Self::IterChannels<'_> {
320        (**self).iter_channels()
321    }
322}
323
324impl<B> Buf for &mut B
325where
326    B: ?Sized + Buf,
327{
328    type Sample = B::Sample;
329
330    type Channel<'this>
331        = B::Channel<'this>
332    where
333        Self: 'this;
334
335    type IterChannels<'this>
336        = B::IterChannels<'this>
337    where
338        Self: 'this;
339
340    #[inline]
341    fn frames_hint(&self) -> Option<usize> {
342        (**self).frames_hint()
343    }
344
345    #[inline]
346    fn channels(&self) -> usize {
347        (**self).channels()
348    }
349
350    #[inline]
351    fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>> {
352        (**self).get_channel(channel)
353    }
354
355    #[inline]
356    fn iter_channels(&self) -> Self::IterChannels<'_> {
357        (**self).iter_channels()
358    }
359}