From 17c70f89e5a954384ce96e99a24c8366ba983e3d Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Sun, 1 Mar 2026 00:41:28 +0100 Subject: [PATCH] [fix](trx-backend-soapysdr): fully reset wfm decoder on tune Signed-off-by: Stan Grams --- .../trx-backend-soapysdr/src/demod.rs | 68 +++++++++++++++++++ .../trx-backend-soapysdr/src/dsp.rs | 4 +- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/demod.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/demod.rs index fed2be1..84e2c39 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/demod.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/demod.rs @@ -146,6 +146,11 @@ impl DcBlocker { self.y1 = y; y } + + pub(crate) fn reset(&mut self) { + self.x1 = 0.0; + self.y1 = 0.0; + } } /// Soft AGC with a fast-attack / slow-release envelope follower. @@ -280,6 +285,13 @@ impl BiquadBandPass { self.y1 = y; y } + + fn reset(&mut self) { + self.x1 = 0.0; + self.x2 = 0.0; + self.y1 = 0.0; + self.y2 = 0.0; + } } /// 2nd-order IIR low-pass filter (RBJ cookbook). Use [`BW4_Q1`]/[`BW4_Q2`] in @@ -323,6 +335,13 @@ impl BiquadLowPass { self.y1 = y; y } + + fn reset(&mut self) { + self.x1 = 0.0; + self.x2 = 0.0; + self.y1 = 0.0; + self.y2 = 0.0; + } } /// 2nd-order IIR notch (band-reject) filter (RBJ cookbook). @@ -365,6 +384,13 @@ impl BiquadNotch { self.y1 = y; y } + + fn reset(&mut self) { + self.x1 = 0.0; + self.x2 = 0.0; + self.y1 = 0.0; + self.y2 = 0.0; + } } impl OnePoleLowPass { @@ -381,6 +407,10 @@ impl OnePoleLowPass { self.y += self.alpha * (x - self.y); self.y } + + fn reset(&mut self) { + self.y = 0.0; + } } #[derive(Debug, Clone)] @@ -401,6 +431,10 @@ impl Deemphasis { self.y += self.alpha * (x - self.y); self.y } + + fn reset(&mut self) { + self.y = 0.0; + } } #[derive(Debug, Clone)] @@ -674,6 +708,40 @@ impl WfmStereoDecoder { self.prev_iq = None; } + pub fn reset_state(&mut self) { + self.rds_decoder.reset(); + self.rds_bpf.reset(); + self.rds_dc.reset(); + self.prev_iq = None; + self.pilot_phase = 0.0; + self.pilot_i_lp.reset(); + self.pilot_q_lp.reset(); + self.pilot_abs_lp.reset(); + self.pilot_bpf.reset(); + self.sum_lpf1.reset(); + self.sum_lpf2.reset(); + self.sum_notch.reset(); + self.diff_lpf1.reset(); + self.diff_lpf2.reset(); + self.diff_q_lpf1.reset(); + self.diff_q_lpf2.reset(); + self.diff_dc.reset(); + self.diff_q_dc.reset(); + self.dc_m.reset(); + self.dc_l.reset(); + self.dc_r.reset(); + self.deemph_m.reset(); + self.deemph_l.reset(); + self.deemph_r.reset(); + self.stereo_detect_level = 0.0; + self.stereo_detected = false; + self.sum_hist = [0.0; WFM_RESAMP_TAPS]; + self.diff_hist = [0.0; WFM_RESAMP_TAPS]; + self.diff_q_hist = [0.0; WFM_RESAMP_TAPS]; + self.prev_blend = 0.0; + self.output_phase = 0.0; + } + pub fn stereo_detected(&self) -> bool { self.stereo_detected } 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 7007c4d..47fc663 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 @@ -603,9 +603,7 @@ impl ChannelDsp { pub fn reset_wfm_state(&mut self) { if let Some(decoder) = &mut self.wfm_decoder { - decoder.reset_rds(); - decoder.reset_stereo_detect(); - decoder.reset_demod_state(); + decoder.reset_state(); } }