1#![cfg_attr(not(feature = "std"), no_std)]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6#[cfg(feature = "alloc")]
7use alloc::vec::Vec;
8
9use core::{num::NonZeroUsize, ops::Range};
10
11pub fn interleave<T: Copy, Vin: AsRef<[T]>, const CHANNELS: usize>(
41 input: &[Vin],
42 input_range: Range<usize>,
43 output: &mut [T],
44) {
45 assert!(CHANNELS > 0);
46 assert!(input.len() >= CHANNELS);
47
48 if input_range.is_empty() {
49 return;
50 }
51
52 assert!(output.len() >= (input_range.end - input_range.start) * CHANNELS);
53
54 for ch in input.iter() {
55 let ch = ch.as_ref();
56 assert!(input_range.start <= ch.len());
57 assert!(input_range.end <= ch.len());
58 }
59
60 unsafe {
62 interleave_unchecked::<T, _, CHANNELS>(input, input_range, output);
63 }
64}
65
66pub unsafe fn interleave_unchecked<T: Copy, Vin: AsRef<[T]>, const CHANNELS: usize>(
98 input: &[Vin],
99 input_range: Range<usize>,
100 output: &mut [T],
101) {
102 if input_range.is_empty() {
103 return;
104 }
105
106 unsafe {
107 for i in 0..(input_range.end - input_range.start) {
108 for ch_i in 0..CHANNELS {
109 *output.get_unchecked_mut((i * CHANNELS) + ch_i) = *input
110 .get_unchecked(ch_i)
111 .as_ref()
112 .get_unchecked(input_range.start + i);
113 }
114 }
115 }
116}
117
118pub fn deinterleave<T: Copy, Vout: AsMut<[T]>, const CHANNELS: usize>(
150 input: &[T],
151 output: &mut [Vout],
152 output_range: Range<usize>,
153) {
154 assert!(CHANNELS > 0);
155 assert!(output.len() >= CHANNELS);
156
157 if output_range.is_empty() {
158 return;
159 }
160
161 assert!(input.len() >= (output_range.end - output_range.start) * CHANNELS);
162
163 for ch in output.iter_mut() {
164 let ch = ch.as_mut();
165 assert!(output_range.start <= ch.len());
166 assert!(output_range.end <= ch.len());
167 }
168
169 unsafe {
171 deinterleave_unchecked::<T, _, CHANNELS>(input, output, output_range);
172 }
173}
174
175pub unsafe fn deinterleave_unchecked<T: Copy, Vout: AsMut<[T]>, const CHANNELS: usize>(
209 input: &[T],
210 output: &mut [Vout],
211 output_range: Range<usize>,
212) {
213 if output_range.is_empty() {
214 return;
215 }
216
217 unsafe {
218 for i in 0..(output_range.end - output_range.start) {
219 for ch_i in 0..CHANNELS {
220 *output
221 .get_unchecked_mut(ch_i)
222 .as_mut()
223 .get_unchecked_mut(output_range.start + i) =
224 *input.get_unchecked((i * CHANNELS) + ch_i)
225 }
226 }
227 }
228}
229
230pub fn interleave_variable<T: Copy, Vin: AsRef<[T]>>(
259 input: &[Vin],
260 input_range: Range<usize>,
261 output: &mut [T],
262 num_out_channels: NonZeroUsize,
263) {
264 if input_range.is_empty() || input.is_empty() {
265 return;
266 }
267
268 let in_frames = input_range.end - input_range.start;
269
270 assert!(output.len() >= in_frames * num_out_channels.get());
271
272 if num_out_channels.get() == 1 {
273 output[..in_frames].copy_from_slice(&input[0].as_ref()[input_range.clone()]);
275
276 return;
277 }
278
279 if num_out_channels.get() == 2 && input.len() >= 2 {
280 interleave::<T, _, 2>(input, input_range, output);
282 return;
283 }
284
285 for (ch_i, in_ch) in (0..num_out_channels.get()).zip(input.iter()) {
286 let in_ch = in_ch.as_ref();
287
288 assert!(input_range.start < in_ch.len() && input_range.end <= in_ch.len());
289
290 unsafe {
293 for i in 0..in_frames {
294 *output.get_unchecked_mut((i * num_out_channels.get()) + ch_i) =
295 *in_ch.get_unchecked(input_range.start + i);
296 }
297 }
298 }
299}
300
301#[cfg(feature = "alloc")]
330pub fn interleave_to_vec_variable<T: Copy + Default, Vin: AsRef<[T]>>(
331 input: &[Vin],
332 input_range: Range<usize>,
333 num_out_channels: NonZeroUsize,
334) -> Vec<T> {
335 let out_len = (input_range.end - input_range.start) * num_out_channels.get();
336
337 let mut out: Vec<T> = Vec::new();
338 out.reserve_exact(out_len);
339
340 if num_out_channels.get() > input.len() {
341 out.resize(out_len, T::default());
342 } else {
343 unsafe {
349 out.set_len(out_len);
350 }
351 }
352
353 interleave_variable(input, input_range, out.as_mut_slice(), num_out_channels);
354
355 out
356}
357
358pub fn deinterleave_variable<T: Copy, Vout: AsMut<[T]>>(
389 input: &[T],
390 num_in_channels: NonZeroUsize,
391 output: &mut [Vout],
392 output_range: Range<usize>,
393) {
394 if output_range.is_empty() || output.is_empty() {
395 return;
396 }
397
398 let out_frames = output_range.end - output_range.start;
399
400 if num_in_channels.get() == 1 {
401 output[0].as_mut()[output_range.clone()].copy_from_slice(&input[..out_frames]);
403
404 return;
405 }
406
407 if num_in_channels.get() == 2 && output.len() >= 2 {
408 deinterleave::<T, _, 2>(input, output, output_range);
410 return;
411 }
412
413 assert!(input.len() >= (output_range.end - output_range.start) * num_in_channels.get());
414
415 for (ch_i, out_ch) in (0..num_in_channels.get()).zip(output.iter_mut()) {
416 let out_ch = out_ch.as_mut();
417
418 assert!(output_range.start < out_ch.len() && output_range.end <= out_ch.len());
419
420 unsafe {
423 for i in 0..(output_range.end - output_range.start) {
424 *out_ch.get_unchecked_mut(output_range.start + i) =
425 *input.get_unchecked((i * num_in_channels.get()) + ch_i);
426 }
427 }
428 }
429}
430
431#[cfg(test)]
432mod tests {
433 #[cfg(feature = "alloc")]
434 use alloc::{vec, vec::Vec};
435
436 use super::*;
437
438 #[test]
439 fn test_interleave() {
440 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
441 let mut output: Vec<i32> = vec![0; 4];
442 interleave::<_, _, 1>(&input, 1..4, &mut output);
443 assert_eq!(&output, &[2, 3, 4, 0]);
444
445 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
446 let mut output: Vec<i32> = vec![0; 8];
447 interleave::<_, _, 2>(&input, 1..4, &mut output);
448 assert_eq!(&output, &[2, 6, 3, 7, 4, 8, 0, 0]);
449
450 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
451 let mut output: Vec<i32> = vec![0; 12];
452 interleave::<_, _, 3>(&input, 1..4, &mut output);
453 assert_eq!(&output, &[2, 6, 10, 3, 7, 11, 4, 8, 12, 0, 0, 0]);
454 }
455
456 #[test]
457 fn test_deinterleave() {
458 let input: Vec<i32> = vec![1, 2, 3, 4];
459 let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
460 deinterleave::<_, _, 1>(&input, &mut output, 1..4);
461 assert_eq!(&output[0], &[0, 1, 2, 3]);
462
463 let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
464 let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
465 deinterleave::<_, _, 2>(&input, &mut output, 1..4);
466 assert_eq!(&output[0], &[0, 1, 3, 5]);
467 assert_eq!(&output[1], &[0, 2, 4, 6]);
468
469 let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
470 let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
471 deinterleave::<_, _, 3>(&input, &mut output, 1..4);
472 assert_eq!(&output[0], &[0, 1, 4, 7]);
473 assert_eq!(&output[1], &[0, 2, 5, 8]);
474 assert_eq!(&output[2], &[0, 3, 6, 9]);
475 }
476
477 #[test]
478 fn test_interleave_variable() {
479 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
480 let mut output: Vec<i32> = vec![0; 4];
481 interleave_variable(&input, 1..4, &mut output, NonZeroUsize::new(1).unwrap());
482 assert_eq!(&output, &[2, 3, 4, 0]);
483
484 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
485 let mut output: Vec<i32> = vec![0; 8];
486 interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(1).unwrap());
487 assert_eq!(&output, &[1, 2, 3, 4, 0, 0, 0, 0]);
488
489 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
490 let mut output: Vec<i32> = vec![0; 8];
491 interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
492 assert_eq!(&output, &[1, 0, 2, 0, 3, 0, 4, 0]);
493
494 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
495 let mut output: Vec<i32> = vec![0; 8];
496 interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
497 assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
498
499 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
500 let mut output: Vec<i32> = vec![0; 8];
501 interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
502 assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
503
504 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
505 let mut output: Vec<i32> = vec![0; 12];
506 interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(3).unwrap());
507 assert_eq!(&output, &[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]);
508 }
509
510 #[test]
511 fn test_interleave_to_vec_variable() {
512 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
513 let output = interleave_to_vec_variable(&input, 1..4, NonZeroUsize::new(1).unwrap());
514 assert_eq!(&output, &[2, 3, 4]);
515
516 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
517 let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(1).unwrap());
518 assert_eq!(&output, &[1, 2, 3, 4]);
519
520 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
521 let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(2).unwrap());
522 assert_eq!(&output, &[1, 0, 2, 0, 3, 0, 4, 0]);
523
524 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
525 let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(2).unwrap());
526 assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
527
528 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
529 let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(2).unwrap());
530 assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
531
532 let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
533 let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(3).unwrap());
534 assert_eq!(&output, &[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]);
535 }
536
537 #[test]
538 fn test_deinterleave_variable() {
539 let input: Vec<i32> = vec![1, 2, 3, 4];
540 let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
541 deinterleave_variable(&input, NonZeroUsize::new(1).unwrap(), &mut output, 1..4);
542 assert_eq!(&output[0], &[0, 1, 2, 3]);
543
544 let input: Vec<i32> = vec![1, 2, 3, 4];
545 let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
546 deinterleave_variable(&input, NonZeroUsize::new(1).unwrap(), &mut output, 0..4);
547 assert_eq!(&output[0], &[1, 2, 3, 4]);
548 assert_eq!(&output[1], &[0, 0, 0, 0]);
549
550 let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
551 let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
552 deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
553 assert_eq!(&output[0], &[1, 3, 5, 7]);
554
555 let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
556 let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
557 deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
558 assert_eq!(&output[0], &[1, 3, 5, 7]);
559 assert_eq!(&output[1], &[2, 4, 6, 8]);
560
561 let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
562 let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
563 deinterleave_variable(&input, NonZeroUsize::new(3).unwrap(), &mut output, 0..4);
564 assert_eq!(&output[0], &[1, 4, 7, 10]);
565 assert_eq!(&output[1], &[2, 5, 8, 11]);
566 assert_eq!(&output[2], &[3, 6, 9, 12]);
567 }
568}