Skip to content

Commit b996a61

Browse files
committed
ALSA: better card enumeration
1 parent b2f399e commit b996a61

File tree

2 files changed

+36
-27
lines changed

2 files changed

+36
-27
lines changed

Diff for: src/host/alsa/enumerate.rs

+26-18
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ use std::sync::{Arc, Mutex};
55

66
/// ALSA's implementation for `Devices`.
77
pub struct Devices {
8-
hint_iter: alsa::device_name::HintIter,
8+
card_iter: alsa::card::Iter,
99
}
1010

1111
impl Devices {
1212
pub fn new() -> Result<Self, DevicesError> {
1313
Ok(Devices {
14-
hint_iter: alsa::device_name::HintIter::new_str(None, "pcm")?,
14+
card_iter: alsa::card::Iter::new(),
1515
})
1616
}
1717
}
@@ -24,23 +24,29 @@ impl Iterator for Devices {
2424

2525
fn next(&mut self) -> Option<Device> {
2626
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-
};
27+
let Some(res) = self.card_iter.next() else {
28+
return None;
29+
};
30+
let Ok(card) = res else { continue };
3631

37-
if let Ok(handles) = DeviceHandles::open(&name) {
38-
return Some(Device {
39-
name,
40-
handles: Arc::new(Mutex::new(handles)),
41-
});
42-
}
43-
}
32+
let ctl_id = format!("hw:{}", card.get_index());
33+
let Ok(ctl) = alsa::Ctl::new(&ctl_id, false) else {
34+
continue;
35+
};
36+
let Ok(cardinfo) = ctl.card_info() else {
37+
continue;
38+
};
39+
let Ok(card_name) = cardinfo.get_name() else {
40+
continue;
41+
};
42+
43+
let pcm_id = format!("plughw:{}", card.get_index());
44+
if let Ok(handles) = DeviceHandles::open(&pcm_id) {
45+
return Some(Device {
46+
name: card_name.to_string(),
47+
pcm_id: pcm_id.to_string(),
48+
handles: Arc::new(Mutex::new(handles)),
49+
});
4450
}
4551
}
4652
}
@@ -50,6 +56,7 @@ impl Iterator for Devices {
5056
pub fn default_input_device() -> Option<Device> {
5157
Some(Device {
5258
name: "default".to_owned(),
59+
pcm_id: "default".to_owned(),
5360
handles: Arc::new(Mutex::new(Default::default())),
5461
})
5562
}
@@ -58,6 +65,7 @@ pub fn default_input_device() -> Option<Device> {
5865
pub fn default_output_device() -> Option<Device> {
5966
Some(Device {
6067
name: "default".to_owned(),
68+
pcm_id: "default".to_owned(),
6169
handles: Arc::new(Mutex::new(Default::default())),
6270
})
6371
}

Diff for: src/host/alsa/mod.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ struct DeviceHandles {
185185
impl DeviceHandles {
186186
/// Create `DeviceHandles` for `name` and try to open a handle for both
187187
/// directions. Returns `Ok` if either direction is opened successfully.
188-
fn open(name: &str) -> Result<Self, alsa::Error> {
188+
fn open(pcm_id: &str) -> Result<Self, alsa::Error> {
189189
let mut handles = Self::default();
190-
let playback_err = handles.try_open(name, alsa::Direction::Playback).err();
191-
let capture_err = handles.try_open(name, alsa::Direction::Capture).err();
190+
let playback_err = handles.try_open(pcm_id, alsa::Direction::Playback).err();
191+
let capture_err = handles.try_open(pcm_id, alsa::Direction::Capture).err();
192192
if let Some(err) = capture_err.and(playback_err) {
193193
Err(err)
194194
} else {
@@ -202,7 +202,7 @@ impl DeviceHandles {
202202
/// `Option` is guaranteed to be `Some(..)`.
203203
fn try_open(
204204
&mut self,
205-
name: &str,
205+
pcm_id: &str,
206206
stream_type: alsa::Direction,
207207
) -> Result<&mut Option<alsa::PCM>, alsa::Error> {
208208
let handle = match stream_type {
@@ -211,7 +211,7 @@ impl DeviceHandles {
211211
};
212212

213213
if handle.is_none() {
214-
*handle = Some(alsa::pcm::PCM::new(name, stream_type, true)?);
214+
*handle = Some(alsa::pcm::PCM::new(pcm_id, stream_type, true)?);
215215
}
216216

217217
Ok(handle)
@@ -221,10 +221,10 @@ impl DeviceHandles {
221221
/// If the handle is not yet opened, it will be opened and stored in `self`.
222222
fn get_mut(
223223
&mut self,
224-
name: &str,
224+
pcm_id: &str,
225225
stream_type: alsa::Direction,
226226
) -> Result<&mut alsa::PCM, alsa::Error> {
227-
Ok(self.try_open(name, stream_type)?.as_mut().unwrap())
227+
Ok(self.try_open(pcm_id, stream_type)?.as_mut().unwrap())
228228
}
229229

230230
/// Take ownership of the `alsa::PCM` handle for a specific `stream_type`.
@@ -237,6 +237,7 @@ impl DeviceHandles {
237237
#[derive(Clone)]
238238
pub struct Device {
239239
name: String,
240+
pcm_id: String,
240241
handles: Arc<Mutex<DeviceHandles>>,
241242
}
242243

@@ -251,7 +252,7 @@ impl Device {
251252
.handles
252253
.lock()
253254
.unwrap()
254-
.take(&self.name, stream_type)
255+
.take(&self.pcm_id, stream_type)
255256
.map_err(|e| (e, e.errno()));
256257

257258
let handle = match handle_result {
@@ -308,7 +309,7 @@ impl Device {
308309
) -> Result<VecIntoIter<SupportedStreamConfigRange>, SupportedStreamConfigsError> {
309310
let mut guard = self.handles.lock().unwrap();
310311
let handle_result = guard
311-
.get_mut(&self.name, stream_t)
312+
.get_mut(&self.pcm_id, stream_t)
312313
.map_err(|e| (e, e.errno()));
313314

314315
let handle = match handle_result {

0 commit comments

Comments
 (0)