cpal/host/alsa/
enumerate.rs

1use super::alsa;
2use super::{Device, DeviceHandles};
3use crate::{BackendSpecificError, DevicesError};
4use std::sync::{Arc, Mutex};
5
6/// ALSA's implementation for `Devices`.
7pub struct Devices {
8    hint_iter: alsa::device_name::HintIter,
9}
10
11impl Devices {
12    pub fn new() -> Result<Self, DevicesError> {
13        Ok(Devices {
14            hint_iter: alsa::device_name::HintIter::new_str(None, "pcm")?,
15        })
16    }
17}
18
19unsafe impl Send for Devices {}
20unsafe impl Sync for Devices {}
21
22impl 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]
50pub fn default_input_device() -> Option<Device> {
51    Some(Device {
52        name: "default".to_owned(),
53        handles: Arc::new(Mutex::new(Default::default())),
54    })
55}
56
57#[inline]
58pub fn default_output_device() -> Option<Device> {
59    Some(Device {
60        name: "default".to_owned(),
61        handles: Arc::new(Mutex::new(Default::default())),
62    })
63}
64
65impl From<alsa::Error> for DevicesError {
66    fn from(err: alsa::Error) -> Self {
67        let err: BackendSpecificError = err.into();
68        err.into()
69    }
70}