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}