[fix](trx-backend-soapysdr): correct WFM S-meter IIR block-rate scaling

The per-sample attack/decay alphas from smeter_alphas() were applied
once per decimated block (~200 samples), inflating effective time
constants by ~200x and causing a sluggish "pumping" meter.  Correct
with α_block = 1 − (1 − α)^N to preserve the intended IARU R.1
time constants (~2 ms attack, ~300 ms decay).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-04-19 23:10:43 +02:00
parent f9cf95705a
commit f57292a65d
@@ -798,11 +798,18 @@ impl ChannelDsp {
// Asymmetric attack/decay: use the faster coefficient when // Asymmetric attack/decay: use the faster coefficient when
// the new measurement is above the current estimate (attack), // the new measurement is above the current estimate (attack),
// and the slower coefficient when below (decay). // and the slower coefficient when below (decay).
let alpha = if mean_power > self.carrier_iq_power { //
// The per-sample alphas from smeter_alphas() assume sample-by-
// sample IIR updates, but we apply the IIR once per decimated
// block. Correct via α_block = 1 (1 α)^N so the
// effective time constants stay at ~2 ms / ~300 ms regardless
// of block size.
let per_sample = if mean_power > self.carrier_iq_power {
self.carrier_attack_alpha self.carrier_attack_alpha
} else { } else {
self.carrier_decay_alpha self.carrier_decay_alpha
}; };
let alpha = 1.0 - (1.0 - per_sample).powf(n);
self.carrier_iq_power += alpha * (mean_power - self.carrier_iq_power); self.carrier_iq_power += alpha * (mean_power - self.carrier_iq_power);
self.last_signal_db = self.last_signal_db =