Skip to main content

rtc_media/audio/buffer/
layout.rs

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