[fix](trx-backend-soapysdr): add wfm limiter and restore cutoffs

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-01 00:02:19 +01:00
parent b6f0a9967d
commit 5060522541
2 changed files with 8 additions and 4 deletions
@@ -11,13 +11,14 @@ const RDS_BPF_Q: f32 = 10.0;
/// Pilot tone frequency (Hz).
const PILOT_HZ: f32 = 19_000.0;
/// Audio bandwidth for WFM (Hz).
/// 17 kHz preserves more top-end while still leaving guard band below the
/// 19 kHz pilot.
const AUDIO_BW_HZ: f32 = 17_000.0;
/// 15.8 kHz leaves more guard band below the 19 kHz pilot and reduces
/// top-end artifacts on strong signals while still preserving the useful
/// broadcast audio range.
const AUDIO_BW_HZ: f32 = 15_800.0;
/// Stereo L-R subchannel bandwidth for WFM (Hz).
/// Keep this a bit lower than the mono path because the recovered difference
/// signal is noisier and more prone to high-frequency artifacts.
const STEREO_DIFF_BW_HZ: f32 = 15_800.0;
const STEREO_DIFF_BW_HZ: f32 = 14_500.0;
/// Q values for a proper 4th-order Butterworth cascade (two 2nd-order stages).
/// Stage 1: Q = 1 / (2 cos(π/8))
const BW4_Q1: f32 = 0.5412;
@@ -267,12 +267,15 @@ impl BlockFirFilter {
/// 500 ms / 5 s only reacts to slow carrier-amplitude fading, not audio.
///
/// CW uses a fast attack/release to follow individual dots and dashes.
/// WFM uses a linked downward-only peak limiter (max gain = 1.0) so louder
/// stations are tamed without boosting quieter ones.
/// All other modes use 5 ms / 500 ms, suitable for SSB voice and FM.
fn agc_for_mode(mode: &RigMode, audio_sample_rate: u32) -> SoftAgc {
let sr = audio_sample_rate.max(1) as f32;
match mode {
RigMode::CW | RigMode::CWR => SoftAgc::new(sr, 1.0, 50.0, 0.5, 30.0),
RigMode::AM => SoftAgc::new(sr, 500.0, 5_000.0, 0.5, 30.0),
RigMode::WFM => SoftAgc::new(sr, 0.2, 80.0, 0.92, 0.0),
_ => SoftAgc::new(sr, 5.0, 500.0, 0.5, 30.0),
}
}