[fix](trx-wefax): discard short images from false auto-start

The variance-based auto-start in Idle state is permissive and fires on
any sustained modulated audio — tones, beeps, noise bursts. When that
happens mid-transmission, the decoder enters Receiving, the correlation
watchdog trips after exactly 31 lines (1 seed + 30 low-correlation),
and we end up saving a sliver of garbage to disk and the history.

Gate finalize_image() on a 100-line minimum. A real WEFAX chart is
hundreds of lines; anything shorter is almost certainly a false
auto-start and gets dropped silently (with a debug log). This doesn't
change start-tone / phasing-driven captures, only filters out the
noise-triggered entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-04-04 19:46:50 +02:00
parent 84e50789d2
commit b12112d035
+18 -1
View File
@@ -43,6 +43,12 @@ const LINE_CORR_NOISE_THRESHOLD: f32 = 0.2;
/// fldigi's line-to-line correlation check for automatic stop.
const LINE_CORR_NOISE_LINES: u32 = 30;
/// Minimum image height (lines) to save. Anything shorter is assumed to be a
/// false-positive auto-start (variance detector tripping on tones, noise
/// bursts, or phasing leakage) and discarded silently. A real WEFAX chart is
/// at least several hundred lines long.
const MIN_IMAGE_LINES: u32 = 100;
/// WEFAX decoder output event.
#[derive(Debug)]
pub enum WefaxEvent {
@@ -453,7 +459,18 @@ impl WefaxDecoder {
let mut events = Vec::new();
if let Some(ref image) = self.image {
if image.line_count() == 0 {
let lines = image.line_count();
if lines == 0 {
return events;
}
if lines < MIN_IMAGE_LINES {
debug!(
lines,
min = MIN_IMAGE_LINES,
"WEFAX: discarding short image (likely false auto-start)"
);
self.image = None;
self.reception_start_ms = None;
return events;
}