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}