From 5dcc117e61834fa2ca80b56cd9b86e9eb0408512 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Thu, 5 Mar 2026 22:01:21 +0100 Subject: [PATCH] [fix](trx-backend-soapysdr): disable hidden AIS DSP outside AIS modes Add per-channel processing gating and disable hidden AIS channel DSP unless mode is AIS or MARINE, reducing continuous IQ read-loop CPU load in normal operation.\n\nCo-authored-by: OpenAI Codex Signed-off-by: Stan Grams --- .../trx-backend-soapysdr/src/dsp/channel.rs | 9 +++++++++ .../trx-backend-soapysdr/src/lib.rs | 19 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) 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 38d6528..2680d27 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 @@ -86,6 +86,7 @@ pub struct ChannelDsp { iq_agc: Option, audio_agc: SoftAgc, audio_dc: Option, + processing_enabled: bool, } impl ChannelDsp { @@ -262,9 +263,14 @@ impl ChannelDsp { iq_agc: iq_agc_for_mode(mode, channel_sample_rate), audio_agc: agc_for_mode(mode, audio_sample_rate), audio_dc: dc_for_mode(mode), + processing_enabled: true, } } + pub fn set_processing_enabled(&mut self, enabled: bool) { + self.processing_enabled = enabled; + } + pub fn set_mode(&mut self, mode: &RigMode) { self.mode = mode.clone(); if *mode != RigMode::WFM { @@ -325,6 +331,9 @@ impl ChannelDsp { } pub fn process_block(&mut self, block: &[Complex]) { + if !self.processing_enabled { + return; + } let n = block.len(); if n == 0 { return; diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs index fef322a..20638cf 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs @@ -227,7 +227,7 @@ impl SoapySdrRig { let spectrum_buf = pipeline.spectrum_buf.clone(); let retune_cmd = pipeline.retune_cmd.clone(); - Ok(Self { + let rig = Self { info, freq: initial_freq, mode: initial_mode, @@ -245,7 +245,9 @@ impl SoapySdrRig { gain_db, max_gain_db, ais_channel_indices: Some((primary_channel_count, primary_channel_count + 1)), - }) + }; + rig.apply_ais_channel_activity(); + Ok(rig) } /// Simple constructor for backward compatibility with the factory function. @@ -300,6 +302,18 @@ impl SoapySdrRig { } } + fn apply_ais_channel_activity(&self) { + let Some((ais_a_idx, ais_b_idx)) = self.ais_channel_indices else { + return; + }; + let enabled = matches!(self.mode, RigMode::AIS | RigMode::MARINE); + for idx in [ais_a_idx, ais_b_idx] { + if let Some(dsp_arc) = self.pipeline.channel_dsps.get(idx) { + dsp_arc.lock().unwrap().set_processing_enabled(enabled); + } + } + } + pub fn subscribe_iq_channel( &self, channel_idx: usize, @@ -435,6 +449,7 @@ impl RigCat for SoapySdrRig { dsp.set_mode(&mode); dsp.set_filter(self.bandwidth_hz, self.fir_taps as usize); } + self.apply_ais_channel_activity(); self.apply_ais_channel_filters(); Ok(()) })