From 60697bb26a0e0fe17202d135ee34b1d9094f8977 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Fri, 13 Mar 2026 14:18:03 +0100 Subject: [PATCH] [perf](trx-server): reduce headless scheduler audio cpu Co-authored-by: OpenAI Codex Signed-off-by: Stan Grams --- src/trx-server/src/main.rs | 6 ++++++ .../trx-backend/trx-backend-soapysdr/src/dsp.rs | 2 ++ .../trx-backend/trx-backend-soapysdr/src/dsp/channel.rs | 9 ++++++++- .../trx-backend/trx-backend-soapysdr/src/vchan_impl.rs | 7 +++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/trx-server/src/main.rs b/src/trx-server/src/main.rs index c14f88b..b5fdcfa 100644 --- a/src/trx-server/src/main.rs +++ b/src/trx-server/src/main.rs @@ -575,6 +575,12 @@ fn spawn_rig_audio_stack( loop { match sdr_rx.recv().await { Ok(frame) => { + let has_audio_clients = rx_audio_tx_sdr.receiver_count() > 0; + if !has_audio_clients { + let _ = pcm_tx_clone.send(frame); + continue; + } + let pcm_frame = match sdr_channels { 1 => frame, 2 => { diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs index 9d03b70..51bb0a4 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs @@ -155,6 +155,7 @@ impl SdrPipeline { wfm_deemphasis_us, wfm_stereo, fir_taps, + channel_idx == 0, channel_squelch_cfg, pcm_tx.clone(), iq_tx.clone(), @@ -233,6 +234,7 @@ impl SdrPipeline { self.wfm_deemphasis_us, self.wfm_stereo, fir_taps.max(1), + false, VirtualSquelchConfig::default(), pcm_tx.clone(), iq_tx.clone(), diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp/channel.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp/channel.rs index a084786..2722561 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp/channel.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp/channel.rs @@ -169,6 +169,7 @@ pub struct ChannelDsp { audio_agc: SoftAgc, audio_dc: Option, processing_enabled: bool, + force_mono_pcm: bool, squelch: VirtualSquelch, } @@ -269,6 +270,7 @@ impl ChannelDsp { wfm_deemphasis_us: u32, wfm_stereo: bool, fir_taps: usize, + force_mono_pcm: bool, squelch_cfg: VirtualSquelchConfig, pcm_tx: broadcast::Sender>, iq_tx: broadcast::Sender>>, @@ -348,6 +350,7 @@ impl ChannelDsp { audio_agc: agc_for_mode(mode, audio_sample_rate), audio_dc: dc_for_mode(mode), processing_enabled: true, + force_mono_pcm, squelch: VirtualSquelch::new(squelch_cfg), } } @@ -356,6 +359,10 @@ impl ChannelDsp { self.processing_enabled = enabled; } + pub fn set_force_mono_pcm(&mut self, enabled: bool) { + self.force_mono_pcm = enabled; + } + pub fn set_squelch(&mut self, enabled: bool, threshold_db: f32) { self.squelch.set_enabled(enabled); self.squelch.set_threshold_db(threshold_db); @@ -548,7 +555,7 @@ impl ChannelDsp { } *sample = self.audio_agc.process(*sample); } - if self.output_channels >= 2 { + if self.output_channels >= 2 && !self.force_mono_pcm { let mut stereo = Vec::with_capacity(raw.len() * self.output_channels); for sample in raw { stereo.push(sample); diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs index fa16208..daa4f53 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs @@ -203,6 +203,13 @@ impl SdrVirtualChannelManager { hidden, }); + if hidden { + let dsps = self.pipeline.channel_dsps.read().unwrap(); + if let Some(dsp_arc) = dsps.get(pipeline_slot) { + dsp_arc.lock().unwrap().set_force_mono_pcm(true); + } + } + Ok(pcm_rx) }