Skip to main content

audio_blocks/sequential/
owned.rs

1use rtsan_standalone::{blocking, nonblocking};
2
3#[cfg(all(feature = "alloc", not(feature = "std")))]
4use alloc::{boxed::Box, vec, vec::Vec};
5use core::{marker::PhantomData, ptr::NonNull};
6#[cfg(all(feature = "std", not(feature = "alloc")))]
7use std::{boxed::Box, vec, vec::Vec};
8#[cfg(all(feature = "std", feature = "alloc"))]
9use std::{boxed::Box, vec, vec::Vec};
10
11use super::{view::SequentialView, view_mut::SequentialViewMut};
12use crate::{
13    AudioBlock, AudioBlockMut, Sample,
14    iter::{StridedSampleIter, StridedSampleIterMut},
15};
16
17/// A sequential audio block that owns its data.
18///
19/// * **Layout:** `[ch0, ch0, ch0, ch1, ch1, ch1]`
20/// * **Interpretation:** All samples from `ch0` are stored first, followed by all from `ch1`, etc.
21/// * **Terminology:** Described as “channels first” in the sense that all data for one channel appears before any data for the next.
22/// * **Usage:** Used in DSP pipelines where per-channel processing is easier and more efficient.
23///
24/// # Example
25///
26/// ```
27/// use audio_blocks::*;
28///
29/// let block = Sequential::new(2, 3);
30/// let mut block = Sequential::from_block(&block);
31///
32/// block.channel_mut(0).fill(0.0);
33/// block.channel_mut(1).fill(1.0);
34///
35/// assert_eq!(block.channel(0), &[0.0, 0.0, 0.0]);
36/// assert_eq!(block.channel(1), &[1.0, 1.0, 1.0]);
37/// ```
38#[derive(Default, Clone)]
39pub struct Sequential<S: Sample> {
40    data: Box<[S]>,
41    num_channels: u16,
42    num_frames: usize,
43    num_channels_allocated: u16,
44    num_frames_allocated: usize,
45}
46
47impl<S: Sample + Default> Sequential<S> {
48    /// Creates a new audio block with the specified dimensions.
49    ///
50    /// Allocates memory with exactly the specified number of channels and
51    /// frames. The block is initialized with zeros.
52    ///
53    /// Do not use in real-time processes!
54    ///
55    /// # Arguments
56    ///
57    /// * `num_channels` - The number of audio channels
58    /// * `num_frames` - The number of frames per channel
59    ///
60    /// # Panics
61    ///
62    /// Panics if the multiplication of `num_channels` and `num_frames` would overflow a usize.
63    #[blocking]
64    pub fn new(num_channels: u16, num_frames: usize) -> Self {
65        let total_samples = (num_channels as usize)
66            .checked_mul(num_frames)
67            .expect("Multiplication overflow: num_channels * num_frames is too large");
68        Self {
69            data: vec![S::default(); total_samples].into_boxed_slice(),
70            num_channels,
71            num_frames,
72            num_channels_allocated: num_channels,
73            num_frames_allocated: num_frames,
74        }
75    }
76}
77
78impl<S: Sample> Sequential<S> {
79    /// Creates a new sequential audio block by copying the data from a slice of sequential audio data.
80    ///
81    /// # Parameters
82    /// * `data` - The slice containing sequential audio samples
83    /// * `num_channels` - Number of audio channels in the data
84    ///
85    /// # Panics
86    /// Panics if the length of `data` is not evenly divisible by `num_channels`.
87    #[blocking]
88    pub fn from_slice(data: &[S], num_channels: u16) -> Self {
89        assert!(
90            num_channels > 0 && data.len() % num_channels as usize == 0,
91            "data length {} must be divisible by num_channels {}",
92            data.len(),
93            num_channels
94        );
95        let num_frames = data.len() / num_channels as usize;
96        Self {
97            data: data.to_vec().into_boxed_slice(),
98            num_channels,
99            num_frames,
100            num_channels_allocated: num_channels,
101            num_frames_allocated: num_frames,
102        }
103    }
104
105    /// Creates a new sequential audio block by copying the data from a slice of sequential audio data with limited visibility.
106    ///
107    /// This function allows creating a block that exposes only a subset of the allocated channels
108    /// and frames, which is useful for working with a logical section of a larger buffer.
109    ///
110    /// # Parameters
111    /// * `data` - The slice containing sequential audio samples
112    /// * `num_channels_visible` - Number of audio channels to expose
113    /// * `num_frames_visible` - Number of audio frames to expose
114    /// * `num_channels_allocated` - Total number of channels allocated in the data buffer
115    /// * `num_frames_allocated` - Total number of frames allocated in the data buffer
116    ///
117    /// # Panics
118    /// * Panics if the length of `data` doesn't equal `num_channels_allocated * num_frames_allocated`
119    /// * Panics if `num_channels_visible` exceeds `num_channels_allocated`
120    /// * Panics if `num_frames_visible` exceeds `num_frames_allocated`
121    #[blocking]
122    pub fn from_slice_limited(
123        data: &[S],
124        num_channels_visible: u16,
125        num_frames_visible: usize,
126        num_channels_allocated: u16,
127        num_frames_allocated: usize,
128    ) -> Self {
129        assert_eq!(
130            data.len(),
131            num_channels_allocated as usize * num_frames_allocated
132        );
133        assert!(num_channels_visible <= num_channels_allocated);
134        assert!(num_frames_visible <= num_frames_allocated);
135        Self {
136            data: data.to_vec().into_boxed_slice(),
137            num_channels: num_channels_visible,
138            num_frames: num_frames_visible,
139            num_channels_allocated,
140            num_frames_allocated,
141        }
142    }
143
144    /// Creates a new audio block by copying data from another [`AudioBlock`].
145    ///
146    /// Converts any [`AudioBlock`] implementation to a sequential format by iterating
147    /// through each channel of the source block and copying its samples. The new block
148    /// will have the same dimensions as the source block.
149    ///
150    /// # Warning
151    ///
152    /// This function allocates memory and should not be used in real-time audio processing contexts.
153    ///
154    /// # Arguments
155    ///
156    /// * `block` - The source audio block to copy data from
157    #[blocking]
158    pub fn from_block(block: &impl AudioBlock<S>) -> Self {
159        let mut data = Vec::with_capacity(block.num_channels() as usize * block.num_frames());
160        block
161            .channels_iter()
162            .for_each(|c| c.for_each(|&v| data.push(v)));
163        Self {
164            data: data.into_boxed_slice(),
165            num_channels: block.num_channels(),
166            num_frames: block.num_frames(),
167            num_channels_allocated: block.num_channels(),
168            num_frames_allocated: block.num_frames(),
169        }
170    }
171
172    /// Returns a slice for a single channel.
173    ///
174    /// # Panics
175    ///
176    /// Panics if channel index is out of bounds.
177    #[nonblocking]
178    pub fn channel(&self, channel: u16) -> &[S] {
179        assert!(channel < self.num_channels);
180        let start = channel as usize * self.num_frames_allocated;
181        let end = start + self.num_frames;
182        &self.data[start..end]
183    }
184
185    /// Returns a mutable slice for a single channel.
186    ///
187    /// # Panics
188    ///
189    /// Panics if channel index is out of bounds.
190    #[nonblocking]
191    pub fn channel_mut(&mut self, channel: u16) -> &mut [S] {
192        assert!(channel < self.num_channels);
193        let start = channel as usize * self.num_frames_allocated;
194        let end = start + self.num_frames;
195        &mut self.data[start..end]
196    }
197
198    /// Returns an iterator over all channels in the block.
199    ///
200    /// Each channel is represented as a slice of samples.
201    #[nonblocking]
202    pub fn channels(&self) -> impl ExactSizeIterator<Item = &[S]> {
203        self.data
204            .chunks(self.num_frames_allocated)
205            .take(self.num_channels as usize)
206            .map(|frame| &frame[..self.num_frames])
207    }
208
209    /// Returns a mutable iterator over all channels in the block.
210    ///
211    /// Each channel is represented as a mutable slice of samples.
212    #[nonblocking]
213    pub fn channels_mut(&mut self) -> impl ExactSizeIterator<Item = &mut [S]> {
214        self.data
215            .chunks_mut(self.num_frames_allocated)
216            .take(self.num_channels as usize)
217            .map(|frame| &mut frame[..self.num_frames])
218    }
219
220    /// Provides direct access to the underlying memory as a sequential slice.
221    ///
222    /// This function gives access to all allocated data, including any reserved capacity
223    /// beyond the visible range.
224    #[nonblocking]
225    pub fn raw_data(&self) -> &[S] {
226        &self.data
227    }
228
229    /// Provides direct mutable access to the underlying memory as a sequential slice.
230    ///
231    /// This function gives mutable access to all allocated data, including any reserved capacity
232    /// beyond the visible range.
233    #[nonblocking]
234    pub fn raw_data_mut(&mut self) -> &mut [S] {
235        &mut self.data
236    }
237
238    #[nonblocking]
239    pub fn view(&self) -> SequentialView<'_, S> {
240        SequentialView::from_slice_limited(
241            &self.data,
242            self.num_channels,
243            self.num_frames,
244            self.num_channels_allocated,
245            self.num_frames_allocated,
246        )
247    }
248
249    #[nonblocking]
250    pub fn view_mut(&mut self) -> SequentialViewMut<'_, S> {
251        SequentialViewMut::from_slice_limited(
252            &mut self.data,
253            self.num_channels,
254            self.num_frames,
255            self.num_channels_allocated,
256            self.num_frames_allocated,
257        )
258    }
259}
260
261impl<S: Sample> AudioBlock<S> for Sequential<S> {
262    type PlanarView = [S; 0];
263
264    #[nonblocking]
265    fn num_channels(&self) -> u16 {
266        self.num_channels
267    }
268
269    #[nonblocking]
270    fn num_frames(&self) -> usize {
271        self.num_frames
272    }
273
274    #[nonblocking]
275    fn num_channels_allocated(&self) -> u16 {
276        self.num_channels_allocated
277    }
278
279    #[nonblocking]
280    fn num_frames_allocated(&self) -> usize {
281        self.num_frames_allocated
282    }
283
284    #[nonblocking]
285    fn layout(&self) -> crate::BlockLayout {
286        crate::BlockLayout::Sequential
287    }
288
289    #[nonblocking]
290    fn sample(&self, channel: u16, frame: usize) -> S {
291        assert!(channel < self.num_channels);
292        assert!(frame < self.num_frames);
293        unsafe {
294            *self
295                .data
296                .get_unchecked(channel as usize * self.num_frames_allocated + frame)
297        }
298    }
299
300    #[nonblocking]
301    fn channel_iter(&self, channel: u16) -> impl ExactSizeIterator<Item = &S> {
302        assert!(channel < self.num_channels);
303        self.data
304            .iter()
305            .skip(channel as usize * self.num_frames_allocated)
306            .take(self.num_frames)
307    }
308
309    #[nonblocking]
310    fn channels_iter(&self) -> impl ExactSizeIterator<Item = impl ExactSizeIterator<Item = &S>> {
311        let num_frames = self.num_frames; // Visible frames per channel
312        let num_frames_allocated = self.num_frames_allocated; // Allocated frames per channel (chunk size)
313
314        self.data
315            .chunks(num_frames_allocated)
316            .take(self.num_channels as usize)
317            .map(move |channel_chunk| channel_chunk.iter().take(num_frames))
318    }
319
320    #[nonblocking]
321    fn frame_iter(&self, frame: usize) -> impl ExactSizeIterator<Item = &S> {
322        assert!(frame < self.num_frames);
323        self.data
324            .iter()
325            .skip(frame)
326            .step_by(self.num_frames_allocated)
327            .take(self.num_channels as usize)
328    }
329
330    #[nonblocking]
331    fn frames_iter(&self) -> impl ExactSizeIterator<Item = impl ExactSizeIterator<Item = &S>> {
332        let num_channels = self.num_channels as usize;
333        let num_frames = self.num_frames;
334        let stride = self.num_frames_allocated;
335        let data_ptr = self.data.as_ptr();
336
337        (0..num_frames).map(move |frame_idx| {
338            // Safety check: Ensure data isn't empty if we calculate a start_ptr.
339            // If num_frames or num_channels is 0, remaining will be 0, iterator is safe.
340            // If data is empty, ptr is dangling, but add(0) is okay. add(>0) is UB.
341            // But if data is empty, num_channels or num_frames must be 0.
342            let start_ptr = if self.data.is_empty() {
343                NonNull::dangling().as_ptr() // Use dangling pointer if slice is empty
344            } else {
345                // Safety: channel_idx is < num_channels <= num_channels_allocated.
346                // Adding it to a valid data_ptr is safe within slice bounds.
347                unsafe { data_ptr.add(frame_idx) }
348            };
349
350            StridedSampleIter::<'_, S> {
351                // Note: '_ lifetime from &self borrow
352                // Safety: Pointer is either dangling (if empty) or valid start pointer.
353                // NonNull::new is safe if start_ptr is non-null (i.e., data not empty).
354                ptr: NonNull::new(start_ptr as *mut S).unwrap_or(NonNull::dangling()), // Use dangling on null/empty
355                stride,
356                remaining: num_channels, // If 0, iterator yields None immediately
357                _marker: PhantomData,
358            }
359        })
360    }
361
362    #[nonblocking]
363    fn as_view(&self) -> impl AudioBlock<S> {
364        self.view()
365    }
366
367    #[nonblocking]
368    fn as_sequential_view(&self) -> Option<SequentialView<'_, S>> {
369        Some(self.view())
370    }
371}
372
373impl<S: Sample> AudioBlockMut<S> for Sequential<S> {
374    type PlanarViewMut = [S; 0];
375
376    #[nonblocking]
377    fn set_num_channels_visible(&mut self, num_channels: u16) {
378        assert!(num_channels <= self.num_channels_allocated);
379        self.num_channels = num_channels;
380    }
381
382    #[nonblocking]
383    fn set_num_frames_visible(&mut self, num_frames: usize) {
384        assert!(num_frames <= self.num_frames_allocated);
385        self.num_frames = num_frames;
386    }
387
388    #[nonblocking]
389    fn sample_mut(&mut self, channel: u16, frame: usize) -> &mut S {
390        assert!(channel < self.num_channels);
391        assert!(frame < self.num_frames);
392        unsafe {
393            self.data
394                .get_unchecked_mut(channel as usize * self.num_frames_allocated + frame)
395        }
396    }
397
398    #[nonblocking]
399    fn channel_iter_mut(&mut self, channel: u16) -> impl ExactSizeIterator<Item = &mut S> {
400        assert!(channel < self.num_channels);
401        self.data
402            .iter_mut()
403            .skip(channel as usize * self.num_frames_allocated)
404            .take(self.num_frames)
405    }
406
407    #[nonblocking]
408    fn channels_iter_mut(
409        &mut self,
410    ) -> impl ExactSizeIterator<Item = impl ExactSizeIterator<Item = &mut S>> {
411        let num_frames = self.num_frames;
412        let num_frames_allocated = self.num_frames_allocated;
413        self.data
414            .chunks_mut(num_frames_allocated)
415            .take(self.num_channels as usize)
416            .map(move |channel_chunk| channel_chunk.iter_mut().take(num_frames))
417    }
418
419    #[nonblocking]
420    fn frame_iter_mut(&mut self, frame: usize) -> impl ExactSizeIterator<Item = &mut S> {
421        assert!(frame < self.num_frames);
422        self.data
423            .iter_mut()
424            .skip(frame)
425            .step_by(self.num_frames_allocated)
426            .take(self.num_channels as usize)
427    }
428
429    #[nonblocking]
430    fn frames_iter_mut(
431        &mut self,
432    ) -> impl ExactSizeIterator<Item = impl ExactSizeIterator<Item = &mut S>> {
433        let num_channels = self.num_channels as usize;
434        let num_frames = self.num_frames;
435        let stride = self.num_frames_allocated;
436        let data_ptr = self.data.as_mut_ptr();
437
438        (0..num_frames).map(move |frame_idx| {
439            // Safety check: Ensure data isn't empty if we calculate a start_ptr.
440            // If num_frames or num_channels is 0, remaining will be 0, iterator is safe.
441            // If data is empty, ptr is dangling, but add(0) is okay. add(>0) is UB.
442            // But if data is empty, num_channels or num_frames must be 0.
443            let start_ptr = if self.data.is_empty() {
444                NonNull::dangling().as_ptr() // Use dangling pointer if slice is empty
445            } else {
446                // Safety: channel_idx is < num_channels <= num_channels_allocated.
447                // Adding it to a valid data_ptr is safe within slice bounds.
448                unsafe { data_ptr.add(frame_idx) }
449            };
450
451            StridedSampleIterMut::<'_, S> {
452                // Note: '_ lifetime from &self borrow
453                // Safety: Pointer is either dangling (if empty) or valid start pointer.
454                // NonNull::new is safe if start_ptr is non-null (i.e., data not empty).
455                ptr: NonNull::new(start_ptr).unwrap_or(NonNull::dangling()), // Use dangling on null/empty
456                stride,
457                remaining: num_channels, // If 0, iterator yields None immediately
458                _marker: PhantomData,
459            }
460        })
461    }
462
463    #[nonblocking]
464    fn as_view_mut(&mut self) -> impl AudioBlockMut<S> {
465        self.view_mut()
466    }
467
468    #[nonblocking]
469    fn as_sequential_view_mut(&mut self) -> Option<SequentialViewMut<'_, S>> {
470        Some(self.view_mut())
471    }
472}
473
474impl<S: Sample + core::fmt::Debug> core::fmt::Debug for Sequential<S> {
475    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
476        writeln!(f, "audio_blocks::Sequential {{")?;
477        writeln!(f, "  num_channels: {}", self.num_channels)?;
478        writeln!(f, "  num_frames: {}", self.num_frames)?;
479        writeln!(
480            f,
481            "  num_channels_allocated: {}",
482            self.num_channels_allocated
483        )?;
484        writeln!(f, "  num_frames_allocated: {}", self.num_frames_allocated)?;
485        writeln!(f, "  channels:")?;
486
487        for (i, channel) in self.channels().enumerate() {
488            writeln!(f, "    {}: {:?}", i, channel)?;
489        }
490
491        writeln!(f, "  raw_data: {:?}", self.raw_data())?;
492        writeln!(f, "}}")?;
493
494        Ok(())
495    }
496}
497
498#[cfg(test)]
499mod tests {
500    use super::*;
501    use crate::interleaved::InterleavedView;
502    use rtsan_standalone::no_sanitize_realtime;
503
504    #[test]
505    fn test_member_functions() {
506        let mut block = Sequential::<f32>::new(3, 4);
507        block.channel_mut(0).copy_from_slice(&[0.0, 1.0, 2.0, 3.0]);
508        block.channel_mut(1).copy_from_slice(&[4.0, 5.0, 6.0, 7.0]);
509        block.set_visible(2, 3);
510
511        // single frame
512        assert_eq!(block.channel(0), &[0.0, 1.0, 2.0]);
513        assert_eq!(block.channel(1), &[4.0, 5.0, 6.0]);
514
515        assert_eq!(block.channel_mut(0), &[0.0, 1.0, 2.0]);
516        assert_eq!(block.channel_mut(1), &[4.0, 5.0, 6.0]);
517
518        // all frames
519        let mut channels = block.channels();
520        assert_eq!(channels.next().unwrap(), &[0.0, 1.0, 2.0]);
521        assert_eq!(channels.next().unwrap(), &[4.0, 5.0, 6.0]);
522        assert_eq!(channels.next(), None);
523        drop(channels);
524
525        let mut channels = block.channels_mut();
526        assert_eq!(channels.next().unwrap(), &[0.0, 1.0, 2.0]);
527        assert_eq!(channels.next().unwrap(), &[4.0, 5.0, 6.0]);
528        assert_eq!(channels.next(), None);
529        drop(channels);
530
531        // raw data
532        assert_eq!(
533            block.raw_data(),
534            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 0.0, 0.0, 0.0, 0.0]
535        );
536
537        // views
538        let view = block.view();
539        assert_eq!(view.num_channels(), block.num_channels());
540        assert_eq!(view.num_frames(), block.num_frames());
541        assert_eq!(
542            view.num_channels_allocated(),
543            block.num_channels_allocated()
544        );
545        assert_eq!(view.num_frames_allocated(), block.num_frames_allocated());
546        assert_eq!(view.raw_data(), block.raw_data());
547
548        let num_channels = block.num_channels();
549        let num_frames = block.num_frames();
550        let num_channels_allocated = block.num_channels_allocated();
551        let num_frames_allocated = block.num_frames_allocated();
552        let data = block.raw_data().to_vec();
553        let view = block.view_mut();
554        assert_eq!(view.num_channels(), num_channels);
555        assert_eq!(view.num_frames(), num_frames);
556        assert_eq!(view.num_channels_allocated(), num_channels_allocated);
557        assert_eq!(view.num_frames_allocated(), num_frames_allocated);
558        assert_eq!(view.raw_data(), &data);
559    }
560
561    #[test]
562    fn test_samples() {
563        let mut block = Sequential::<f32>::new(2, 5);
564
565        let num_frames = block.num_frames();
566        for ch in 0..block.num_channels() {
567            for f in 0..block.num_frames() {
568                *block.sample_mut(ch, f) = (ch as usize * num_frames + f) as f32;
569            }
570        }
571
572        for ch in 0..block.num_channels() {
573            for f in 0..block.num_frames() {
574                assert_eq!(block.sample(ch, f), (ch as usize * num_frames + f) as f32);
575            }
576        }
577
578        assert_eq!(
579            block.raw_data(),
580            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
581        );
582    }
583
584    #[test]
585    fn test_channel_iter() {
586        let mut block = Sequential::<f32>::new(2, 5);
587
588        let channel = block.channel_iter(0).copied().collect::<Vec<_>>();
589        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
590        let channel = block.channel_iter(1).copied().collect::<Vec<_>>();
591        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
592
593        block
594            .channel_iter_mut(0)
595            .enumerate()
596            .for_each(|(i, v)| *v = i as f32);
597        block
598            .channel_iter_mut(1)
599            .enumerate()
600            .for_each(|(i, v)| *v = i as f32 + 10.0);
601
602        let channel = block.channel_iter(0).copied().collect::<Vec<_>>();
603        assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
604        let channel = block.channel_iter(1).copied().collect::<Vec<_>>();
605        assert_eq!(channel, vec![10.0, 11.0, 12.0, 13.0, 14.0]);
606    }
607
608    #[test]
609    fn test_channel_iters() {
610        let mut block = Sequential::<f32>::new(2, 5);
611
612        let mut channels_iter = block.channels_iter();
613        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
614        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
615        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
616        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
617        assert!(channels_iter.next().is_none());
618        drop(channels_iter);
619
620        let mut channels_iter = block.channels_iter_mut();
621        channels_iter
622            .next()
623            .unwrap()
624            .enumerate()
625            .for_each(|(i, v)| *v = i as f32);
626        channels_iter
627            .next()
628            .unwrap()
629            .enumerate()
630            .for_each(|(i, v)| *v = i as f32 + 10.0);
631        assert!(channels_iter.next().is_none());
632        drop(channels_iter);
633
634        let mut channels_iter = block.channels_iter();
635        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
636        assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
637        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
638        assert_eq!(channel, vec![10.0, 11.0, 12.0, 13.0, 14.0]);
639        assert!(channels_iter.next().is_none());
640        drop(channels_iter);
641    }
642
643    #[test]
644    fn test_frame_iter() {
645        let mut block = Sequential::<f32>::new(2, 5);
646
647        for i in 0..block.num_frames() {
648            let frame = block.frame_iter(i).copied().collect::<Vec<_>>();
649            assert_eq!(frame, vec![0.0, 0.0]);
650        }
651
652        for i in 0..block.num_frames() {
653            let add = i as f32 * 10.0;
654            block
655                .frame_iter_mut(i)
656                .enumerate()
657                .for_each(|(i, v)| *v = i as f32 + add);
658        }
659
660        let channel = block.frame_iter(0).copied().collect::<Vec<_>>();
661        assert_eq!(channel, vec![0.0, 1.0]);
662        let channel = block.frame_iter(1).copied().collect::<Vec<_>>();
663        assert_eq!(channel, vec![10.0, 11.0]);
664        let channel = block.frame_iter(2).copied().collect::<Vec<_>>();
665        assert_eq!(channel, vec![20.0, 21.0]);
666        let channel = block.frame_iter(3).copied().collect::<Vec<_>>();
667        assert_eq!(channel, vec![30.0, 31.0]);
668        let channel = block.frame_iter(4).copied().collect::<Vec<_>>();
669        assert_eq!(channel, vec![40.0, 41.0]);
670    }
671
672    #[test]
673    fn test_frame_iters() {
674        let mut block = Sequential::<f32>::new(3, 6);
675        block.set_visible(2, 5);
676
677        let num_frames = block.num_frames;
678        let mut frames_iter = block.frames_iter();
679        for _ in 0..num_frames {
680            let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
681            assert_eq!(frame, vec![0.0, 0.0]);
682        }
683        assert!(frames_iter.next().is_none());
684        drop(frames_iter);
685
686        let mut frames_iter = block.frames_iter_mut();
687        for i in 0..num_frames {
688            let add = i as f32 * 10.0;
689            frames_iter
690                .next()
691                .unwrap()
692                .enumerate()
693                .for_each(|(i, v)| *v = i as f32 + add);
694        }
695        assert!(frames_iter.next().is_none());
696        drop(frames_iter);
697
698        let mut frames_iter = block.frames_iter();
699        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
700        assert_eq!(frame, vec![0.0, 1.0]);
701        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
702        assert_eq!(frame, vec![10.0, 11.0]);
703        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
704        assert_eq!(frame, vec![20.0, 21.0]);
705        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
706        assert_eq!(frame, vec![30.0, 31.0]);
707        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
708        assert_eq!(frame, vec![40.0, 41.0]);
709        assert!(frames_iter.next().is_none());
710    }
711
712    #[test]
713    fn test_from_slice() {
714        let block = Sequential::<f32>::from_block(&InterleavedView::from_slice(
715            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],
716            2,
717        ));
718        assert_eq!(block.num_channels(), 2);
719        assert_eq!(block.num_channels_allocated(), 2);
720        assert_eq!(block.num_frames(), 5);
721        assert_eq!(block.num_frames_allocated(), 5);
722        assert_eq!(
723            block.channel_iter(0).copied().collect::<Vec<_>>(),
724            vec![0.0, 2.0, 4.0, 6.0, 8.0]
725        );
726        assert_eq!(
727            block.channel_iter(1).copied().collect::<Vec<_>>(),
728            vec![1.0, 3.0, 5.0, 7.0, 9.0]
729        );
730        assert_eq!(
731            block.frame_iter(0).copied().collect::<Vec<_>>(),
732            vec![0.0, 1.0]
733        );
734        assert_eq!(
735            block.frame_iter(1).copied().collect::<Vec<_>>(),
736            vec![2.0, 3.0]
737        );
738        assert_eq!(
739            block.frame_iter(2).copied().collect::<Vec<_>>(),
740            vec![4.0, 5.0]
741        );
742        assert_eq!(
743            block.frame_iter(3).copied().collect::<Vec<_>>(),
744            vec![6.0, 7.0]
745        );
746        assert_eq!(
747            block.frame_iter(4).copied().collect::<Vec<_>>(),
748            vec![8.0, 9.0]
749        );
750    }
751
752    #[test]
753    fn test_view() {
754        let block = Sequential::<f32>::from_block(&InterleavedView::from_slice(
755            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],
756            2,
757        ));
758        assert!(block.as_interleaved_view().is_none());
759        assert!(block.as_planar_view().is_none());
760        assert!(block.as_sequential_view().is_some());
761        let view = block.as_view();
762        assert_eq!(
763            view.channel_iter(0).copied().collect::<Vec<_>>(),
764            vec![0.0, 2.0, 4.0, 6.0, 8.0]
765        );
766        assert_eq!(
767            view.channel_iter(1).copied().collect::<Vec<_>>(),
768            vec![1.0, 3.0, 5.0, 7.0, 9.0]
769        );
770    }
771
772    #[test]
773    fn test_view_mut() {
774        let mut block = Sequential::<f32>::new(2, 5);
775        assert!(block.as_interleaved_view().is_none());
776        assert!(block.as_planar_view().is_none());
777        assert!(block.as_sequential_view().is_some());
778        {
779            let mut view = block.as_view_mut();
780            view.channel_iter_mut(0)
781                .enumerate()
782                .for_each(|(i, v)| *v = i as f32);
783            view.channel_iter_mut(1)
784                .enumerate()
785                .for_each(|(i, v)| *v = i as f32 + 10.0);
786        }
787
788        assert_eq!(
789            block.channel_iter(0).copied().collect::<Vec<_>>(),
790            vec![0.0, 1.0, 2.0, 3.0, 4.0]
791        );
792        assert_eq!(
793            block.channel_iter(1).copied().collect::<Vec<_>>(),
794            vec![10.0, 11.0, 12.0, 13.0, 14.0]
795        );
796    }
797
798    #[test]
799    #[should_panic]
800    #[no_sanitize_realtime]
801    fn test_slice_out_of_bounds() {
802        let mut block = Sequential::<f32>::new(3, 6);
803        block.set_visible(2, 5);
804        block.channel(2);
805    }
806
807    #[test]
808    #[should_panic]
809    #[no_sanitize_realtime]
810    fn test_slice_out_of_bounds_mut() {
811        let mut block = Sequential::<f32>::new(3, 6);
812        block.set_visible(2, 5);
813        block.channel_mut(2);
814    }
815
816    #[test]
817    fn test_resize() {
818        let mut block = Sequential::<f32>::new(3, 10);
819        assert_eq!(block.num_channels(), 3);
820        assert_eq!(block.num_frames(), 10);
821        assert_eq!(block.num_channels_allocated(), 3);
822        assert_eq!(block.num_frames_allocated(), 10);
823
824        for i in 0..block.num_channels() {
825            assert_eq!(block.channel_iter(i).count(), 10);
826            assert_eq!(block.channel_iter_mut(i).count(), 10);
827        }
828        for i in 0..block.num_frames() {
829            assert_eq!(block.frame_iter(i).count(), 3);
830            assert_eq!(block.frame_iter_mut(i).count(), 3);
831        }
832
833        block.set_visible(3, 10);
834        block.set_visible(2, 5);
835
836        assert_eq!(block.num_channels(), 2);
837        assert_eq!(block.num_frames(), 5);
838        assert_eq!(block.num_channels_allocated(), 3);
839        assert_eq!(block.num_frames_allocated(), 10);
840
841        for i in 0..block.num_channels() {
842            assert_eq!(block.channel_iter(i).count(), 5);
843            assert_eq!(block.channel_iter_mut(i).count(), 5);
844        }
845        for i in 0..block.num_frames() {
846            assert_eq!(block.frame_iter(i).count(), 2);
847            assert_eq!(block.frame_iter_mut(i).count(), 2);
848        }
849    }
850
851    #[test]
852    #[should_panic]
853    #[no_sanitize_realtime]
854    fn test_wrong_resize_channels() {
855        let mut block = Sequential::<f32>::new(2, 10);
856        block.set_visible(3, 10);
857    }
858
859    #[test]
860    #[should_panic]
861    #[no_sanitize_realtime]
862    fn test_wrong_resize_frames() {
863        let mut block = Sequential::<f32>::new(2, 10);
864        block.set_visible(2, 11);
865    }
866
867    #[test]
868    #[should_panic]
869    #[no_sanitize_realtime]
870    fn test_wrong_channel() {
871        let mut block = Sequential::<f32>::new(2, 10);
872        block.set_visible(1, 10);
873        let _ = block.channel_iter(1);
874    }
875
876    #[test]
877    #[should_panic]
878    #[no_sanitize_realtime]
879    fn test_wrong_frame() {
880        let mut block = Sequential::<f32>::new(2, 10);
881        block.set_visible(2, 5);
882        let _ = block.frame_iter(5);
883    }
884
885    #[test]
886    #[should_panic]
887    #[no_sanitize_realtime]
888    fn test_wrong_channel_mut() {
889        let mut block = Sequential::<f32>::new(2, 10);
890        block.set_visible(1, 10);
891        let _ = block.channel_iter_mut(1);
892    }
893}