mirror of
https://github.com/smittix/intercept.git
synced 2026-06-03 03:33:37 -07:00
morse: fix startup race and stuck noise floor in Goertzel decoder
Filter decoder-thread 'stopped' status events that race with the route lifecycle, causing the frontend to drop back to idle on first start. Pull noise floor upward using adjacent-frequency Goertzel reference when warmup calibration runs before AGC converges, preventing permanent tone-on with zero character decodes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -32,6 +32,23 @@ from utils.validation import (
|
|||||||
|
|
||||||
morse_bp = Blueprint('morse', __name__)
|
morse_bp = Blueprint('morse', __name__)
|
||||||
|
|
||||||
|
|
||||||
|
class _FilteredQueue:
|
||||||
|
"""Suppress decoder-thread 'stopped' events that race with route lifecycle."""
|
||||||
|
|
||||||
|
def __init__(self, inner: queue.Queue) -> None:
|
||||||
|
self._inner = inner
|
||||||
|
|
||||||
|
def put_nowait(self, item: Any) -> None:
|
||||||
|
if isinstance(item, dict) and item.get('type') == 'status' and item.get('status') == 'stopped':
|
||||||
|
return
|
||||||
|
self._inner.put_nowait(item)
|
||||||
|
|
||||||
|
def put(self, item: Any, **kwargs: Any) -> None:
|
||||||
|
if isinstance(item, dict) and item.get('type') == 'status' and item.get('status') == 'stopped':
|
||||||
|
return
|
||||||
|
self._inner.put(item, **kwargs)
|
||||||
|
|
||||||
# Track which device is being used
|
# Track which device is being used
|
||||||
morse_active_device: int | None = None
|
morse_active_device: int | None = None
|
||||||
|
|
||||||
@@ -495,7 +512,7 @@ def start_morse() -> Response:
|
|||||||
target=morse_decoder_thread,
|
target=morse_decoder_thread,
|
||||||
kwargs={
|
kwargs={
|
||||||
'rtl_stdout': rtl_process.stdout,
|
'rtl_stdout': rtl_process.stdout,
|
||||||
'output_queue': app_module.morse_queue,
|
'output_queue': _FilteredQueue(app_module.morse_queue),
|
||||||
'stop_event': stop_event,
|
'stop_event': stop_event,
|
||||||
'sample_rate': sample_rate,
|
'sample_rate': sample_rate,
|
||||||
'tone_freq': tone_freq,
|
'tone_freq': tone_freq,
|
||||||
|
|||||||
@@ -433,6 +433,11 @@ class MorseDecoder:
|
|||||||
|
|
||||||
self._signal_peak = max(self._signal_peak, self._noise_floor * 1.05)
|
self._signal_peak = max(self._signal_peak, self._noise_floor * 1.05)
|
||||||
|
|
||||||
|
# Prevent noise floor from staying stuck below actual ambient noise
|
||||||
|
# (occurs when warmup calibration runs before AGC converges)
|
||||||
|
if noise_ref > self._noise_floor * 1.5:
|
||||||
|
self._noise_floor += settle_alpha * 0.5 * (noise_ref - self._noise_floor)
|
||||||
|
|
||||||
if self.threshold_mode == 'manual':
|
if self.threshold_mode == 'manual':
|
||||||
self._threshold = max(0.0, self.manual_threshold)
|
self._threshold = max(0.0, self.manual_threshold)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user