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
17pub 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 #[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::zero(); 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 #[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 let effective_num_frames = if self.data.is_empty() { 0 } else { num_frames };
155
156 let data_ptr = self.data.as_ptr();
159
160 (0..num_channels).map(move |channel_idx| {
161 let start_ptr = unsafe { data_ptr.add(channel_idx) };
171
172 StridedSampleIter::<'_, S> {
173 ptr: NonNull::new(start_ptr as *mut S).unwrap_or(NonNull::dangling()),
177 stride,
178 remaining: effective_num_frames, _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 frame_slice(&self, frame: usize) -> Option<&[S]> {
205 assert!(frame < self.num_frames);
206 let start = frame * self.num_channels_allocated as usize;
207 let end = start + self.num_channels as usize;
208 Some(&self.data[start..end])
209 }
210
211 #[nonblocking]
212 fn view(&self) -> impl AudioBlock<S> {
213 InterleavedView::from_slice_limited(
214 &self.data,
215 self.num_channels,
216 self.num_frames,
217 self.num_channels_allocated,
218 self.num_frames_allocated,
219 )
220 }
221
222 #[nonblocking]
223 fn layout(&self) -> crate::BlockLayout {
224 crate::BlockLayout::Interleaved
225 }
226
227 #[nonblocking]
228 fn raw_data(&self, _: Option<u16>) -> &[S] {
229 &self.data
230 }
231}
232
233impl<S: Sample> AudioBlockMut<S> for Interleaved<S> {
234 #[nonblocking]
235 fn set_active_num_channels(&mut self, num_channels: u16) {
236 assert!(num_channels <= self.num_channels_allocated);
237 self.num_channels = num_channels;
238 }
239
240 #[nonblocking]
241 fn set_active_num_frames(&mut self, num_frames: usize) {
242 assert!(num_frames <= self.num_frames_allocated);
243 self.num_frames = num_frames;
244 }
245
246 #[nonblocking]
247 fn sample_mut(&mut self, channel: u16, frame: usize) -> &mut S {
248 assert!(channel < self.num_channels);
249 assert!(frame < self.num_frames);
250 unsafe {
251 self.data
252 .get_unchecked_mut(frame * self.num_channels_allocated as usize + channel as usize)
253 }
254 }
255
256 #[nonblocking]
257 fn channel_mut(&mut self, channel: u16) -> impl Iterator<Item = &mut S> {
258 assert!(channel < self.num_channels);
259 self.data
260 .iter_mut()
261 .skip(channel as usize)
262 .step_by(self.num_channels_allocated as usize)
263 .take(self.num_frames)
264 }
265
266 #[nonblocking]
267 fn channels_mut(&mut self) -> impl Iterator<Item = impl Iterator<Item = &mut S> + '_> + '_ {
268 let num_channels = self.num_channels as usize;
269 let num_frames = self.num_frames;
270 let stride = self.num_channels_allocated as usize;
271
272 let effective_num_frames = if self.data.is_empty() { 0 } else { num_frames };
274
275 let data_ptr = self.data.as_mut_ptr();
277
278 (0..num_channels).map(move |channel_idx| {
279 let start_ptr = unsafe { data_ptr.add(channel_idx) };
282
283 StridedSampleIterMut::<'_, S> {
284 ptr: NonNull::new(start_ptr).unwrap_or(NonNull::dangling()),
286 stride,
287 remaining: effective_num_frames, _marker: PhantomData,
289 }
290 })
291 }
292
293 #[nonblocking]
294 fn frame_mut(&mut self, frame: usize) -> impl Iterator<Item = &mut S> {
295 assert!(frame < self.num_frames);
296 self.data
297 .iter_mut()
298 .skip(frame * self.num_channels_allocated as usize)
299 .take(self.num_channels as usize)
300 }
301
302 #[nonblocking]
303 fn frames_mut(&mut self) -> impl Iterator<Item = impl Iterator<Item = &mut S> + '_> + '_ {
304 let num_channels = self.num_channels as usize;
305 let num_channels_allocated = self.num_channels_allocated as usize;
306 self.data
307 .chunks_mut(num_channels_allocated)
308 .take(self.num_frames)
309 .map(move |channel_chunk| channel_chunk.iter_mut().take(num_channels))
310 }
311
312 #[nonblocking]
313 fn frame_slice_mut(&mut self, frame: usize) -> Option<&mut [S]> {
314 assert!(frame < self.num_frames);
315 let start = frame * self.num_channels_allocated as usize;
316 let end = start + self.num_channels as usize;
317 Some(&mut self.data[start..end])
318 }
319
320 #[nonblocking]
321 fn view_mut(&mut self) -> impl AudioBlockMut<S> {
322 InterleavedViewMut::from_slice_limited(
323 &mut self.data,
324 self.num_channels,
325 self.num_frames,
326 self.num_channels_allocated,
327 self.num_frames_allocated,
328 )
329 }
330
331 #[nonblocking]
332 fn raw_data_mut(&mut self, _: Option<u16>) -> &mut [S] {
333 &mut self.data
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use rtsan_standalone::no_sanitize_realtime;
340
341 use super::*;
342 use crate::sequential::SequentialView;
343
344 #[test]
345 fn test_samples() {
346 let mut block = Interleaved::<f32>::new(2, 5);
347
348 let num_frames = block.num_frames();
349 for ch in 0..block.num_channels() {
350 for f in 0..block.num_frames() {
351 *block.sample_mut(ch, f) = (ch as usize * num_frames + f) as f32;
352 }
353 }
354
355 for ch in 0..block.num_channels() {
356 for f in 0..block.num_frames() {
357 assert_eq!(block.sample(ch, f), (ch as usize * num_frames + f) as f32);
358 }
359 }
360
361 assert_eq!(
362 block.raw_data(None),
363 &[0.0, 5.0, 1.0, 6.0, 2.0, 7.0, 3.0, 8.0, 4.0, 9.0]
364 );
365 }
366
367 #[test]
368 fn test_channel() {
369 let mut block = Interleaved::<f32>::new(2, 5);
370
371 let channel = block.channel(0).copied().collect::<Vec<_>>();
372 assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
373 let channel = block.channel(1).copied().collect::<Vec<_>>();
374 assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
375
376 block
377 .channel_mut(0)
378 .enumerate()
379 .for_each(|(i, v)| *v = i as f32);
380 block
381 .channel_mut(1)
382 .enumerate()
383 .for_each(|(i, v)| *v = i as f32 + 10.0);
384
385 let channel = block.channel(0).copied().collect::<Vec<_>>();
386 assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
387 let channel = block.channel(1).copied().collect::<Vec<_>>();
388 assert_eq!(channel, vec![10.0, 11.0, 12.0, 13.0, 14.0]);
389 }
390
391 #[test]
392 fn test_channels() {
393 let mut block = Interleaved::<f32>::new(2, 5);
394
395 let mut channels_iter = block.channels();
396 let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
397 assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
398 let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
399 assert_eq!(channel, vec![0.0, 0.0, 0.0, 0.0, 0.0]);
400 assert!(channels_iter.next().is_none());
401 drop(channels_iter);
402
403 let mut channels_iter = block.channels_mut();
404 channels_iter
405 .next()
406 .unwrap()
407 .enumerate()
408 .for_each(|(i, v)| *v = i as f32);
409 channels_iter
410 .next()
411 .unwrap()
412 .enumerate()
413 .for_each(|(i, v)| *v = i as f32 + 10.0);
414 assert!(channels_iter.next().is_none());
415 drop(channels_iter);
416
417 let mut channels_iter = block.channels();
418 let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
419 assert_eq!(channel, vec![0.0, 1.0, 2.0, 3.0, 4.0]);
420 let channel = channels_iter.next().unwrap().copied().collect::<Vec<_>>();
421 assert_eq!(channel, vec![10.0, 11.0, 12.0, 13.0, 14.0]);
422 assert!(channels_iter.next().is_none());
423 drop(channels_iter);
424 }
425
426 #[test]
427 fn test_frame() {
428 let mut block = Interleaved::<f32>::new(2, 5);
429
430 for i in 0..block.num_frames() {
431 let frame = block.frame(i).copied().collect::<Vec<_>>();
432 assert_eq!(frame, vec![0.0, 0.0]);
433 }
434
435 for i in 0..block.num_frames() {
436 let add = i as f32 * 10.0;
437 block
438 .frame_mut(i)
439 .enumerate()
440 .for_each(|(i, v)| *v = i as f32 + add);
441 }
442
443 let frame = block.frame(0).copied().collect::<Vec<_>>();
444 assert_eq!(frame, vec![0.0, 1.0]);
445 let frame = block.frame(1).copied().collect::<Vec<_>>();
446 assert_eq!(frame, vec![10.0, 11.0]);
447 let frame = block.frame(2).copied().collect::<Vec<_>>();
448 assert_eq!(frame, vec![20.0, 21.0]);
449 let frame = block.frame(3).copied().collect::<Vec<_>>();
450 assert_eq!(frame, vec![30.0, 31.0]);
451 let frame = block.frame(4).copied().collect::<Vec<_>>();
452 assert_eq!(frame, vec![40.0, 41.0]);
453 }
454
455 #[test]
456 fn test_frames() {
457 let mut block = Interleaved::<f32>::new(2, 5);
458 let num_frames = block.num_frames;
459 let mut frames_iter = block.frames();
460 for _ in 0..num_frames {
461 let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
462 assert_eq!(frame, vec![0.0, 0.0]);
463 }
464 assert!(frames_iter.next().is_none());
465 drop(frames_iter);
466
467 let mut frames_iter = block.frames_mut();
468 for i in 0..num_frames {
469 let add = i as f32 * 10.0;
470 frames_iter
471 .next()
472 .unwrap()
473 .enumerate()
474 .for_each(|(i, v)| *v = i as f32 + add);
475 }
476 assert!(frames_iter.next().is_none());
477 drop(frames_iter);
478
479 let mut frames_iter = block.frames();
480 let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
481 assert_eq!(frame, vec![0.0, 1.0]);
482 let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
483 assert_eq!(frame, vec![10.0, 11.0]);
484 let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
485 assert_eq!(frame, vec![20.0, 21.0]);
486 let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
487 assert_eq!(frame, vec![30.0, 31.0]);
488 let frame = frames_iter.next().unwrap().copied().collect::<Vec<_>>();
489 assert_eq!(frame, vec![40.0, 41.0]);
490 assert!(frames_iter.next().is_none());
491 }
492
493 #[test]
494 fn test_from_slice() {
495 let block = Interleaved::<f32>::from_block(&InterleavedView::from_slice(
496 &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],
497 2,
498 5,
499 ));
500 assert_eq!(block.num_channels(), 2);
501 assert_eq!(block.num_channels_allocated(), 2);
502 assert_eq!(block.num_frames(), 5);
503 assert_eq!(block.num_frames_allocated(), 5);
504 assert_eq!(
505 block.channel(0).copied().collect::<Vec<_>>(),
506 vec![0.0, 2.0, 4.0, 6.0, 8.0]
507 );
508 assert_eq!(
509 block.channel(1).copied().collect::<Vec<_>>(),
510 vec![1.0, 3.0, 5.0, 7.0, 9.0]
511 );
512 assert_eq!(block.frame(0).copied().collect::<Vec<_>>(), vec![0.0, 1.0]);
513 assert_eq!(block.frame(1).copied().collect::<Vec<_>>(), vec![2.0, 3.0]);
514 assert_eq!(block.frame(2).copied().collect::<Vec<_>>(), vec![4.0, 5.0]);
515 assert_eq!(block.frame(3).copied().collect::<Vec<_>>(), vec![6.0, 7.0]);
516 assert_eq!(block.frame(4).copied().collect::<Vec<_>>(), vec![8.0, 9.0]);
517 }
518
519 #[test]
520 fn test_view() {
521 let block = Interleaved::<f32>::from_block(&InterleavedView::from_slice(
522 &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],
523 2,
524 5,
525 ));
526 let view = block.view();
527 assert_eq!(
528 view.channel(0).copied().collect::<Vec<_>>(),
529 vec![0.0, 2.0, 4.0, 6.0, 8.0]
530 );
531 assert_eq!(
532 view.channel(1).copied().collect::<Vec<_>>(),
533 vec![1.0, 3.0, 5.0, 7.0, 9.0]
534 );
535 }
536
537 #[test]
538 fn test_view_mut() {
539 let mut block = Interleaved::<f32>::new(2, 5);
540 {
541 let mut view = block.view_mut();
542 view.channel_mut(0)
543 .enumerate()
544 .for_each(|(i, v)| *v = i as f32);
545 view.channel_mut(1)
546 .enumerate()
547 .for_each(|(i, v)| *v = i as f32 + 10.0);
548 }
549
550 assert_eq!(
551 block.channel(0).copied().collect::<Vec<_>>(),
552 vec![0.0, 1.0, 2.0, 3.0, 4.0]
553 );
554 assert_eq!(
555 block.channel(1).copied().collect::<Vec<_>>(),
556 vec![10.0, 11.0, 12.0, 13.0, 14.0]
557 );
558 }
559
560 #[test]
561 fn test_from_block() {
562 let block = SequentialView::<f32>::from_slice(
563 &[0.0, 2.0, 4.0, 6.0, 8.0, 1.0, 3.0, 5.0, 7.0, 9.0],
564 2,
565 5,
566 );
567
568 let block = Interleaved::<f32>::from_block(&block);
569
570 assert_eq!(
571 block.channel(0).copied().collect::<Vec<_>>(),
572 vec![0.0, 2.0, 4.0, 6.0, 8.0]
573 );
574 assert_eq!(
575 block.channel(1).copied().collect::<Vec<_>>(),
576 vec![1.0, 3.0, 5.0, 7.0, 9.0]
577 );
578 }
579
580 #[test]
581 fn test_resize() {
582 let mut block = Interleaved::<f32>::new(3, 10);
583 assert_eq!(block.num_channels(), 3);
584 assert_eq!(block.num_frames(), 10);
585 assert_eq!(block.num_channels_allocated(), 3);
586 assert_eq!(block.num_frames_allocated(), 10);
587
588 for i in 0..block.num_channels() {
589 assert_eq!(block.channel(i).count(), 10);
590 assert_eq!(block.channel_mut(i).count(), 10);
591 }
592 for i in 0..block.num_frames() {
593 assert_eq!(block.frame(i).count(), 3);
594 assert_eq!(block.frame_mut(i).count(), 3);
595 }
596
597 block.set_active_size(3, 10);
598 block.set_active_size(2, 5);
599
600 assert_eq!(block.num_channels(), 2);
601 assert_eq!(block.num_frames(), 5);
602 assert_eq!(block.num_channels_allocated(), 3);
603 assert_eq!(block.num_frames_allocated(), 10);
604
605 for i in 0..block.num_channels() {
606 assert_eq!(block.channel(i).count(), 5);
607 assert_eq!(block.channel_mut(i).count(), 5);
608 }
609 for i in 0..block.num_frames() {
610 assert_eq!(block.frame(i).count(), 2);
611 assert_eq!(block.frame_mut(i).count(), 2);
612 }
613 }
614
615 #[test]
616 #[should_panic]
617 #[no_sanitize_realtime]
618 fn test_wrong_resize_channels() {
619 let mut block = Interleaved::<f32>::new(2, 10);
620 block.set_active_size(3, 10);
621 }
622
623 #[test]
624 #[should_panic]
625 #[no_sanitize_realtime]
626 fn test_wrong_resize_frames() {
627 let mut block = Interleaved::<f32>::new(2, 10);
628 block.set_active_size(2, 11);
629 }
630
631 #[test]
632 #[should_panic]
633 #[no_sanitize_realtime]
634 fn test_wrong_channel() {
635 let mut block = Interleaved::<f32>::new(2, 10);
636 block.set_active_size(1, 10);
637 let _ = block.channel(1);
638 }
639
640 #[test]
641 #[should_panic]
642 #[no_sanitize_realtime]
643 fn test_wrong_frame() {
644 let mut block = Interleaved::<f32>::new(2, 10);
645 block.set_active_size(2, 5);
646 let _ = block.frame(5);
647 }
648
649 #[test]
650 #[should_panic]
651 #[no_sanitize_realtime]
652 fn test_wrong_channel_mut() {
653 let mut block = Interleaved::<f32>::new(2, 10);
654 block.set_active_size(1, 10);
655 let _ = block.channel_mut(1);
656 }
657
658 #[test]
659 #[should_panic]
660 #[no_sanitize_realtime]
661 fn test_wrong_frame_mut() {
662 let mut block = Interleaved::<f32>::new(2, 10);
663 block.set_active_size(2, 5);
664 let _ = block.frame_mut(5);
665 }
666
667 #[test]
668 fn test_slice() {
669 let mut block = Interleaved::<f32>::new(3, 6);
670 block.set_active_size(2, 5);
671 assert!(block.channel_slice(0).is_none());
672
673 block.frame_slice_mut(0).unwrap().fill(1.0);
674 block.frame_slice_mut(1).unwrap().fill(2.0);
675 block.frame_slice_mut(2).unwrap().fill(3.0);
676 assert_eq!(block.frame_slice(0).unwrap(), &[1.0; 2]);
677 assert_eq!(block.frame_slice(1).unwrap(), &[2.0; 2]);
678 assert_eq!(block.frame_slice(2).unwrap(), &[3.0; 2]);
679 }
680
681 #[test]
682 #[should_panic]
683 #[no_sanitize_realtime]
684 fn test_slice_out_of_bounds() {
685 let mut block = Interleaved::<f32>::new(3, 6);
686 block.set_active_size(2, 5);
687 block.frame_slice(5);
688 }
689
690 #[test]
691 #[should_panic]
692 #[no_sanitize_realtime]
693 fn test_slice_out_of_bounds_mut() {
694 let mut block = Interleaved::<f32>::new(3, 6);
695 block.set_active_size(2, 5);
696 block.frame_slice(5);
697 }
698
699 #[test]
700 fn test_raw_data() {
701 let data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
702 let mut block =
703 Interleaved::<f32>::from_block(&InterleavedView::<f32>::from_slice(&data, 2, 5));
704
705 assert_eq!(block.layout(), crate::BlockLayout::Interleaved);
706
707 assert_eq!(
708 block.raw_data(None),
709 &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
710 );
711
712 assert_eq!(
713 block.raw_data_mut(None),
714 &[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
715 );
716 }
717}