audio_device/alsa/
card.rs

1use crate::alsa::{CString, Result};
2use crate::libc as c;
3use alsa_sys as alsa;
4use std::ffi::CStr;
5use std::mem;
6
7/// Construct an iterator over sounds cards.
8///
9/// # Examples
10///
11/// ```rust,no_run
12/// use audio_device::alsa;
13///
14/// # fn main() -> anyhow::Result<()> {
15/// for card in alsa::cards() {
16///     let card = card?;
17///     println!("{}", card.name()?.to_str()?);
18/// }
19/// # Ok(()) }
20/// ```
21pub fn cards() -> Cards {
22    Cards { index: -1 }
23}
24
25/// An iterator over available cards.
26///
27/// See [cards].
28pub struct Cards {
29    index: c::c_int,
30}
31
32impl Iterator for Cards {
33    type Item = Result<Card>;
34
35    fn next(&mut self) -> Option<Self::Item> {
36        Some(
37            if let Err(e) = errno!(unsafe { alsa::snd_card_next(&mut self.index) }) {
38                Err(e.into())
39            } else {
40                if self.index == -1 {
41                    return None;
42                }
43
44                Ok(Card { index: self.index })
45            },
46        )
47    }
48}
49
50/// A reference to a card.
51pub struct Card {
52    index: c::c_int,
53}
54
55impl Card {
56    /// Open the given pcm device identified by name.
57    ///
58    /// # Examples
59    ///
60    /// ```rust,no_run
61    /// use audio_device::alsa;
62    /// use std::ffi::CStr;
63    ///
64    /// # fn main() -> anyhow::Result<()> {
65    /// let name = CStr::from_bytes_with_nul(b"hw:0\0")?;
66    ///
67    /// let pcm = alsa::Card::open(name)?;
68    /// # Ok(()) }
69    /// ```
70    pub fn open(name: &CStr) -> Result<Self> {
71        unsafe {
72            let index = errno!(alsa::snd_card_get_index(
73                name.to_bytes().as_ptr() as *const i8
74            ))?;
75            Ok(Self { index })
76        }
77    }
78
79    /// Get the index of the card.
80    ///
81    /// # Examples
82    ///
83    /// ```rust,no_run
84    /// use audio_device::alsa;
85    ///
86    /// # fn main() -> anyhow::Result<()> {
87    /// for card in alsa::cards() {
88    ///     let card = card?;
89    ///     println!("{}", card.index());
90    /// }
91    /// # Ok(()) }
92    /// ```
93    pub fn index(&self) -> c::c_int {
94        self.index
95    }
96
97    /// Get the name of the card.
98    ///
99    /// # Examples
100    ///
101    /// ```rust,no_run
102    /// use audio_device::alsa;
103    ///
104    /// # fn main() -> anyhow::Result<()> {
105    /// for card in alsa::cards() {
106    ///     let card = card?;
107    ///     println!("{}", card.name()?.to_str()?);
108    /// }
109    /// # Ok(()) }
110    /// ```
111    pub fn name(&self) -> Result<CString> {
112        unsafe {
113            let mut ptr = mem::MaybeUninit::uninit();
114            errno!(alsa::snd_card_get_name(self.index, ptr.as_mut_ptr()))?;
115            let ptr = ptr.assume_init();
116            Ok(CString::from_raw(ptr))
117        }
118    }
119
120    /// Get the long name of the card.
121    ///
122    /// # Examples
123    ///
124    /// ```rust,no_run
125    /// use audio_device::alsa;
126    ///
127    /// # fn main() -> anyhow::Result<()> {
128    /// for card in alsa::cards() {
129    ///     let card = card?;
130    ///     println!("{}", card.long_name()?.to_str()?);
131    /// }
132    /// # Ok(()) }
133    /// ```
134    pub fn long_name(&self) -> Result<CString> {
135        unsafe {
136            let mut ptr = mem::MaybeUninit::uninit();
137            errno!(alsa::snd_card_get_longname(self.index, ptr.as_mut_ptr()))?;
138            let ptr = ptr.assume_init();
139            Ok(CString::from_raw(ptr))
140        }
141    }
142}