From 75de1e50b9ab0c2c3d01c4796d946a7451266ff4 Mon Sep 17 00:00:00 2001 From: Stanislaw Grams Date: Sat, 7 Feb 2026 15:14:16 +0100 Subject: [PATCH] [fix](trx-server): pause audio capture when no clients are connected Instead of running the cpal input stream continuously, start it paused and only activate when broadcast subscribers are present. When the last client disconnects, pause the stream and sleep at 100ms intervals polling for new receivers. This eliminates idle CPU usage from continuous CoreAudio callbacks, channel allocations, and sample processing when nobody is listening. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Stanislaw Grams --- src/trx-server/src/audio.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/trx-server/src/audio.rs b/src/trx-server/src/audio.rs index caa7860..b726b70 100644 --- a/src/trx-server/src/audio.rs +++ b/src/trx-server/src/audio.rs @@ -97,13 +97,34 @@ fn run_capture( None, )?; - stream.play()?; - info!("Audio capture: started ({}Hz, {} ch, {}ms frames)", sample_rate, channels, frame_duration_ms); + // Start paused — only capture when clients are connected + info!("Audio capture: ready ({}Hz, {} ch, {}ms frames)", sample_rate, channels, frame_duration_ms); let mut pcm_buf: Vec = Vec::with_capacity(frame_samples * 2); let mut opus_buf = vec![0u8; 4096]; + let mut capturing = false; loop { + let has_receivers = tx.receiver_count() > 0; + + if has_receivers && !capturing { + let _ = stream.play(); + capturing = true; + info!("Audio capture: started"); + } else if !has_receivers && capturing { + let _ = stream.pause(); + capturing = false; + pcm_buf.clear(); + // Drain any buffered samples + while sample_rx.try_recv().is_ok() {} + info!("Audio capture: paused (no listeners)"); + } + + if !capturing { + std::thread::sleep(std::time::Duration::from_millis(100)); + continue; + } + match sample_rx.recv() { Ok(samples) => { pcm_buf.extend_from_slice(&samples);