Skip to main content

rtc_media/audio/buffer/
info.rs

1use std::marker::PhantomData;
2
3use crate::audio::buffer::layout::{Deinterleaved, Interleaved};
4
5#[derive(Eq, PartialEq, Debug)]
6/// The channel and frame counts of a buffer, tagged with its layout `L`.
7pub struct BufferInfo<L> {
8    channels: usize,
9    frames: usize,
10    _phantom: PhantomData<L>,
11}
12
13impl<L> BufferInfo<L> {
14    /// Describes a buffer of `channels` channels and `frames` frames per channel.
15    pub fn new(channels: usize, frames: usize) -> Self {
16        Self {
17            channels,
18            frames,
19            _phantom: PhantomData,
20        }
21    }
22
23    /// Get a reference to the buffer info's channels.
24    pub fn channels(&self) -> usize {
25        self.channels
26    }
27
28    /// Set the buffer info's channels.
29    pub fn set_channels(&mut self, channels: usize) {
30        self.channels = channels;
31    }
32
33    /// Get a reference to the buffer info's frames.
34    pub fn frames(&self) -> usize {
35        self.frames
36    }
37
38    /// Set the buffer info's frames.
39    pub fn set_frames(&mut self, frames: usize) {
40        self.frames = frames;
41    }
42
43    /// The total sample count: channels times frames.
44    pub fn samples(&self) -> usize {
45        self.channels * self.frames
46    }
47}
48
49impl<L> Copy for BufferInfo<L> {}
50
51impl<L> Clone for BufferInfo<L> {
52    fn clone(&self) -> Self {
53        *self
54    }
55}
56
57macro_rules! impl_from_buffer_info {
58    ($in_layout:ty => $out_layout:ty) => {
59        impl From<BufferInfo<$in_layout>> for BufferInfo<$out_layout> {
60            fn from(info: BufferInfo<$in_layout>) -> Self {
61                Self {
62                    channels: info.channels,
63                    frames: info.frames,
64                    _phantom: PhantomData,
65                }
66            }
67        }
68    };
69}
70
71impl_from_buffer_info!(Interleaved => Deinterleaved);
72impl_from_buffer_info!(Deinterleaved => Interleaved);
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn new() {
80        let channels = 3;
81        let frames = 100;
82
83        let interleaved = BufferInfo::<Interleaved>::new(channels, frames);
84
85        assert_eq!(interleaved.channels, channels);
86        assert_eq!(interleaved.frames, frames);
87
88        let deinterleaved = BufferInfo::<Deinterleaved>::new(channels, frames);
89
90        assert_eq!(deinterleaved.channels, channels);
91        assert_eq!(deinterleaved.frames, frames);
92    }
93
94    #[test]
95    fn clone() {
96        let channels = 3;
97        let frames = 100;
98
99        let interleaved = BufferInfo::<Interleaved>::new(channels, frames);
100
101        assert_eq!(interleaved.clone(), interleaved);
102
103        let deinterleaved = BufferInfo::<Deinterleaved>::new(channels, frames);
104
105        assert_eq!(deinterleaved.clone(), deinterleaved);
106    }
107
108    #[test]
109    fn samples() {
110        let channels = 3;
111        let frames = 100;
112
113        let interleaved = BufferInfo::<Interleaved>::new(channels, frames);
114
115        assert_eq!(interleaved.samples(), channels * frames);
116
117        let deinterleaved = BufferInfo::<Deinterleaved>::new(channels, frames);
118
119        assert_eq!(deinterleaved.samples(), channels * frames);
120    }
121}