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