Skip to main content

audio_blocks/planar/
owned.rs

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