1 use crate::audio::buffer::BufferInfo;
2 use crate::audio::sealed::Sealed;
3
4 pub trait BufferLayout: Sized + Sealed {
index_of(info: &BufferInfo<Self>, channel: usize, frame: usize) -> usize5 fn index_of(info: &BufferInfo<Self>, channel: usize, frame: usize) -> usize;
6 }
7
8 #[derive(Eq, PartialEq, Copy, Clone, Debug)]
9 pub enum Deinterleaved {}
10
11 impl Sealed for Deinterleaved {}
12
13 impl BufferLayout for Deinterleaved {
14 #[inline]
index_of(info: &BufferInfo<Self>, channel: usize, frame: usize) -> usize15 fn index_of(info: &BufferInfo<Self>, channel: usize, frame: usize) -> usize {
16 (channel * info.frames()) + frame
17 }
18 }
19
20 #[derive(Eq, PartialEq, Copy, Clone, Debug)]
21 pub enum Interleaved {}
22
23 impl Sealed for Interleaved {}
24
25 impl BufferLayout for Interleaved {
26 #[inline]
index_of(info: &BufferInfo<Self>, channel: usize, frame: usize) -> usize27 fn index_of(info: &BufferInfo<Self>, channel: usize, frame: usize) -> usize {
28 (frame * info.channels()) + channel
29 }
30 }
31
32 #[cfg(test)]
33 #[inline(always)]
deinterleaved<T>(input: &[T], output: &mut [T], channels: usize) where T: Copy,34 pub(crate) fn deinterleaved<T>(input: &[T], output: &mut [T], channels: usize)
35 where
36 T: Copy,
37 {
38 deinterleaved_by(input, output, channels, |sample| *sample)
39 }
40
41 /// De-interleaves an interleaved slice using a memory access pattern
42 /// that's optimized for efficient cached (i.e. sequential) reads.
deinterleaved_by<T, U, F>(input: &[T], output: &mut [U], channels: usize, f: F) where F: Fn(&T) -> U,43 pub(crate) fn deinterleaved_by<T, U, F>(input: &[T], output: &mut [U], channels: usize, f: F)
44 where
45 F: Fn(&T) -> U,
46 {
47 assert_eq!(input.len(), output.len());
48 assert_eq!(input.len() % channels, 0);
49
50 let frames = input.len() / channels;
51 let mut interleaved_index = 0;
52 for frame in 0..frames {
53 let mut deinterleaved_index = frame;
54 for _channel in 0..channels {
55 output[deinterleaved_index] = f(&input[interleaved_index]);
56 interleaved_index += 1;
57 deinterleaved_index += frames;
58 }
59 }
60 }
61
62 #[cfg(test)]
63 #[inline(always)]
interleaved<T>(input: &[T], output: &mut [T], channels: usize) where T: Copy,64 pub(crate) fn interleaved<T>(input: &[T], output: &mut [T], channels: usize)
65 where
66 T: Copy,
67 {
68 interleaved_by(input, output, channels, |sample| *sample)
69 }
70
71 /// Interleaves an de-interleaved slice using a memory access pattern
72 /// that's optimized for efficient cached (i.e. sequential) reads.
interleaved_by<T, U, F>(input: &[T], output: &mut [U], channels: usize, f: F) where F: Fn(&T) -> U,73 pub(crate) fn interleaved_by<T, U, F>(input: &[T], output: &mut [U], channels: usize, f: F)
74 where
75 F: Fn(&T) -> U,
76 {
77 assert_eq!(input.len(), output.len());
78 assert_eq!(input.len() % channels, 0);
79
80 let frames = input.len() / channels;
81 let mut deinterleaved_index = 0;
82 for channel in 0..channels {
83 let mut interleaved_index = channel;
84 for _frame in 0..frames {
85 output[interleaved_index] = f(&input[deinterleaved_index]);
86 deinterleaved_index += 1;
87 interleaved_index += channels;
88 }
89 }
90 }
91
92 #[cfg(test)]
93 mod tests {
94 use super::*;
95
96 #[test]
interleaved_1_channel()97 fn interleaved_1_channel() {
98 let input: Vec<_> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
99 let mut output = vec![0; input.len()];
100 let channels = 1;
101
102 interleaved(&input[..], &mut output[..], channels);
103
104 let actual = output;
105 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
106
107 assert_eq!(actual, expected);
108 }
109
110 #[test]
deinterleaved_1_channel()111 fn deinterleaved_1_channel() {
112 let input: Vec<_> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
113 let mut output = vec![0; input.len()];
114 let channels = 1;
115
116 deinterleaved(&input[..], &mut output[..], channels);
117
118 let actual = output;
119 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
120
121 assert_eq!(actual, expected);
122 }
123
124 #[test]
interleaved_2_channel()125 fn interleaved_2_channel() {
126 let input: Vec<_> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
127 let mut output = vec![0; input.len()];
128 let channels = 2;
129
130 interleaved(&input[..], &mut output[..], channels);
131
132 let actual = output;
133 let expected = vec![0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15];
134
135 assert_eq!(actual, expected);
136 }
137
138 #[test]
deinterleaved_2_channel()139 fn deinterleaved_2_channel() {
140 let input: Vec<_> = vec![0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15];
141 let mut output = vec![0; input.len()];
142 let channels = 2;
143
144 deinterleaved(&input[..], &mut output[..], channels);
145
146 let actual = output;
147 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
148
149 assert_eq!(actual, expected);
150 }
151
152 #[test]
interleaved_3_channel()153 fn interleaved_3_channel() {
154 let input: Vec<_> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
155 let mut output = vec![0; input.len()];
156 let channels = 3;
157
158 interleaved(&input[..], &mut output[..], channels);
159
160 let actual = output;
161 let expected = vec![0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14];
162
163 assert_eq!(actual, expected);
164 }
165
166 #[test]
deinterleaved_3_channel()167 fn deinterleaved_3_channel() {
168 let input: Vec<_> = vec![0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14];
169 let mut output = vec![0; input.len()];
170 let channels = 3;
171
172 deinterleaved(&input[..], &mut output[..], channels);
173
174 let actual = output;
175 let expected = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
176
177 assert_eq!(actual, expected);
178 }
179 }
180