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::InterleavedView, view_mut::InterleavedViewMut};
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 = Interleaved::new(2, 3);
30/// let mut block = Interleaved::from_block(&block);
31///
32/// block.channel_mut(0).for_each(|v| *v = 0.0);
33/// block.channel_mut(1).for_each(|v| *v = 1.0);
34///
35/// assert_eq!(block.raw_data(None), &[0.0, 1.0, 0.0, 1.0, 0.0, 1.0]);
36/// ```
37pub struct Interleaved<S: Sample> {
38    data: Box<[S]>,
39    num_channels: u16,
40    num_frames: usize,
41    num_channels_allocated: u16,
42    num_frames_allocated: usize,
43}
44
45impl<S: Sample> Interleaved<S> {
46    /// Creates a new [`Interleaved`] audio block with the specified dimensions.
47    ///
48    /// Allocates memory for a new interleaved audio block with exactly the specified
49    /// number of channels and frames. The block is initialized with the default value
50    /// for the sample type.
51    ///
52    /// Do not use in real-time processes!
53    ///
54    /// # Arguments
55    ///
56    /// * `num_channels` - The number of audio channels
57    /// * `num_frames` - The number of frames per channel
58    ///
59    /// # Panics
60    ///
61    /// Panics if the multiplication of `num_channels` and `num_frames` would overflow a usize.
62    #[blocking]
63    pub fn new(num_channels: u16, num_frames: usize) -> Self {
64        let total_samples = (num_channels as usize)
65            .checked_mul(num_frames)
66            .expect("Multiplication overflow: num_channels * num_frames is too large");
67
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    /// Creates a new [`Interleaved`] audio block by copying data from another [`AudioBlock`].
78    ///
79    /// Converts any [`AudioBlock`] implementation to an interleaved format by iterating
80    /// through each frame of the source block and copying its samples. The new block
81    /// will have the same dimensions as the source block.
82    ///
83    /// # Warning
84    ///
85    /// This function allocates memory and should not be used in real-time audio processing contexts.
86    ///
87    /// # Arguments
88    ///
89    /// * `block` - The source audio block to copy data from
90    #[blocking]
91    pub fn from_block(block: &impl AudioBlock<S>) -> Self {
92        let mut data = Vec::with_capacity(block.num_channels() as usize * block.num_frames());
93        block.frames().for_each(|f| f.for_each(|&v| data.push(v)));
94        Self {
95            data: data.into_boxed_slice(),
96            num_channels: block.num_channels(),
97            num_frames: block.num_frames(),
98            num_channels_allocated: block.num_channels(),
99            num_frames_allocated: block.num_frames(),
100        }
101    }
102}
103
104impl<S: Sample> AudioBlock<S> for Interleaved<S> {
105    #[nonblocking]
106    fn num_channels(&self) -> u16 {
107        self.num_channels
108    }
109
110    #[nonblocking]
111    fn num_frames(&self) -> usize {
112        self.num_frames
113    }
114
115    #[nonblocking]
116    fn num_channels_allocated(&self) -> u16 {
117        self.num_channels_allocated
118    }
119
120    #[nonblocking]
121    fn num_frames_allocated(&self) -> usize {
122        self.num_frames_allocated
123    }
124
125    #[nonblocking]
126    fn sample(&self, channel: u16, frame: usize) -> S {
127        assert!(channel < self.num_channels);
128        assert!(frame < self.num_frames);
129        unsafe {
130            *self
131                .data
132                .get_unchecked(frame * self.num_channels_allocated as usize + channel as usize)
133        }
134    }
135
136    #[nonblocking]
137    fn channel(&self, channel: u16) -> impl Iterator<Item = &S> {
138        assert!(channel < self.num_channels);
139        self.data
140            .iter()
141            .skip(channel as usize)
142            .step_by(self.num_channels_allocated as usize)
143            .take(self.num_frames)
144    }
145
146    #[nonblocking]
147    fn channels(&self) -> impl Iterator<Item = impl Iterator<Item = &S> + '_> + '_ {
148        let num_channels = self.num_channels as usize;
149        let num_frames = self.num_frames;
150        let stride = self.num_channels_allocated as usize;
151
152        // If the data slice is empty (num_channels or num_frames was 0),
153        // the effective number of frames any iterator should yield is 0.
154        let effective_num_frames = if self.data.is_empty() { 0 } else { num_frames };
155
156        // Get base pointer. If data is empty, it's dangling, but this is fine
157        // because effective_num_frames will be 0, preventing its use in next().
158        let data_ptr = self.data.as_ptr();
159
160        (0..num_channels).map(move |channel_idx| {
161            // Calculate start pointer for the channel.
162            // Safety: If data is not empty, data_ptr is valid and channel_idx is
163            // within bounds [0, num_channels), which is <= num_channels_allocated.
164            // Pointer arithmetic is contained within the allocation.
165            // If data is empty, data_ptr is dangling, but add(0) is okay.
166            // If channel_idx > 0 and data is empty, this relies on num_channels being 0
167            // (so this closure doesn't run) or effective_num_frames being 0
168            // (so the resulting iterator is a no-op).
169            // We rely on effective_num_frames == 0 when data is empty.
170            let start_ptr = unsafe { data_ptr.add(channel_idx) };
171
172            StridedSampleIter::<'_, S> {
173                // Safety: Cast to *mut S for NonNull::new.
174                // If effective_num_frames is 0, ptr can be dangling (NonNull::dangling()).
175                // If effective_num_frames > 0, data is not empty, start_ptr is valid and non-null.
176                ptr: NonNull::new(start_ptr as *mut S).unwrap_or(NonNull::dangling()),
177                stride,
178                remaining: effective_num_frames, // Use the safe frame count
179                _marker: PhantomData,
180            }
181        })
182    }
183
184    #[nonblocking]
185    fn frame(&self, frame: usize) -> impl Iterator<Item = &S> {
186        assert!(frame < self.num_frames);
187        self.data
188            .iter()
189            .skip(frame * self.num_channels_allocated as usize)
190            .take(self.num_channels as usize)
191    }
192
193    #[nonblocking]
194    fn frames(&self) -> impl Iterator<Item = impl Iterator<Item = &S> + '_> + '_ {
195        let num_channels = self.num_channels as usize;
196        let num_channels_allocated = self.num_channels_allocated as usize;
197        self.data
198            .chunks(num_channels_allocated)
199            .take(self.num_frames)
200            .map(move |channel_chunk| channel_chunk.iter().take(num_channels))
201    }
202
203    #[nonblocking]
204    fn view(&self) -> impl AudioBlock<S> {
205        InterleavedView::from_slice_limited(
206            &self.data,
207            self.num_channels,
208            self.num_frames,
209            self.num_channels_allocated,
210            self.num_frames_allocated,
211        )
212    }
213
214    #[nonblocking]
215    fn layout(&self) -> crate::BlockLayout {
216        crate::BlockLayout::Interleaved
217    }
218
219    #[nonblocking]
220    fn raw_data(&self, _: Option<u16>) -> &[S] {
221        &self.data
222    }
223}
224
225impl<S: Sample> AudioBlockMut<S> for Interleaved<S> {
226    #[nonblocking]
227    fn resize(&mut self, num_channels: u16, num_frames: usize) {
228        assert!(num_channels <= self.num_channels_allocated);
229        assert!(num_frames <= self.num_frames_allocated);
230        self.num_channels = num_channels;
231        self.num_frames = num_frames;
232    }
233
234    #[nonblocking]
235    fn sample_mut(&mut self, channel: u16, frame: usize) -> &mut S {
236        assert!(channel < self.num_channels);
237        assert!(frame < self.num_frames);
238        unsafe {
239            self.data
240                .get_unchecked_mut(frame * self.num_channels_allocated as usize + channel as usize)
241        }
242    }
243
244    #[nonblocking]
245    fn channel_mut(&mut self, channel: u16) -> impl Iterator<Item = &mut S> {
246        assert!(channel < self.num_channels);
247        self.data
248            .iter_mut()
249            .skip(channel as usize)
250            .step_by(self.num_channels_allocated as usize)
251            .take(self.num_frames)
252    }
253
254    #[nonblocking]
255    fn channels_mut(&mut self) -> impl Iterator<Item = impl Iterator<Item = &mut S> + '_> + '_ {
256        let num_channels = self.num_channels as usize;
257        let num_frames = self.num_frames;
258        let stride = self.num_channels_allocated as usize;
259
260        // Ensure iterator is empty if underlying data is empty.
261        let effective_num_frames = if self.data.is_empty() { 0 } else { num_frames };
262
263        // Get base mutable pointer.
264        let data_ptr = self.data.as_mut_ptr();
265
266        (0..num_channels).map(move |channel_idx| {
267            // Calculate start pointer.
268            // Safety: Same reasoning as the immutable version applies.
269            let start_ptr = unsafe { data_ptr.add(channel_idx) };
270
271            StridedSampleIterMut::<'_, S> {
272                // Safety: Same reasoning as the immutable version applies.
273                ptr: NonNull::new(start_ptr).unwrap_or(NonNull::dangling()),
274                stride,
275                remaining: effective_num_frames, // Use the safe frame count
276                _marker: PhantomData,
277            }
278        })
279    }
280
281    #[nonblocking]
282    fn frame_mut(&mut self, frame: usize) -> impl Iterator<Item = &mut S> {
283        assert!(frame < self.num_frames);
284        self.data
285            .iter_mut()
286            .skip(frame * self.num_channels_allocated as usize)
287            .take(self.num_channels as usize)
288    }
289
290    #[nonblocking]
291    fn frames_mut(&mut self) -> impl Iterator<Item = impl Iterator<Item = &mut S> + '_> + '_ {
292        let num_channels = self.num_channels as usize;
293        let num_channels_allocated = self.num_channels_allocated as usize;
294        self.data
295            .chunks_mut(num_channels_allocated)
296            .take(self.num_frames)
297            .map(move |channel_chunk| channel_chunk.iter_mut().take(num_channels))
298    }
299
300    #[nonblocking]
301    fn view_mut(&mut self) -> impl AudioBlockMut<S> {
302        InterleavedViewMut::from_slice_limited(
303            &mut self.data,
304            self.num_channels,
305            self.num_frames,
306            self.num_channels_allocated,
307            self.num_frames_allocated,
308        )
309    }
310
311    #[nonblocking]
312    fn raw_data_mut(&mut self, _: Option<u16>) -> &mut [S] {
313        &mut self.data
314    }
315}
316
317#[cfg(test)]
318mod tests {
319    use rtsan_standalone::no_sanitize_realtime;
320
321    use super::*;
322    use crate::sequential::SequentialView;
323
324    #[test]
325    fn test_samples() {
326        let mut block = Interleaved::<f32>::new(2, 5);
327
328        let num_frames = block.num_frames();
329        for ch in 0..block.num_channels() {
330            for f in 0..block.num_frames() {
331                *block.sample_mut(ch, f) = (ch as usize * num_frames + f) as f32;
332            }
333        }
334
335        for ch in 0..block.num_channels() {
336            for f in 0..block.num_frames() {
337                assert_eq!(block.sample(ch, f), (ch as usize * num_frames + f) as f32);
338            }
339        }
340
341        assert_eq!(
342            block.raw_data(None),
343            &[0.0, 5.0, 1.0, 6.0, 2.0, 7.0, 3.0, 8.0, 4.0, 9.0]
344        );
345    }
346
347    #[test]
348    fn test_channel() {
349        let mut block = Interleaved::<f32>::new(2, 5);
350
351        let channel = block.channel(0).copied().collect::<Vec<_>>();
352        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
353        let channel = block.channel(1).copied().collect::<Vec<_>>();
354        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
355
356        block
357            .channel_mut(0)
358            .enumerate()
359            .for_each(|(i, v)| *v = i as f32);
360        block
361            .channel_mut(1)
362            .enumerate()
363            .for_each(|(i, v)| *v = i as f32 + 10.0);
364
365        let channel = block.channel(0).copied().collect::<Vec<_>>();
366        assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
367        let channel = block.channel(1).copied().collect::<Vec<_>>();
368        assert_eq!(channel, vec![10.0, 11.0, 12.0, 13.0, 14.0]);
369    }
370
371    #[test]
372    fn test_channels() {
373        let mut block = Interleaved::<f32>::new(2, 5);
374
375        let mut channels_iter = block.channels();
376        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
377        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
378        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
379        assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
380        assert!(channels_iter.next().is_none());
381        drop(channels_iter);
382
383        let mut channels_iter = block.channels_mut();
384        channels_iter
385            .next()
386            .unwrap()
387            .enumerate()
388            .for_each(|(i, v)| *v = i as f32);
389        channels_iter
390            .next()
391            .unwrap()
392            .enumerate()
393            .for_each(|(i, v)| *v = i as f32 + 10.0);
394        assert!(channels_iter.next().is_none());
395        drop(channels_iter);
396
397        let mut channels_iter = block.channels();
398        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
399        assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
400        let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
401        assert_eq!(channel, vec![10.0, 11.0, 12.0, 13.0, 14.0]);
402        assert!(channels_iter.next().is_none());
403        drop(channels_iter);
404    }
405
406    #[test]
407    fn test_frame() {
408        let mut block = Interleaved::<f32>::new(2, 5);
409
410        for i in 0..block.num_frames() {
411            let frame = block.frame(i).copied().collect::<Vec<_>>();
412            assert_eq!(frame, vec![0.0, 0.0]);
413        }
414
415        for i in 0..block.num_frames() {
416            let add = i as f32 * 10.0;
417            block
418                .frame_mut(i)
419                .enumerate()
420                .for_each(|(i, v)| *v = i as f32 + add);
421        }
422
423        let frame = block.frame(0).copied().collect::<Vec<_>>();
424        assert_eq!(frame, vec![0.0, 1.0]);
425        let frame = block.frame(1).copied().collect::<Vec<_>>();
426        assert_eq!(frame, vec![10.0, 11.0]);
427        let frame = block.frame(2).copied().collect::<Vec<_>>();
428        assert_eq!(frame, vec![20.0, 21.0]);
429        let frame = block.frame(3).copied().collect::<Vec<_>>();
430        assert_eq!(frame, vec![30.0, 31.0]);
431        let frame = block.frame(4).copied().collect::<Vec<_>>();
432        assert_eq!(frame, vec![40.0, 41.0]);
433    }
434
435    #[test]
436    fn test_frames() {
437        let mut block = Interleaved::<f32>::new(2, 5);
438        let num_frames = block.num_frames;
439        let mut frames_iter = block.frames();
440        for _ in 0..num_frames {
441            let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
442            assert_eq!(frame, vec![0.0, 0.0]);
443        }
444        assert!(frames_iter.next().is_none());
445        drop(frames_iter);
446
447        let mut frames_iter = block.frames_mut();
448        for i in 0..num_frames {
449            let add = i as f32 * 10.0;
450            frames_iter
451                .next()
452                .unwrap()
453                .enumerate()
454                .for_each(|(i, v)| *v = i as f32 + add);
455        }
456        assert!(frames_iter.next().is_none());
457        drop(frames_iter);
458
459        let mut frames_iter = block.frames();
460        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
461        assert_eq!(frame, vec![0.0, 1.0]);
462        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
463        assert_eq!(frame, vec![10.0, 11.0]);
464        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
465        assert_eq!(frame, vec![20.0, 21.0]);
466        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
467        assert_eq!(frame, vec![30.0, 31.0]);
468        let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
469        assert_eq!(frame, vec![40.0, 41.0]);
470        assert!(frames_iter.next().is_none());
471    }
472
473    #[test]
474    fn test_from_slice() {
475        let block = Interleaved::<f32>::from_block(&InterleavedView::from_slice(
476            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],
477            2,
478            5,
479        ));
480        assert_eq!(block.num_channels(), 2);
481        assert_eq!(block.num_channels_allocated(), 2);
482        assert_eq!(block.num_frames(), 5);
483        assert_eq!(block.num_frames_allocated(), 5);
484        assert_eq!(
485            block.channel(0).copied().collect::<Vec<_>>(),
486            vec![0.0, 2.0, 4.0, 6.0, 8.0]
487        );
488        assert_eq!(
489            block.channel(1).copied().collect::<Vec<_>>(),
490            vec![1.0, 3.0, 5.0, 7.0, 9.0]
491        );
492        assert_eq!(block.frame(0).copied().collect::<Vec<_>>(), vec![0.0, 1.0]);
493        assert_eq!(block.frame(1).copied().collect::<Vec<_>>(), vec![2.0, 3.0]);
494        assert_eq!(block.frame(2).copied().collect::<Vec<_>>(), vec![4.0, 5.0]);
495        assert_eq!(block.frame(3).copied().collect::<Vec<_>>(), vec![6.0, 7.0]);
496        assert_eq!(block.frame(4).copied().collect::<Vec<_>>(), vec![8.0, 9.0]);
497    }
498
499    #[test]
500    fn test_view() {
501        let block = Interleaved::<f32>::from_block(&InterleavedView::from_slice(
502            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],
503            2,
504            5,
505        ));
506        let view = block.view();
507        assert_eq!(
508            view.channel(0).copied().collect::<Vec<_>>(),
509            vec![0.0, 2.0, 4.0, 6.0, 8.0]
510        );
511        assert_eq!(
512            view.channel(1).copied().collect::<Vec<_>>(),
513            vec![1.0, 3.0, 5.0, 7.0, 9.0]
514        );
515    }
516
517    #[test]
518    fn test_view_mut() {
519        let mut block = Interleaved::<f32>::new(2, 5);
520        {
521            let mut view = block.view_mut();
522            view.channel_mut(0)
523                .enumerate()
524                .for_each(|(i, v)| *v = i as f32);
525            view.channel_mut(1)
526                .enumerate()
527                .for_each(|(i, v)| *v = i as f32 + 10.0);
528        }
529
530        assert_eq!(
531            block.channel(0).copied().collect::<Vec<_>>(),
532            vec![0.0, 1.0, 2.0, 3.0, 4.0]
533        );
534        assert_eq!(
535            block.channel(1).copied().collect::<Vec<_>>(),
536            vec![10.0, 11.0, 12.0, 13.0, 14.0]
537        );
538    }
539
540    #[test]
541    fn test_from_block() {
542        let block = SequentialView::<f32>::from_slice(
543            &[0.0, 2.0, 4.0, 6.0, 8.0, 1.0, 3.0, 5.0, 7.0, 9.0],
544            2,
545            5,
546        );
547
548        let block = Interleaved::<f32>::from_block(&block);
549
550        assert_eq!(
551            block.channel(0).copied().collect::<Vec<_>>(),
552            vec![0.0, 2.0, 4.0, 6.0, 8.0]
553        );
554        assert_eq!(
555            block.channel(1).copied().collect::<Vec<_>>(),
556            vec![1.0, 3.0, 5.0, 7.0, 9.0]
557        );
558    }
559
560    #[test]
561    fn test_resize() {
562        let mut block = Interleaved::<f32>::new(3, 10);
563        assert_eq!(block.num_channels(), 3);
564        assert_eq!(block.num_frames(), 10);
565        assert_eq!(block.num_channels_allocated(), 3);
566        assert_eq!(block.num_frames_allocated(), 10);
567
568        for i in 0..block.num_channels() {
569            assert_eq!(block.channel(i).count(), 10);
570            assert_eq!(block.channel_mut(i).count(), 10);
571        }
572        for i in 0..block.num_frames() {
573            assert_eq!(block.frame(i).count(), 3);
574            assert_eq!(block.frame_mut(i).count(), 3);
575        }
576
577        block.resize(3, 10);
578        block.resize(2, 5);
579
580        assert_eq!(block.num_channels(), 2);
581        assert_eq!(block.num_frames(), 5);
582        assert_eq!(block.num_channels_allocated(), 3);
583        assert_eq!(block.num_frames_allocated(), 10);
584
585        for i in 0..block.num_channels() {
586            assert_eq!(block.channel(i).count(), 5);
587            assert_eq!(block.channel_mut(i).count(), 5);
588        }
589        for i in 0..block.num_frames() {
590            assert_eq!(block.frame(i).count(), 2);
591            assert_eq!(block.frame_mut(i).count(), 2);
592        }
593    }
594
595    #[test]
596    #[should_panic]
597    #[no_sanitize_realtime]
598    fn test_wrong_resize_channels() {
599        let mut block = Interleaved::<f32>::new(2, 10);
600        block.resize(3, 10);
601    }
602
603    #[test]
604    #[should_panic]
605    #[no_sanitize_realtime]
606    fn test_wrong_resize_frames() {
607        let mut block = Interleaved::<f32>::new(2, 10);
608        block.resize(2, 11);
609    }
610
611    #[test]
612    #[should_panic]
613    #[no_sanitize_realtime]
614    fn test_wrong_channel() {
615        let mut block = Interleaved::<f32>::new(2, 10);
616        block.resize(1, 10);
617        let _ = block.channel(1);
618    }
619
620    #[test]
621    #[should_panic]
622    #[no_sanitize_realtime]
623    fn test_wrong_frame() {
624        let mut block = Interleaved::<f32>::new(2, 10);
625        block.resize(2, 5);
626        let _ = block.frame(5);
627    }
628
629    #[test]
630    #[should_panic]
631    #[no_sanitize_realtime]
632    fn test_wrong_channel_mut() {
633        let mut block = Interleaved::<f32>::new(2, 10);
634        block.resize(1, 10);
635        let _ = block.channel_mut(1);
636    }
637
638    #[test]
639    #[should_panic]
640    #[no_sanitize_realtime]
641    fn test_wrong_frame_mut() {
642        let mut block = Interleaved::<f32>::new(2, 10);
643        block.resize(2, 5);
644        let _ = block.frame_mut(5);
645    }
646
647    #[test]
648    fn test_raw_data() {
649        let data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
650        let mut block =
651            Interleaved::<f32>::from_block(&InterleavedView::<f32>::from_slice(&data, 2, 5));
652
653        assert_eq!(block.layout(), crate::BlockLayout::Interleaved);
654
655        assert_eq!(
656            block.raw_data(None),
657            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
658        );
659
660        assert_eq!(
661            block.raw_data_mut(None),
662            &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
663        );
664    }
665}