xref: /webrtc/media/src/audio/buffer/layout.rs (revision ffe74184)
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