fixed_resample/
interleave.rs1use std::{num::NonZeroUsize, ops::Range};
2
3use rubato::Sample;
4
5pub fn interleave<T: Sample, Vin: AsRef<[T]>>(
12 input: &[Vin],
13 output: &mut [T],
14 num_out_channels: NonZeroUsize,
15 in_range: Range<usize>,
16) {
17 let in_frames = in_range.end - in_range.start;
18 let out_frames = output.len() / num_out_channels.get();
19
20 let frames = in_frames.min(out_frames);
21
22 let in_range = in_range.start..in_range.start + frames;
23
24 if num_out_channels.get() == 1 {
25 output[..frames].copy_from_slice(&input[0].as_ref()[in_range.clone()]);
27
28 return;
29 }
30
31 if num_out_channels.get() == 2 && input.len() >= 2 {
32 let in_ch_1 = &input[0].as_ref()[in_range.clone()];
34 let in_ch_2 = &input[1].as_ref()[in_range.clone()];
35
36 for ((os, &s1), &s2) in output.chunks_exact_mut(2).zip(in_ch_1).zip(in_ch_2) {
37 os[0] = s1;
38 os[1] = s2
39 }
40
41 return;
42 }
43
44 for (ch_i, in_ch) in input.iter().enumerate() {
45 if ch_i >= num_out_channels.get() {
46 break;
47 }
48
49 for (os, &is) in output
50 .chunks_exact_mut(num_out_channels.get())
51 .zip(&in_ch.as_ref()[in_range.clone()])
52 {
53 os[ch_i] = is;
54 }
55 }
56}
57
58pub fn deinterleave<T: Sample, Vout: AsMut<[T]>>(
65 input: &[T],
66 output: &mut [Vout],
67 num_in_channels: NonZeroUsize,
68 out_range: Range<usize>,
69) {
70 let out_frames = out_range.end - out_range.start;
71 let in_frames = input.len() / num_in_channels.get();
72
73 let frames = out_frames.min(in_frames);
74
75 let out_range = out_range.start..out_range.start + frames;
76
77 if num_in_channels.get() == 1 {
78 output[0].as_mut()[out_range.clone()].copy_from_slice(&input[..frames]);
80
81 return;
82 }
83
84 if num_in_channels.get() == 2 && output.len() >= 2 {
85 let (out_ch_1, out_ch_2) = output.split_first_mut().unwrap();
87
88 for ((s, os1), os2) in input
89 .chunks_exact(2)
90 .zip(out_ch_1.as_mut()[out_range.clone()].iter_mut())
91 .zip(out_ch_2[0].as_mut()[out_range.clone()].iter_mut())
92 {
93 *os1 = s[0];
94 *os2 = s[1];
95 }
96
97 return;
98 }
99
100 for (ch_i, out_ch) in output.iter_mut().enumerate() {
101 if ch_i >= num_in_channels.get() {
102 break;
103 }
104
105 for (s, os) in input
106 .chunks_exact(num_in_channels.get())
107 .zip(&mut out_ch.as_mut()[out_range.clone()])
108 {
109 *os = s[ch_i];
110 }
111 }
112}