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