From 3947d5b07a5fb2ce74f6cd9348e4b3668b5b84f4 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Sun, 28 Jun 2026 12:46:06 +0000 Subject: [PATCH] fix(host/audio): drive the Linux virtual mic with RT_PROCESS (was silent) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The punktfunk-mic PipeWire source connected without RT_PROCESS, so it ran as an async/main-loop node. In the host's busy multi-stream graph (desktop audio + video capture + the session) it never acquired a driver, stayed suspended, and its process() callback never fired — every recorder reading the remote mic heard pure silence (the long-standing "Linux host mic broken"). Connect the mic stream with RT_PROCESS so it is a synchronous node that joins its consumer's driver group and is actually driven. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/punktfunk-host/src/audio/linux/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/punktfunk-host/src/audio/linux/mod.rs b/crates/punktfunk-host/src/audio/linux/mod.rs index 52a7f8d..78c1e2b 100644 --- a/crates/punktfunk-host/src/audio/linux/mod.rs +++ b/crates/punktfunk-host/src/audio/linux/mod.rs @@ -320,11 +320,18 @@ fn mic_pw_thread( .into_inner(); let mut params = [Pod::from_bytes(&values).context("mic pod from bytes")?]; + // RT_PROCESS: run the producer callback on PipeWire's realtime data loop, so the source is a + // *synchronous* graph node that joins its consumer's driver group and is actually driven. Without + // it the node is async/main-loop and, in the host's busy multi-stream graph (desktop-audio + + // video capture + the session), never acquires a driver — it stays suspended and its process() + // never fires, so every recorder hears pure silence (the long-standing "Linux host mic broken"). stream .connect( spa::utils::Direction::Output, // we PRODUCE samples (a source) None, - pw::stream::StreamFlags::AUTOCONNECT | pw::stream::StreamFlags::MAP_BUFFERS, + pw::stream::StreamFlags::AUTOCONNECT + | pw::stream::StreamFlags::MAP_BUFFERS + | pw::stream::StreamFlags::RT_PROCESS, &mut params, ) .context("pw mic stream connect")?;