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}