1 | use super::alsa; |
2 | use super::{Device, DeviceHandles}; |
3 | use crate::{BackendSpecificError, DevicesError}; |
4 | use std::sync::{Arc, Mutex}; |
5 | |
6 | /// ALSA's implementation for `Devices`. |
7 | pub struct Devices { |
8 | hint_iter: alsa::device_name::HintIter, |
9 | } |
10 | |
11 | impl Devices { |
12 | pub fn new() -> Result<Self, DevicesError> { |
13 | Ok(Devices { |
14 | hint_iter: alsa::device_name::HintIter::new_str(card:None, iface:"pcm" )?, |
15 | }) |
16 | } |
17 | } |
18 | |
19 | unsafe impl Send for Devices {} |
20 | unsafe impl Sync for Devices {} |
21 | |
22 | impl Iterator for Devices { |
23 | type Item = Device; |
24 | |
25 | fn next(&mut self) -> Option<Device> { |
26 | loop { |
27 | match self.hint_iter.next() { |
28 | None => return None, |
29 | Some(hint) => { |
30 | let name = match hint.name { |
31 | None => continue, |
32 | // Ignoring the `null` device. |
33 | Some(name) if name == "null" => continue, |
34 | Some(name) => name, |
35 | }; |
36 | |
37 | if let Ok(handles) = DeviceHandles::open(&name) { |
38 | return Some(Device { |
39 | name, |
40 | handles: Arc::new(Mutex::new(handles)), |
41 | }); |
42 | } |
43 | } |
44 | } |
45 | } |
46 | } |
47 | } |
48 | |
49 | #[inline ] |
50 | pub fn default_input_device() -> Option<Device> { |
51 | Some(Device { |
52 | name: "default" .to_owned(), |
53 | handles: Arc::new(data:Mutex::new(Default::default())), |
54 | }) |
55 | } |
56 | |
57 | #[inline ] |
58 | pub fn default_output_device() -> Option<Device> { |
59 | Some(Device { |
60 | name: "default" .to_owned(), |
61 | handles: Arc::new(data:Mutex::new(Default::default())), |
62 | }) |
63 | } |
64 | |
65 | impl From<alsa::Error> for DevicesError { |
66 | fn from(err: alsa::Error) -> Self { |
67 | let err: BackendSpecificError = err.into(); |
68 | err.into() |
69 | } |
70 | } |
71 | |