diff --git a/routes/morse.py b/routes/morse.py index 83338c2..5491979 100644 --- a/routes/morse.py +++ b/routes/morse.py @@ -32,6 +32,23 @@ from utils.validation import ( 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 morse_active_device: int | None = None @@ -495,7 +512,7 @@ def start_morse() -> Response: target=morse_decoder_thread, kwargs={ 'rtl_stdout': rtl_process.stdout, - 'output_queue': app_module.morse_queue, + 'output_queue': _FilteredQueue(app_module.morse_queue), 'stop_event': stop_event, 'sample_rate': sample_rate, 'tone_freq': tone_freq, diff --git a/utils/morse.py b/utils/morse.py index 58c03dc..6606d18 100644 --- a/utils/morse.py +++ b/utils/morse.py @@ -433,6 +433,11 @@ class MorseDecoder: 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': self._threshold = max(0.0, self.manual_threshold) else: