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}