fix: show one linux audio backend
This commit is contained in:
@@ -124,14 +124,14 @@ fn pulse_output_name_from_id(id: &str) -> Option<&str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_input_devices(default_label: Option<&str>) -> Vec<AudioDeviceInfo> {
|
pub(crate) fn list_input_devices(default_label: Option<&str>) -> Vec<AudioDeviceInfo> {
|
||||||
visible_devices(list_devices(LinuxDirection::Input))
|
list_devices(LinuxDirection::Input)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|device| device.to_audio_device_info(default_label))
|
.map(|device| device.to_audio_device_info(default_label))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_output_devices(default_label: Option<&str>) -> Vec<AudioDeviceInfo> {
|
pub(crate) fn list_output_devices(default_label: Option<&str>) -> Vec<AudioDeviceInfo> {
|
||||||
visible_devices(list_devices(LinuxDirection::Output))
|
list_devices(LinuxDirection::Output)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|device| device.to_audio_device_info(default_label))
|
.map(|device| device.to_audio_device_info(default_label))
|
||||||
.collect()
|
.collect()
|
||||||
@@ -237,39 +237,22 @@ fn select_device(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn list_devices(direction: LinuxDirection) -> Vec<LinuxDevice> {
|
fn list_devices(direction: LinuxDirection) -> Vec<LinuxDevice> {
|
||||||
let mut devices = Vec::new();
|
|
||||||
match list_pipewire_nodes(direction) {
|
match list_pipewire_nodes(direction) {
|
||||||
Ok(mut pipewire) => devices.append(&mut pipewire),
|
Ok(pipewire) if !pipewire.is_empty() => return pipewire,
|
||||||
|
Ok(_) => {
|
||||||
|
warn!(target: "chanora_audio", "PipeWire device enumeration returned no devices; trying PulseAudio fallback")
|
||||||
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
warn!(target: "chanora_audio", error = %error, "PipeWire device enumeration failed")
|
warn!(target: "chanora_audio", error = %error, "PipeWire device enumeration failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match list_pulse_devices(direction) {
|
match list_pulse_devices(direction) {
|
||||||
Ok(mut pulse) => devices.append(&mut pulse),
|
Ok(pulse) => pulse,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
warn!(target: "chanora_audio", error = %error, "PulseAudio device enumeration failed")
|
warn!(target: "chanora_audio", error = %error, "PulseAudio device enumeration failed");
|
||||||
|
Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
devices
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visible_devices(devices: Vec<LinuxDevice>) -> Vec<LinuxDevice> {
|
|
||||||
let pipewire_labels = devices
|
|
||||||
.iter()
|
|
||||||
.filter(|device| device.backend == LinuxBackend::PipeWire)
|
|
||||||
.map(|device| normalized_device_label(&device.label))
|
|
||||||
.collect::<std::collections::HashSet<_>>();
|
|
||||||
devices
|
|
||||||
.into_iter()
|
|
||||||
.filter(|device| {
|
|
||||||
device.backend == LinuxBackend::PipeWire
|
|
||||||
|| !pipewire_labels.contains(&normalized_device_label(&device.label))
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn normalized_device_label(label: &str) -> String {
|
|
||||||
label.split_whitespace().collect::<Vec<_>>().join(" ").to_lowercase()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_pipewire_nodes(direction: LinuxDirection) -> Result<Vec<LinuxDevice>, String> {
|
fn list_pipewire_nodes(direction: LinuxDirection) -> Result<Vec<LinuxDevice>, String> {
|
||||||
@@ -951,8 +934,7 @@ mod tests {
|
|||||||
use super::{
|
use super::{
|
||||||
input_device_id, input_device_node_id_from_id, output_device_id,
|
input_device_id, input_device_node_id_from_id, output_device_id,
|
||||||
output_device_node_id_from_id, pulse_input_device_id, pulse_input_name_from_id,
|
output_device_node_id_from_id, pulse_input_device_id, pulse_input_name_from_id,
|
||||||
pulse_output_device_id, pulse_output_name_from_id, visible_devices, LinuxBackend,
|
pulse_output_device_id, pulse_output_name_from_id,
|
||||||
LinuxDevice, LinuxDirection,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -982,32 +964,4 @@ mod tests {
|
|||||||
Some("alsa_output.pci-0000_00_1f.3")
|
Some("alsa_output.pci-0000_00_1f.3")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn visible_devices_hides_pulse_duplicates_when_pipewire_matches() {
|
|
||||||
let devices = visible_devices(vec![
|
|
||||||
LinuxDevice {
|
|
||||||
backend: LinuxBackend::PipeWire,
|
|
||||||
direction: LinuxDirection::Output,
|
|
||||||
raw_id: "42".to_string(),
|
|
||||||
label: "Built-in Audio Analog Stereo".to_string(),
|
|
||||||
},
|
|
||||||
LinuxDevice {
|
|
||||||
backend: LinuxBackend::PulseAudio,
|
|
||||||
direction: LinuxDirection::Output,
|
|
||||||
raw_id: "alsa_output.pci-0000".to_string(),
|
|
||||||
label: " built-in audio analog stereo ".to_string(),
|
|
||||||
},
|
|
||||||
LinuxDevice {
|
|
||||||
backend: LinuxBackend::PulseAudio,
|
|
||||||
direction: LinuxDirection::Output,
|
|
||||||
raw_id: "bluez_output.headset".to_string(),
|
|
||||||
label: "Headset".to_string(),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert_eq!(devices.len(), 2);
|
|
||||||
assert!(devices.iter().any(|device| device.backend == LinuxBackend::PipeWire));
|
|
||||||
assert!(devices.iter().any(|device| device.label == "Headset"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user