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::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 #[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 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 let effective_num_frames = if self.data.is_empty() { 0 } else { num_frames };
262
263 let data_ptr = self.data.as_mut_ptr();
265
266 (0..num_channels).map(move |channel_idx| {
267 let start_ptr = unsafe { data_ptr.add(channel_idx) };
270
271 StridedSampleIterMut::<'_, S> {
272 ptr: NonNull::new(start_ptr).unwrap_or(NonNull::dangling()),
274 stride,
275 remaining: effective_num_frames, _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}