From 91562b2a4bb5886b01d20d67c6d59c58f9e7b95f Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Fri, 6 Mar 2026 21:30:58 +0100 Subject: [PATCH] [fix](trx-cw): fix window size, dot/dash threshold, and cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reduce analysis window from 50ms to 10ms so the decoder can detect dits at 25+ WPM (at 25 WPM a dit is 48ms, shorter than the old window) - Fix dot/dash classification threshold from 2.0× to 1.5× unit_ms; ITU Morse dah = 3× dit, so the midpoint boundary is 1.5× - Replace O(n) on_durations.remove(0) with drain() to trim the window - Remove pointless emit_text() wrapper; callers now call emit_event() directly Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Stan Grams --- src/decoders/trx-cw/src/lib.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/decoders/trx-cw/src/lib.rs b/src/decoders/trx-cw/src/lib.rs index 1db7e1f..5b40818 100644 --- a/src/decoders/trx-cw/src/lib.rs +++ b/src/decoders/trx-cw/src/lib.rs @@ -153,7 +153,7 @@ pub struct CwDecoder { impl CwDecoder { pub fn new(sample_rate: u32) -> Self { - let window_ms = 50; + let window_ms = 10; let window_size = (sample_rate as usize * window_ms) / 1000; let default_tone = 700u32; let k = (default_tone as f32 * window_size as f32 / sample_rate as f32).round(); @@ -347,15 +347,15 @@ impl CwDecoder { // Word gap if !self.current_symbol.is_empty() { let ch = morse_lookup(&self.current_symbol).unwrap_or('?'); - self.emit_text(&ch.to_string()); + self.emit_event(&ch.to_string()); self.current_symbol.clear(); } - self.emit_text(" "); + self.emit_event(" "); } else if off_duration > u * 2.0 { // Character gap if !self.current_symbol.is_empty() { let ch = morse_lookup(&self.current_symbol).unwrap_or('?'); - self.emit_text(&ch.to_string()); + self.emit_event(&ch.to_string()); self.current_symbol.clear(); } } @@ -367,7 +367,7 @@ impl CwDecoder { self.tone_on = false; let on_duration = now - self.tone_on_at; let u = self.unit_ms(); - if on_duration > u * 2.0 { + if on_duration > u * 1.5 { self.current_symbol.push('-'); } else { self.current_symbol.push('.'); @@ -378,7 +378,7 @@ impl CwDecoder { // Collect for auto WPM self.on_durations.push(on_duration); if self.on_durations.len() > 30 { - self.on_durations.remove(0); + self.on_durations.drain(..self.on_durations.len() - 30); } self.auto_detect_wpm(); } @@ -391,7 +391,7 @@ impl CwDecoder { let silence = now - self.tone_off_at; if silence > self.unit_ms() * 5.0 { let ch = morse_lookup(&self.current_symbol).unwrap_or('?'); - self.emit_text(&ch.to_string()); + self.emit_event(&ch.to_string()); self.current_symbol.clear(); } } @@ -406,10 +406,6 @@ impl CwDecoder { }); } - fn emit_text(&mut self, text: &str) { - self.emit_event(text); - } - pub fn process_samples(&mut self, samples: &[f32]) -> Vec { for &s in samples { self.sample_buf[self.sample_idx] = s;