Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 7 additions & 57 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ libc = "0.2"
# event-handle APIs from the exclusive-mode output thread without
# going through `wasapi`'s less ergonomic wrappers.
[target.'cfg(target_os = "windows")'.dependencies]
wasapi = "0.17"
wasapi = "0.23"
windows = { version = "0.62", features = [
"Win32_Foundation",
"Win32_System_Com",
Expand Down
21 changes: 14 additions & 7 deletions src-tauri/src/audio/wasapi_exclusive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ use crossbeam_channel::{bounded, Receiver, Sender};
use rtrb::{Consumer, Producer, RingBuffer};
use tauri::AppHandle;
use wasapi::{
get_default_device, AudioClient, AudioRenderClient, Device, DeviceCollection, Direction,
Handle, SampleType, ShareMode, StreamMode, WaveFormat,
AudioClient, AudioRenderClient, Device, DeviceEnumerator, Direction, Handle, SampleType,
ShareMode, StreamMode, WaveFormat,
};

use super::output::{OutputHandle, RING_CAPACITY};
Expand Down Expand Up @@ -260,11 +260,17 @@ fn open_exclusive_session(
}

fn pick_device(device_name: &Option<String>) -> AppResult<Device> {
// wasapi 0.23 removed the free `get_default_device` / `DeviceCollection`
// entry points; everything now goes through a `DeviceEnumerator`
// (which owns the underlying `IMMDeviceEnumerator` COM pointer).
let enumerator = DeviceEnumerator::new()
.map_err(|e| AppError::Audio(format!("DeviceEnumerator::new: {e:?}")))?;
if let Some(name) = device_name.as_deref().filter(|n| !n.is_empty()) {
// Iterate the render collection until we find a friendlyname
// match. The Linux ALSA story has the same pattern — name
// strings are how we pin a specific endpoint across reboots.
let coll = DeviceCollection::new(&Direction::Render)
// Friendly-name lookup lives on the collection, not the
// enumerator (the enumerator's `get_device` wants an opaque
// device-id, not the human-readable name we persist).
let coll = enumerator
.get_device_collection(&Direction::Render)
.map_err(|e| AppError::Audio(format!("enumerate render devices: {e:?}")))?;
if let Ok(dev) = coll.get_device_with_name(name) {
return Ok(dev);
Expand All @@ -274,7 +280,8 @@ fn pick_device(device_name: &Option<String>) -> AppResult<Device> {
"wasapi exclusive: requested device not found, falling back to default"
);
}
get_default_device(&Direction::Render)
enumerator
.get_default_device(&Direction::Render)
.map_err(|e| AppError::Audio(format!("default render device: {e:?}")))
}

Expand Down
Loading