Field Guide · term

Also known as: adaptive smoothing, soft-error handling, amplitude smoothing

MBE adaptive smoothing is the IMBE decoder’s soft-error handling stage: using a running estimate of the channel error rate, it tames the amplitude spikes and voicing glitches that survive forward error correction on a weak signal, and mutes frames the channel has corrupted beyond rescue.1 Its defining property is restraint — on a clean channel it changes nothing at all, only advancing its trackers, so well-decoded audio is bit-identical with and without the stage.

clean → pass through cap spikes · reclaim voicing mute (er > 0.0875) error rate
The running error-rate estimate selects the response: pass-through when clean, cap and reclaim in the middle band, mute when the channel is hopeless.

The error-rate recursion

The stage keeps a single scalar, a leaky-integrator estimate of the channel error rate driven by how many bits the FEC had to correct each frame:

er = 0.95·er_prev + 0.000365·correctedBits

This is the JMBE/OP25 recursion exactly. A frame is declared hopeless and muted when er > SmoothMuteErrorRate = 0.0875; at the IMBE FEC budget (~15 correctable bits per frame) that threshold requires a sustained ~12+ corrected bits per frame — a channel so bad the audio would be unintelligible anyway. UpdateErrorRate in internal/voice/mbe/smoothing.go advances this estimate on every frame, on every code path, so the running rate is uniform regardless of what else the decoder does.

The clean-channel guarantee

Before touching any model parameter, Smooth checks a clean-frame test: if er ≤ 0.005 and the current frame’s corrected-bit count is ≤ 6, it advances only its local-energy tracker and returns, leaving the amplitudes M and the voicing decisions Vl exactly as decoded. This is the guarantee that adaptive smoothing never regresses good audio — a clean call decodes identically whether or not the stage is present, which also makes the stage safe to run unconditionally.

Scale-free thresholds

The reference decoders express their amplitude and voicing thresholds as fixed absolute constants tied to their internal amplitude scale. GopherTrunk’s linear amplitudes live on a different scale, so the two parameter-cleanup rules are expressed relative to a running local-energy estimate instead, which tracks the recent speech level:

le = 0.95·le_prev + 0.05·RM0     (floored at 1.0)

The error-rate recursion and the mute threshold, by contrast, are scale-free and match the reference exactly. Two cleanups then run, but only once the clean-frame test has failed:

  • Amplitude cap. If the frame energy RM0 spikes above 2.0 × localEnergy — a hallmark of bit-error corruption — every amplitude is scaled by sqrt(cap / RM0) to pull the frame back to a plausible level.
  • Voicing cleanup. A harmonic whose amplitude exceeds 2.0 × RMS (the per-harmonic RMS of the smoothed local energy) is almost certainly voiced, so if a corrupted voicing bit marked it unvoiced, the stage reclaims it by forcing Vl[l] = 1.

Where it sits

Adaptive smoothing runs on the decoded model parameters after spectral enhancement and before the voiced and unvoiced synthesis stages consume them. It is the counterpart to enhancement: enhancement is a perceptual polish applied to good parameters, while smoothing is damage control applied to corrupted ones. The two never fight, because smoothing is inert whenever the channel is clean.

Relevance to SDR

For a scanner working real, marginal RF, adaptive smoothing is what makes a fading P25 Phase 1 signal degrade into a muffled-but-intelligible warble and then a clean mute, rather than erupting into loud bit-error squawks. It converts the FEC’s corrected-bit count — information the decoder already has — into a graceful-degradation policy, so the listener hears the signal fade instead of the decoder failing.

Sources

  1. Multi-Band Excitation — Wikipedia, on the IMBE model parameters that adaptive smoothing cleans up. 

See also