mirror of
https://github.com/smittix/intercept.git
synced 2026-07-31 11:53:05 -07:00
morse: fix SNR threshold for real CW and stop timeout
Widen noise detector offset from ±100Hz to ±200Hz to reduce spectral leakage into the noise reference, and scale threshold_multiplier for SNR space (2.8 → 1.54) so real CW signals reliably trigger tone detection instead of producing all-E's at 60 WPM. Fix misleading "decoder startup" timeout message on stop requests and increase stop timeout from 2.2s to 5s. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ var MorseMode = (function () {
|
|||||||
|
|
||||||
var SETTINGS_KEY = 'intercept.morse.settings.v3';
|
var SETTINGS_KEY = 'intercept.morse.settings.v3';
|
||||||
var STATUS_POLL_MS = 5000;
|
var STATUS_POLL_MS = 5000;
|
||||||
var LOCAL_STOP_TIMEOUT_MS = 2200;
|
var LOCAL_STOP_TIMEOUT_MS = 5000;
|
||||||
var START_TIMEOUT_MS = 60000;
|
var START_TIMEOUT_MS = 60000;
|
||||||
|
|
||||||
var state = {
|
var state = {
|
||||||
@@ -87,7 +87,7 @@ var MorseMode = (function () {
|
|||||||
});
|
});
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
if (err && err.name === 'AbortError') {
|
if (err && err.name === 'AbortError') {
|
||||||
throw new Error('Request timed out while waiting for decoder startup');
|
throw new Error('Request timed out');
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}).finally(function () {
|
}).finally(function () {
|
||||||
|
|||||||
+6
-5
@@ -165,12 +165,12 @@ class MorseDecoder:
|
|||||||
|
|
||||||
self._detector = GoertzelFilter(self._active_tone_freq, self.sample_rate, self._block_size)
|
self._detector = GoertzelFilter(self._active_tone_freq, self.sample_rate, self._block_size)
|
||||||
self._noise_detector_low = GoertzelFilter(
|
self._noise_detector_low = GoertzelFilter(
|
||||||
_clamp(self._active_tone_freq - max(60.0, self.bandwidth_hz * 0.5), 150.0, 2000.0),
|
_clamp(self._active_tone_freq - max(150.0, self.bandwidth_hz), 150.0, 2000.0),
|
||||||
self.sample_rate,
|
self.sample_rate,
|
||||||
self._block_size,
|
self._block_size,
|
||||||
)
|
)
|
||||||
self._noise_detector_high = GoertzelFilter(
|
self._noise_detector_high = GoertzelFilter(
|
||||||
_clamp(self._active_tone_freq + max(60.0, self.bandwidth_hz * 0.5), 150.0, 2000.0),
|
_clamp(self._active_tone_freq + max(150.0, self.bandwidth_hz), 150.0, 2000.0),
|
||||||
self.sample_rate,
|
self.sample_rate,
|
||||||
self._block_size,
|
self._block_size,
|
||||||
)
|
)
|
||||||
@@ -249,7 +249,7 @@ class MorseDecoder:
|
|||||||
def _rebuild_detectors(self) -> None:
|
def _rebuild_detectors(self) -> None:
|
||||||
"""Rebuild target/noise Goertzel filters after tone updates."""
|
"""Rebuild target/noise Goertzel filters after tone updates."""
|
||||||
self._detector = GoertzelFilter(self._active_tone_freq, self.sample_rate, self._block_size)
|
self._detector = GoertzelFilter(self._active_tone_freq, self.sample_rate, self._block_size)
|
||||||
ref_offset = max(60.0, self.bandwidth_hz * 0.5)
|
ref_offset = max(150.0, self.bandwidth_hz)
|
||||||
self._noise_detector_low = GoertzelFilter(
|
self._noise_detector_low = GoertzelFilter(
|
||||||
_clamp(self._active_tone_freq - ref_offset, 150.0, 2000.0),
|
_clamp(self._active_tone_freq - ref_offset, 150.0, 2000.0),
|
||||||
self.sample_rate,
|
self.sample_rate,
|
||||||
@@ -457,8 +457,9 @@ class MorseDecoder:
|
|||||||
# gain-invariant — fixes stuck-ON tone when AGC amplifies
|
# gain-invariant — fixes stuck-ON tone when AGC amplifies
|
||||||
# inter-element silence above the raw magnitude threshold.
|
# inter-element silence above the raw magnitude threshold.
|
||||||
snr = level / max(noise_ref, 1e-6)
|
snr = level / max(noise_ref, 1e-6)
|
||||||
snr_on = self.threshold_multiplier * (1.0 + self._hysteresis)
|
snr_mult = max(1.3, self.threshold_multiplier * 0.55)
|
||||||
snr_off = self.threshold_multiplier * (1.0 - self._hysteresis)
|
snr_on = snr_mult * (1.0 + self._hysteresis)
|
||||||
|
snr_off = snr_mult * (1.0 - self._hysteresis)
|
||||||
|
|
||||||
if self._tone_on:
|
if self._tone_on:
|
||||||
tone_detected = gate_ok and snr >= snr_off
|
tone_detected = gate_ok and snr >= snr_off
|
||||||
|
|||||||
Reference in New Issue
Block a user