perf: Optimize PipeWire communication with single background thread actor

Replaces the previous approach of spawning new PipeWire main loops and
awaiting a 100ms timeout for every `get_all_devices` call. Instead,
this introduces a `PipeWireManager` which maintains a single, persistent
background thread with a PipeWire main loop and registry listener. The
actor caches `AudioDevice`s and `Port`s continuously in a `HashMap`,
providing instantaneous responses to device queries via a channel.

This architectural change replaces `Sender<Terminate>` with a simple
`PwTerminator` drop-guard to manage the lifetimes of PipeWire objects
(virtual mic and links) via `PwCommand::DestroyObject` without creating
additional OS threads or PipeWire contexts.

Co-authored-by: arabianq <55220741+arabianq@users.noreply.github.com>
This commit is contained in:
google-labs-jules[bot]
2026-06-13 14:34:54 +00:00
parent 838fc1ce29
commit 2a56e1db6b
3 changed files with 291 additions and 272 deletions
+4 -1
View File
@@ -28,7 +28,10 @@ async fn main() -> Result<()> {
}
get_daemon_config(); // Initialize daemon config
create_virtual_mic()?;
// Virtual mic object must be kept alive by some variable until daemon exits
let _virtual_mic = create_virtual_mic().await?;
if let Err(err) = get_audio_player().await {
eprintln!("Failed to initialize audio player: {}", err);
} // Initialize audio player