feat(audio): add list_audio_devices command; wire device into start_recording

list_audio_devices runs the (blocking, COM-based) enumeration off the
async runtime via spawn_blocking, same pattern as import_pst_core.
start_recording now passes settings.audio_output_device through to
WasapiCapture::start instead of always capturing the default device.
This commit is contained in:
iamdoubz
2026-07-06 16:00:49 -05:00
parent 8e3e22c0e5
commit 2759a0e49a
+19 -1
View File
@@ -62,6 +62,7 @@ fn default_settings() -> Settings {
retention_max_size_gb: None,
pst_last_path: None,
pst_auto_sync: false,
audio_output_device: None,
}
}
@@ -286,7 +287,12 @@ pub async fn start_recording(
// Level updates + device-change notices (FR-CAP-5/6); low-volume, forwarded to events below.
let (event_tx, event_rx) = std::sync::mpsc::sync_channel::<crate::audio::CaptureEvent>(8);
let capture = WasapiCapture
.start(&wav_path, frame_tx, event_tx)
.start(
&wav_path,
settings.audio_output_device.as_deref(),
frame_tx,
event_tx,
)
.map_err(|e| WaError::new("audio", e.to_string()))?;
// Fire-and-forget: exits on its own once `event_tx` drops at capture stop;
@@ -905,6 +911,18 @@ pub async fn hardware_status() -> WaResult<serde_json::Value> {
}))
}
/// Lists active render (playback) devices for the "Audio Devices" picker
/// (Settings ▸ Hardware) — loopback-only, matching the app's only capture
/// path (FR-CAP-1). Runs off the async runtime thread since device
/// enumeration is a blocking COM call.
#[tauri::command]
pub async fn list_audio_devices() -> WaResult<Vec<crate::audio::AudioDeviceInfo>> {
tauri::async_runtime::spawn_blocking(crate::audio::list_render_devices)
.await
.map_err(|e| WaError::new("audio", e.to_string()))?
.map_err(|e| WaError::new("audio", e.to_string()))
}
#[derive(Deserialize)]
pub struct SetPreferredBackendArgs {
pub backend: String, // "auto"|"npu"|"nvidia"|"amd"|"intel"|"cpu"