cubeb_core/
channel.rs

1// Copyright © 2017-2018 Mozilla Foundation
2//
3// This program is made available under an ISC-style license.  See the
4// accompanying file LICENSE for details.
5
6use ffi;
7
8bitflags! {
9    /// Some common layout definitions
10    pub struct ChannelLayout: ffi::cubeb_channel_layout {
11        const FRONT_LEFT = ffi::CHANNEL_FRONT_LEFT;
12        const FRONT_RIGHT = ffi::CHANNEL_FRONT_RIGHT;
13        const FRONT_CENTER = ffi::CHANNEL_FRONT_CENTER;
14        const LOW_FREQUENCY = ffi::CHANNEL_LOW_FREQUENCY;
15        const BACK_LEFT = ffi::CHANNEL_BACK_LEFT;
16        const BACK_RIGHT = ffi::CHANNEL_BACK_RIGHT;
17        const FRONT_LEFT_OF_CENTER = ffi::CHANNEL_FRONT_LEFT_OF_CENTER;
18        const FRONT_RIGHT_OF_CENTER = ffi::CHANNEL_FRONT_RIGHT_OF_CENTER;
19        const BACK_CENTER = ffi::CHANNEL_BACK_CENTER;
20        const SIDE_LEFT = ffi::CHANNEL_SIDE_LEFT;
21        const SIDE_RIGHT = ffi::CHANNEL_SIDE_RIGHT;
22        const TOP_CENTER = ffi::CHANNEL_TOP_CENTER;
23        const TOP_FRONT_LEFT = ffi::CHANNEL_TOP_FRONT_LEFT;
24        const TOP_FRONT_CENTER = ffi::CHANNEL_TOP_FRONT_CENTER;
25        const TOP_FRONT_RIGHT = ffi::CHANNEL_TOP_FRONT_RIGHT;
26        const TOP_BACK_LEFT = ffi::CHANNEL_TOP_BACK_LEFT;
27        const TOP_BACK_CENTER = ffi::CHANNEL_TOP_BACK_CENTER;
28        const TOP_BACK_RIGHT = ffi::CHANNEL_TOP_BACK_RIGHT;
29    }
30}
31
32macro_rules! bits {
33    ($($x:ident => $y:ident),*) => {
34        $(pub const $x: ChannelLayout = ChannelLayout::from_bits_truncate(ffi::$y);)*
35    }
36}
37
38impl ChannelLayout {
39    bits!(UNDEFINED => CUBEB_LAYOUT_UNDEFINED,
40          MONO => CUBEB_LAYOUT_MONO,
41          MONO_LFE => CUBEB_LAYOUT_MONO_LFE,
42          STEREO => CUBEB_LAYOUT_STEREO,
43          STEREO_LFE => CUBEB_LAYOUT_STEREO_LFE,
44          _3F => CUBEB_LAYOUT_3F,
45          _3F_LFE => CUBEB_LAYOUT_3F_LFE,
46          _2F1 => CUBEB_LAYOUT_2F1,
47          _2F1_LFE => CUBEB_LAYOUT_2F1_LFE,
48          _3F1 => CUBEB_LAYOUT_3F1,
49          _3F1_LFE => CUBEB_LAYOUT_3F1_LFE,
50          _2F2 => CUBEB_LAYOUT_2F2,
51          _2F2_LFE => CUBEB_LAYOUT_2F2_LFE,
52          QUAD => CUBEB_LAYOUT_QUAD,
53          QUAD_LFE => CUBEB_LAYOUT_QUAD_LFE,
54          _3F2 => CUBEB_LAYOUT_3F2,
55          _3F2_LFE => CUBEB_LAYOUT_3F2_LFE,
56          _3F2_BACK => CUBEB_LAYOUT_3F2_BACK,
57          _3F2_LFE_BACK => CUBEB_LAYOUT_3F2_LFE_BACK,
58          _3F3R_LFE => CUBEB_LAYOUT_3F3R_LFE,
59          _3F4_LFE => CUBEB_LAYOUT_3F4_LFE
60    );
61}
62
63impl From<ffi::cubeb_channel> for ChannelLayout {
64    fn from(x: ffi::cubeb_channel) -> Self {
65        ChannelLayout::from_bits_truncate(x)
66    }
67}
68
69impl From<ChannelLayout> for ffi::cubeb_channel {
70    fn from(x: ChannelLayout) -> Self {
71        x.bits()
72    }
73}
74
75impl ChannelLayout {
76    pub fn num_channels(&self) -> u32 {
77        unsafe { ffi::cubeb_channel_layout_nb_channels(self.bits()) }
78    }
79}
80
81#[cfg(test)]
82mod test {
83    use ffi;
84
85    #[test]
86    fn channel_layout_from_raw() {
87        macro_rules! check(
88            ($($raw:ident => $real:ident),*) => (
89                $(let x = super::ChannelLayout::from(ffi::$raw);
90                  assert_eq!(x, super::ChannelLayout::$real);
91                )*
92            ) );
93
94        check!(CUBEB_LAYOUT_UNDEFINED => UNDEFINED,
95               CUBEB_LAYOUT_MONO => MONO,
96               CUBEB_LAYOUT_MONO_LFE => MONO_LFE,
97               CUBEB_LAYOUT_STEREO => STEREO,
98               CUBEB_LAYOUT_STEREO_LFE => STEREO_LFE,
99               CUBEB_LAYOUT_3F => _3F,
100               CUBEB_LAYOUT_3F_LFE => _3F_LFE,
101               CUBEB_LAYOUT_2F1 => _2F1,
102               CUBEB_LAYOUT_2F1_LFE => _2F1_LFE,
103               CUBEB_LAYOUT_3F1 => _3F1,
104               CUBEB_LAYOUT_3F1_LFE => _3F1_LFE,
105               CUBEB_LAYOUT_2F2 => _2F2,
106               CUBEB_LAYOUT_2F2_LFE => _2F2_LFE,
107               CUBEB_LAYOUT_QUAD => QUAD,
108               CUBEB_LAYOUT_QUAD_LFE => QUAD_LFE,
109               CUBEB_LAYOUT_3F2 => _3F2,
110               CUBEB_LAYOUT_3F2_LFE => _3F2_LFE,
111               CUBEB_LAYOUT_3F2_BACK => _3F2_BACK,
112               CUBEB_LAYOUT_3F2_LFE_BACK => _3F2_LFE_BACK,
113               CUBEB_LAYOUT_3F3R_LFE => _3F3R_LFE,
114               CUBEB_LAYOUT_3F4_LFE => _3F4_LFE);
115    }
116
117    #[test]
118    fn channel_layout_into_raw() {
119        macro_rules! check(
120            ($($real:ident => $raw:ident),*) => (
121                $(let x = super::ChannelLayout::$real;
122                  let x: ffi::cubeb_channel_layout = x.into();
123                  assert_eq!(x, ffi::$raw);
124                )*
125            ) );
126
127        check!(UNDEFINED => CUBEB_LAYOUT_UNDEFINED,
128               MONO => CUBEB_LAYOUT_MONO,
129               MONO_LFE => CUBEB_LAYOUT_MONO_LFE,
130               STEREO => CUBEB_LAYOUT_STEREO,
131               STEREO_LFE => CUBEB_LAYOUT_STEREO_LFE,
132               _3F => CUBEB_LAYOUT_3F,
133               _3F_LFE => CUBEB_LAYOUT_3F_LFE,
134               _2F1 => CUBEB_LAYOUT_2F1,
135               _2F1_LFE=> CUBEB_LAYOUT_2F1_LFE,
136               _3F1 => CUBEB_LAYOUT_3F1,
137               _3F1_LFE =>  CUBEB_LAYOUT_3F1_LFE,
138               _2F2 => CUBEB_LAYOUT_2F2,
139               _2F2_LFE => CUBEB_LAYOUT_2F2_LFE,
140               QUAD => CUBEB_LAYOUT_QUAD,
141               QUAD_LFE => CUBEB_LAYOUT_QUAD_LFE,
142               _3F2 => CUBEB_LAYOUT_3F2,
143               _3F2_LFE => CUBEB_LAYOUT_3F2_LFE,
144               _3F2_BACK => CUBEB_LAYOUT_3F2_BACK,
145               _3F2_LFE_BACK => CUBEB_LAYOUT_3F2_LFE_BACK,
146               _3F3R_LFE => CUBEB_LAYOUT_3F3R_LFE,
147               _3F4_LFE => CUBEB_LAYOUT_3F4_LFE);
148    }
149}