rotary/sequential.rs
1//! A dynamically sized, multi-channel sequential audio buffer.
2
3use rotary_core::{Buf, BufMut, Channel, ChannelMut, ExactSizeBuf, ResizableBuf, Sample};
4use std::cmp;
5use std::fmt;
6use std::hash;
7use std::ops;
8use std::ptr;
9
10mod iter;
11pub use self::iter::{Iter, IterMut};
12
13/// A dynamically sized, multi-channel sequential audio buffer.
14///
15/// A *sequential* audio buffer stores all audio data sequentially in memory,
16/// one channel after another.
17///
18/// An audio buffer can only be resized if it contains a type which is
19/// sample-apt For more information of what this means, see [Sample].
20///
21/// Resizing the buffer might therefore cause a fair bit of copying, and for the
22/// worst cases, this might result in having to copy a memory region
23/// byte-by-byte since they might overlap.
24///
25/// Resized regions also aren't zeroed, so certain operations might cause stale
26/// data to be visible after a resize.
27///
28/// ```rust
29/// let mut buffer = rotary::Sequential::<f32>::with_topology(2, 4);
30/// buffer[0].copy_from_slice(&[1.0, 2.0, 3.0, 4.0]);
31/// buffer[1].copy_from_slice(&[2.0, 3.0, 4.0, 5.0]);
32///
33/// buffer.resize(3);
34///
35/// assert_eq!(&buffer[0], &[1.0, 2.0, 3.0]);
36/// assert_eq!(&buffer[1], &[2.0, 3.0, 4.0]);
37///
38/// buffer.resize(4);
39///
40/// assert_eq!(&buffer[0], &[1.0, 2.0, 3.0, 2.0]); // <- 2.0 is stale data.
41/// assert_eq!(&buffer[1], &[2.0, 3.0, 4.0, 5.0]); // <- 5.0 is stale data.
42/// ```
43///
44/// To access the full, currently assumed *valid* slice you can use
45/// [Sequential::as_slice] or [Sequential::into_vec].
46///
47/// ```rust
48/// let mut buffer = rotary::Sequential::<f32>::with_topology(2, 4);
49/// buffer[0].copy_from_slice(&[1.0, 2.0, 3.0, 4.0]);
50/// buffer[1].copy_from_slice(&[2.0, 3.0, 4.0, 5.0]);
51///
52/// buffer.resize(3);
53///
54/// assert_eq!(buffer.as_slice(), &[1.0, 2.0, 3.0, 2.0, 3.0, 4.0]);
55/// ```
56pub struct Sequential<T> {
57 data: Vec<T>,
58 channels: usize,
59 frames: usize,
60}
61
62impl<T> Sequential<T> {
63 /// Construct a new empty audio buffer.
64 ///
65 /// # Examples
66 ///
67 /// ```rust
68 /// let mut buffer = rotary::Sequential::<f32>::new();
69 ///
70 /// assert_eq!(buffer.frames(), 0);
71 /// ```
72 pub fn new() -> Self {
73 Self {
74 data: Vec::new(),
75 channels: 0,
76 frames: 0,
77 }
78 }
79
80 /// Allocate an audio buffer with the given topology. A "topology" is a
81 /// given number of `channels` and the corresponding number of `frames` in
82 /// their buffers.
83 ///
84 /// # Examples
85 ///
86 /// ```rust
87 /// let mut buffer = rotary::Sequential::<f32>::with_topology(4, 256);
88 ///
89 /// assert_eq!(buffer.frames(), 256);
90 /// assert_eq!(buffer.channels(), 4);
91 /// ```
92 pub fn with_topology(channels: usize, frames: usize) -> Self
93 where
94 T: Sample,
95 {
96 Self {
97 data: vec![T::ZERO; channels * frames],
98 channels,
99 frames,
100 }
101 }
102
103 /// Allocate an audio buffer from a fixed-size array.
104 ///
105 /// See [sequential!].
106 ///
107 /// # Examples
108 ///
109 /// ```rust
110 /// let mut buffer = rotary::sequential![[2.0; 256]; 4];
111 ///
112 /// assert_eq!(buffer.frames(), 256);
113 /// assert_eq!(buffer.channels(), 4);
114 ///
115 /// for chan in &buffer {
116 /// assert_eq!(chan, vec![2.0; 256]);
117 /// }
118 /// ```
119 pub fn from_vec(data: Vec<T>, channels: usize, frames: usize) -> Self {
120 Self {
121 data,
122 channels,
123 frames,
124 }
125 }
126
127 /// Allocate an audio buffer from a fixed-size array acting as a template
128 /// for all the channels.
129 ///
130 /// See [sequential!].
131 ///
132 /// # Examples
133 ///
134 /// ```rust
135 /// let mut buffer = rotary::Sequential::from_frames([1.0, 2.0, 3.0, 4.0], 2);
136 ///
137 /// assert_eq!(buffer.frames(), 4);
138 /// assert_eq!(buffer.channels(), 2);
139 ///
140 /// assert_eq!(buffer.as_slice(), &[1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0]);
141 /// ```
142 pub fn from_frames<const N: usize>(frames: [T; N], channels: usize) -> Self
143 where
144 T: Copy,
145 {
146 return Self {
147 data: data_from_frames(frames, channels),
148 channels,
149 frames: N,
150 };
151
152 fn data_from_frames<T, const N: usize>(frames: [T; N], channels: usize) -> Vec<T>
153 where
154 T: Copy,
155 {
156 let mut data = Vec::with_capacity(N * channels);
157
158 for _ in 0..channels {
159 data.extend(std::array::IntoIter::new(frames));
160 }
161
162 data
163 }
164 }
165
166 /// Take ownership of the backing vector.
167 ///
168 /// # Examples
169 ///
170 /// ```rust
171 /// let mut buffer = rotary::Sequential::<f32>::with_topology(2, 4);
172 /// buffer[0].copy_from_slice(&[1.0, 2.0, 3.0, 4.0]);
173 /// buffer[1].copy_from_slice(&[2.0, 3.0, 4.0, 5.0]);
174 ///
175 /// buffer.resize(3);
176 ///
177 /// assert_eq!(buffer.into_vec(), vec![1.0, 2.0, 3.0, 2.0, 3.0, 4.0])
178 /// ```
179 pub fn into_vec(self) -> Vec<T> {
180 self.data
181 }
182
183 /// Access the underlying vector as a slice.
184 ///
185 /// # Examples
186 ///
187 /// ```rust
188 /// let mut buffer = rotary::Sequential::<f32>::with_topology(2, 4);
189 ///
190 /// buffer[0].copy_from_slice(&[1.0, 2.0, 3.0, 4.0]);
191 /// buffer[1].copy_from_slice(&[2.0, 3.0, 4.0, 5.0]);
192 ///
193 /// buffer.resize(3);
194 ///
195 /// assert_eq!(buffer.as_slice(), &[1.0, 2.0, 3.0, 2.0, 3.0, 4.0])
196 /// ```
197 pub fn as_slice(&self) -> &[T] {
198 &self.data
199 }
200
201 /// Get the number of frames in the channels of an audio buffer.
202 ///
203 /// # Examples
204 ///
205 /// ```rust
206 /// let mut buffer = rotary::Sequential::<f32>::new();
207 ///
208 /// assert_eq!(buffer.frames(), 0);
209 /// buffer.resize(256);
210 /// assert_eq!(buffer.frames(), 256);
211 /// ```
212 pub fn frames(&self) -> usize {
213 self.frames
214 }
215
216 /// Check how many channels there are in the buffer.
217 ///
218 /// # Examples
219 ///
220 /// ```rust
221 /// let mut buffer = rotary::Sequential::<f32>::new();
222 ///
223 /// assert_eq!(buffer.channels(), 0);
224 /// buffer.resize_channels(2);
225 /// assert_eq!(buffer.channels(), 2);
226 /// ```
227 pub fn channels(&self) -> usize {
228 self.channels
229 }
230
231 /// Construct an iterator over all available channels.
232 ///
233 /// # Examples
234 ///
235 /// ```
236 /// use rand::Rng as _;
237 ///
238 /// let mut buffer = rotary::Sequential::<f32>::with_topology(4, 256);
239 ///
240 /// let all_zeros = vec![0.0; 256];
241 ///
242 /// for chan in buffer.iter() {
243 /// assert_eq!(chan, &all_zeros[..]);
244 /// }
245 /// ```
246 pub fn iter(&self) -> Iter<'_, T> {
247 Iter::new(&self.data, self.frames)
248 }
249
250 /// Construct a mutable iterator over all available channels.
251 ///
252 /// # Examples
253 ///
254 /// ```
255 /// use rand::Rng as _;
256 ///
257 /// let mut buffer = rotary::Sequential::<f32>::with_topology(4, 256);
258 /// let mut rng = rand::thread_rng();
259 ///
260 /// for chan in buffer.iter_mut() {
261 /// rng.fill(chan);
262 /// }
263 /// ```
264 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
265 IterMut::new(&mut self.data, self.frames)
266 }
267
268 /// Set the number of channels in use.
269 ///
270 /// If the size of the buffer increases as a result, the new channels will
271 /// be zeroed. If the size decreases, the channels that falls outside of the
272 /// new size will be dropped.
273 ///
274 /// # Examples
275 ///
276 /// ```rust
277 /// let mut buffer = rotary::Sequential::<f32>::new();
278 ///
279 /// assert_eq!(buffer.channels(), 0);
280 /// assert_eq!(buffer.frames(), 0);
281 ///
282 /// buffer.resize_channels(4);
283 /// buffer.resize(256);
284 ///
285 /// assert_eq!(buffer.channels(), 4);
286 /// assert_eq!(buffer.frames(), 256);
287 /// ```
288 pub fn resize_channels(&mut self, channels: usize)
289 where
290 T: Sample,
291 {
292 self.resize_inner(self.channels, self.frames, channels, self.frames);
293 }
294
295 /// Set the size of the buffer. The size is the size of each channel's
296 /// buffer.
297 ///
298 /// If the size of the buffer increases as a result, the new regions in the
299 /// frames will be zeroed. If the size decreases, the region will be left
300 /// untouched. So if followed by another increase, the data will be "dirty".
301 ///
302 /// # Examples
303 ///
304 /// ```rust
305 /// let mut buffer = rotary::Sequential::<f32>::new();
306 ///
307 /// assert_eq!(buffer.channels(), 0);
308 /// assert_eq!(buffer.frames(), 0);
309 ///
310 /// buffer.resize_channels(4);
311 /// buffer.resize(256);
312 ///
313 /// assert_eq!(buffer[1][128], 0.0);
314 /// buffer[1][128] = 42.0;
315 ///
316 /// assert_eq!(buffer.channels(), 4);
317 /// assert_eq!(buffer.frames(), 256);
318 /// ```
319 ///
320 /// Decreasing and increasing the size will modify the underlying buffer:
321 ///
322 /// ```rust
323 /// # let mut buffer = rotary::Sequential::<f32>::with_topology(4, 256);
324 /// assert_eq!(buffer[1][128], 0.0);
325 /// buffer[1][128] = 42.0;
326 ///
327 /// buffer.resize(64);
328 /// assert!(buffer[1].get(128).is_none());
329 ///
330 /// buffer.resize(256);
331 /// assert_eq!(buffer[1][128], 0.0);
332 /// ```
333 ///
334 /// # Stale data
335 ///
336 /// Resizing a channel doesn't "free" the underlying data or zero previously
337 /// initialized regions.
338 ///
339 /// Old regions which were previously sized out and ignored might contain
340 /// stale data from previous uses. So this should be kept in mind when
341 /// resizing this buffer dynamically.
342 ///
343 /// ```rust
344 /// let mut buffer = rotary::Sequential::<f32>::new();
345 ///
346 /// buffer.resize_channels(4);
347 /// buffer.resize(128);
348 ///
349 /// let expected = (0..128).map(|v| v as f32).collect::<Vec<_>>();
350 ///
351 /// for chan in buffer.iter_mut() {
352 /// for (s, v) in chan.iter_mut().zip(&expected) {
353 /// *s = *v;
354 /// }
355 /// }
356 ///
357 /// assert_eq!(buffer.get(0), Some(&expected[..]));
358 /// assert_eq!(buffer.get(1), Some(&expected[..]));
359 /// assert_eq!(buffer.get(2), Some(&expected[..]));
360 /// assert_eq!(buffer.get(3), Some(&expected[..]));
361 /// assert_eq!(buffer.get(4), None);
362 ///
363 /// buffer.resize_channels(2);
364 ///
365 /// assert_eq!(buffer.get(0), Some(&expected[..]));
366 /// assert_eq!(buffer.get(1), Some(&expected[..]));
367 /// assert_eq!(buffer.get(2), None);
368 ///
369 /// // shrink
370 /// buffer.resize(64);
371 ///
372 /// assert_eq!(buffer.get(0), Some(&expected[..64]));
373 /// assert_eq!(buffer.get(1), Some(&expected[..64]));
374 /// assert_eq!(buffer.get(2), None);
375 ///
376 /// // increase - this causes some weirdness.
377 /// buffer.resize(128);
378 ///
379 /// let first_overlapping = expected[..64]
380 /// .iter()
381 /// .chain(expected[..64].iter())
382 /// .copied()
383 /// .collect::<Vec<_>>();
384 ///
385 /// assert_eq!(buffer.get(0), Some(&first_overlapping[..]));
386 /// // Note: second channel matches perfectly up with an old channel that was
387 /// // masked out.
388 /// assert_eq!(buffer.get(1), Some(&expected[..]));
389 /// assert_eq!(buffer.get(2), None);
390 /// ```
391 pub fn resize(&mut self, frames: usize)
392 where
393 T: Sample,
394 {
395 self.resize_inner(self.channels, self.frames, self.channels, frames);
396 }
397
398 /// Get a reference to the buffer of the given channel.
399 ///
400 /// # Examples
401 ///
402 /// ```rust
403 /// let mut buffer = rotary::Sequential::<f32>::new();
404 ///
405 /// buffer.resize_channels(4);
406 /// buffer.resize(256);
407 ///
408 /// let expected = vec![0.0; 256];
409 ///
410 /// assert_eq!(Some(&expected[..]), buffer.get(0));
411 /// assert_eq!(Some(&expected[..]), buffer.get(1));
412 /// assert_eq!(Some(&expected[..]), buffer.get(2));
413 /// assert_eq!(Some(&expected[..]), buffer.get(3));
414 /// assert_eq!(None, buffer.get(4));
415 /// ```
416 pub fn get(&self, channel: usize) -> Option<&[T]> {
417 if !(channel < self.channels) {
418 return None;
419 }
420
421 self.data.get(channel * self.frames..)?.get(..self.frames)
422 }
423
424 /// Get a mutable reference to the buffer of the given channel.
425 ///
426 /// # Examples
427 ///
428 /// ```rust
429 /// use rand::Rng as _;
430 ///
431 /// let mut buffer = rotary::Sequential::<f32>::new();
432 ///
433 /// buffer.resize_channels(2);
434 /// buffer.resize(256);
435 ///
436 /// let mut rng = rand::thread_rng();
437 ///
438 /// if let Some(left) = buffer.get_mut(0) {
439 /// rng.fill(left);
440 /// }
441 ///
442 /// if let Some(right) = buffer.get_mut(1) {
443 /// rng.fill(right);
444 /// }
445 /// ```
446 pub fn get_mut(&mut self, channel: usize) -> Option<&mut [T]> {
447 if !(channel < self.channels) {
448 return None;
449 }
450
451 self.data
452 .get_mut(channel * self.frames..)?
453 .get_mut(..self.frames)
454 }
455
456 fn resize_inner(
457 &mut self,
458 from_channels: usize,
459 from_frames: usize,
460 to_channels: usize,
461 to_frames: usize,
462 ) where
463 T: Sample,
464 {
465 if to_channels == 0 || to_frames == 0 {
466 self.channels = to_channels;
467 self.frames = to_frames;
468 return;
469 } else if self.channels == to_channels && self.frames == to_frames {
470 return;
471 }
472
473 let old_cap = self.data.capacity();
474 let new_len = to_channels * to_frames;
475
476 if old_cap < new_len {
477 let additional = new_len - self.data.capacity();
478 self.data.reserve(additional);
479
480 // zero the additional capacity.
481 unsafe {
482 ptr::write_bytes(
483 self.data.as_mut_ptr().add(old_cap),
484 0,
485 self.data.capacity() - old_cap,
486 );
487 }
488 }
489
490 if from_frames < to_frames {
491 for chan in (0..from_channels).rev() {
492 unsafe {
493 let src = self.data.as_mut_ptr().add(chan * from_frames);
494 let dst = self.data.as_mut_ptr().add(chan * to_frames);
495 ptr::copy(src, dst, from_frames);
496 }
497 }
498 } else {
499 for chan in 0..from_channels {
500 unsafe {
501 let src = self.data.as_mut_ptr().add(chan * from_frames);
502 let dst = self.data.as_mut_ptr().add(chan * to_frames);
503 ptr::copy(src, dst, from_frames);
504 }
505 }
506 }
507
508 // Resize underlying storage.
509 unsafe {
510 self.data.set_len(new_len);
511 }
512
513 self.channels = to_channels;
514 self.frames = to_frames;
515 }
516}
517
518impl<T> fmt::Debug for Sequential<T>
519where
520 T: fmt::Debug,
521{
522 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
523 f.debug_list().entries(self.iter()).finish()
524 }
525}
526
527impl<T> cmp::PartialEq for Sequential<T>
528where
529 T: cmp::PartialEq,
530{
531 fn eq(&self, other: &Self) -> bool {
532 self.iter().eq(other.iter())
533 }
534}
535
536impl<T> cmp::Eq for Sequential<T> where T: cmp::Eq {}
537
538impl<T> cmp::PartialOrd for Sequential<T>
539where
540 T: cmp::PartialOrd,
541{
542 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
543 self.iter().partial_cmp(other.iter())
544 }
545}
546
547impl<T> cmp::Ord for Sequential<T>
548where
549 T: cmp::Ord,
550{
551 fn cmp(&self, other: &Self) -> cmp::Ordering {
552 self.iter().cmp(other.iter())
553 }
554}
555
556impl<T> hash::Hash for Sequential<T>
557where
558 T: hash::Hash,
559{
560 fn hash<H: hash::Hasher>(&self, state: &mut H) {
561 for channel in self.iter() {
562 channel.hash(state);
563 }
564 }
565}
566
567impl<'a, T> IntoIterator for &'a Sequential<T> {
568 type IntoIter = Iter<'a, T>;
569 type Item = <Self::IntoIter as Iterator>::Item;
570
571 fn into_iter(self) -> Self::IntoIter {
572 self.iter()
573 }
574}
575
576impl<'a, T> IntoIterator for &'a mut Sequential<T> {
577 type IntoIter = IterMut<'a, T>;
578 type Item = <Self::IntoIter as Iterator>::Item;
579
580 fn into_iter(self) -> Self::IntoIter {
581 self.iter_mut()
582 }
583}
584
585impl<T> ops::Index<usize> for Sequential<T> {
586 type Output = [T];
587
588 fn index(&self, index: usize) -> &Self::Output {
589 match self.get(index) {
590 Some(slice) => slice,
591 None => panic!("index `{}` is not a channel", index),
592 }
593 }
594}
595
596impl<T> ops::IndexMut<usize> for Sequential<T> {
597 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
598 match self.get_mut(index) {
599 Some(slice) => slice,
600 None => panic!("index `{}` is not a channel", index,),
601 }
602 }
603}
604
605impl<T> ExactSizeBuf for Sequential<T> {
606 fn frames(&self) -> usize {
607 self.frames
608 }
609}
610
611impl<T> Buf<T> for Sequential<T> {
612 fn frames_hint(&self) -> Option<usize> {
613 Some(self.frames)
614 }
615
616 fn channels(&self) -> usize {
617 self.channels
618 }
619
620 fn channel(&self, channel: usize) -> Channel<'_, T> {
621 let data = &self.data[self.frames * channel..];
622 Channel::linear(&data[..self.frames])
623 }
624}
625
626impl<T> ResizableBuf for Sequential<T>
627where
628 T: Sample,
629{
630 fn resize(&mut self, frames: usize) {
631 Self::resize(self, frames);
632 }
633
634 fn resize_topology(&mut self, channels: usize, frames: usize) {
635 Self::resize(self, frames);
636 self.resize_channels(channels);
637 }
638}
639
640impl<T> BufMut<T> for Sequential<T> {
641 fn channel_mut(&mut self, channel: usize) -> ChannelMut<'_, T> {
642 let data = &mut self.data[self.frames * channel..];
643 ChannelMut::linear(&mut data[..self.frames])
644 }
645}