1use ffi;
7use std::str;
8use util::opt_bytes;
9
10#[derive(PartialEq, Eq, Clone, Debug, Copy)]
12pub enum DeviceState {
13 Disabled,
15 Unplugged,
17 Enabled,
19}
20
21bitflags! {
22 pub struct DeviceFormat: ffi::cubeb_device_fmt {
24 const S16LE = ffi::CUBEB_DEVICE_FMT_S16LE;
25 const S16BE = ffi::CUBEB_DEVICE_FMT_S16BE;
26 const F32LE = ffi::CUBEB_DEVICE_FMT_F32LE;
27 const F32BE = ffi::CUBEB_DEVICE_FMT_F32BE;
28 }
29}
30
31bitflags! {
32 pub struct DevicePref: ffi::cubeb_device_pref {
36 const MULTIMEDIA = ffi::CUBEB_DEVICE_PREF_MULTIMEDIA;
37 const VOICE = ffi::CUBEB_DEVICE_PREF_VOICE;
38 const NOTIFICATION = ffi::CUBEB_DEVICE_PREF_NOTIFICATION;
39 const ALL = ffi::CUBEB_DEVICE_PREF_ALL;
40 }
41}
42
43impl DevicePref {
44 pub const NONE: Self = Self::empty();
45}
46
47bitflags! {
48 pub struct DeviceType: ffi::cubeb_device_type {
51 const INPUT = ffi::CUBEB_DEVICE_TYPE_INPUT as _;
52 const OUTPUT = ffi::CUBEB_DEVICE_TYPE_OUTPUT as _;
53 }
54}
55
56impl DeviceType {
57 pub const UNKNOWN: Self = Self::empty();
58}
59
60pub type DeviceId = ffi::cubeb_devid;
63
64ffi_type_heap! {
65 type CType = ffi::cubeb_device;
67 #[derive(Debug)]
68 pub struct Device;
69 pub struct DeviceRef;
70}
71
72impl DeviceRef {
73 fn get_ref(&self) -> &ffi::cubeb_device {
74 unsafe { &*self.as_ptr() }
75 }
76
77 pub fn output_name(&self) -> Option<&str> {
81 self.output_name_bytes().map(|b| str::from_utf8(b).unwrap())
82 }
83
84 pub fn output_name_bytes(&self) -> Option<&[u8]> {
85 unsafe { opt_bytes(self.get_ref().output_name) }
86 }
87
88 pub fn input_name(&self) -> Option<&str> {
92 self.input_name_bytes().map(|b| str::from_utf8(b).unwrap())
93 }
94
95 pub fn input_name_bytes(&self) -> Option<&[u8]> {
96 unsafe { opt_bytes(self.get_ref().input_name) }
97 }
98}
99
100ffi_type_stack! {
101 type CType = ffi::cubeb_device_info;
106 pub struct DeviceInfo;
107 pub struct DeviceInfoRef;
108}
109
110impl DeviceInfoRef {
111 fn get_ref(&self) -> &ffi::cubeb_device_info {
112 unsafe { &*self.as_ptr() }
113 }
114
115 pub fn devid(&self) -> DeviceId {
117 self.get_ref().devid
118 }
119
120 pub fn device_id(&self) -> Option<&str> {
122 self.device_id_bytes().map(|b| str::from_utf8(b).unwrap())
123 }
124
125 pub fn device_id_bytes(&self) -> Option<&[u8]> {
126 unsafe { opt_bytes(self.get_ref().device_id) }
127 }
128
129 pub fn friendly_name(&self) -> Option<&str> {
131 self.friendly_name_bytes()
132 .map(|b| str::from_utf8(b).unwrap())
133 }
134
135 pub fn friendly_name_bytes(&self) -> Option<&[u8]> {
136 unsafe { opt_bytes(self.get_ref().friendly_name) }
137 }
138
139 pub fn group_id(&self) -> Option<&str> {
143 self.group_id_bytes().map(|b| str::from_utf8(b).unwrap())
144 }
145
146 pub fn group_id_bytes(&self) -> Option<&[u8]> {
147 unsafe { opt_bytes(self.get_ref().group_id) }
148 }
149
150 pub fn vendor_name(&self) -> Option<&str> {
152 self.vendor_name_bytes().map(|b| str::from_utf8(b).unwrap())
153 }
154
155 pub fn vendor_name_bytes(&self) -> Option<&[u8]> {
156 unsafe { opt_bytes(self.get_ref().vendor_name) }
157 }
158
159 pub fn device_type(&self) -> DeviceType {
161 DeviceType::from_bits_truncate(self.get_ref().device_type)
162 }
163
164 pub fn state(&self) -> DeviceState {
166 let state = self.get_ref().state;
167 macro_rules! check( ($($raw:ident => $real:ident),*) => (
168 $(if state == ffi::$raw {
169 DeviceState::$real
170 }) else *
171 else {
172 panic!("unknown device state: {}", state)
173 }
174 ));
175
176 check!(CUBEB_DEVICE_STATE_DISABLED => Disabled,
177 CUBEB_DEVICE_STATE_UNPLUGGED => Unplugged,
178 CUBEB_DEVICE_STATE_ENABLED => Enabled)
179 }
180
181 pub fn preferred(&self) -> DevicePref {
183 DevicePref::from_bits(self.get_ref().preferred).unwrap()
184 }
185
186 pub fn format(&self) -> DeviceFormat {
188 DeviceFormat::from_bits(self.get_ref().format).unwrap()
189 }
190
191 pub fn default_format(&self) -> DeviceFormat {
193 DeviceFormat::from_bits(self.get_ref().default_format).unwrap()
194 }
195
196 pub fn max_channels(&self) -> u32 {
198 self.get_ref().max_channels
199 }
200
201 pub fn default_rate(&self) -> u32 {
203 self.get_ref().default_rate
204 }
205
206 pub fn max_rate(&self) -> u32 {
208 self.get_ref().max_rate
209 }
210
211 pub fn min_rate(&self) -> u32 {
213 self.get_ref().min_rate
214 }
215
216 pub fn latency_lo(&self) -> u32 {
218 self.get_ref().latency_lo
219 }
220
221 pub fn latency_hi(&self) -> u32 {
223 self.get_ref().latency_hi
224 }
225}
226
227#[cfg(test)]
228mod tests {
229 use ffi::cubeb_device;
230 use Device;
231
232 #[test]
233 fn device_device_ref_same_ptr() {
234 let ptr: *mut cubeb_device = 0xDEAD_BEEF as *mut _;
235 let device = unsafe { Device::from_ptr(ptr) };
236 assert_eq!(device.as_ptr(), ptr);
237 assert_eq!(device.as_ptr(), device.as_ref().as_ptr());
238 }
239}