mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 14:50:00 -07:00
fix: Preserve image-start samples across VIS-to-decoder boundary
VISDetector._process_window() was calling self.reset() inside the STOP_BIT handler, wiping self._buffer before feed() could advance past the triggering window. All audio samples buffered after the VIS STOP_BIT (the start of the first scan line) were silently discarded, causing the image decoder to begin decoding mid-stream with no alignment reference. The result was every scan line being desynchronised from the first, producing the diagonal stripes and scrambled colours seen in decoded images. Fix: remove the premature reset() from _process_window(). The STOP_BIT handler now sets state=DETECTED and returns the result. A new remaining_buffer property exposes the post-VIS samples. _decode_audio_stream() and decode_file() capture those samples before calling reset(), then immediately feed them into the newly created SSTVImageDecoder so decoding begins from sample 0 of the first sync pulse. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -464,7 +464,13 @@ class SSTVDecoder:
|
||||
result = vis_detector.feed(samples)
|
||||
if result is not None:
|
||||
vis_code, mode_name = result
|
||||
logger.info(f"VIS detected: code={vis_code}, mode={mode_name}")
|
||||
# Capture samples that arrived after the VIS STOP_BIT —
|
||||
# these are the start of the image and must be fed into
|
||||
# the image decoder before the next chunk arrives.
|
||||
remaining = vis_detector.remaining_buffer.copy()
|
||||
vis_detector.reset()
|
||||
logger.info(f"VIS detected: code={vis_code}, mode={mode_name}, "
|
||||
f"{len(remaining)} image-start samples retained")
|
||||
|
||||
mode_spec = get_mode(vis_code)
|
||||
if mode_spec:
|
||||
@@ -473,6 +479,8 @@ class SSTVDecoder:
|
||||
mode_spec,
|
||||
sample_rate=SAMPLE_RATE,
|
||||
)
|
||||
if len(remaining) > 0:
|
||||
image_decoder.feed(remaining)
|
||||
self._emit_progress(DecodeProgress(
|
||||
status='decoding',
|
||||
mode=mode_name,
|
||||
@@ -481,7 +489,6 @@ class SSTVDecoder:
|
||||
))
|
||||
else:
|
||||
logger.warning(f"No mode spec for VIS code {vis_code}")
|
||||
vis_detector.reset()
|
||||
|
||||
# Emit signal level metrics every ~500ms (every 5th 100ms chunk)
|
||||
scope_tone: str | None = None
|
||||
@@ -853,6 +860,8 @@ class SSTVDecoder:
|
||||
result = vis_detector.feed(chunk)
|
||||
if result is not None:
|
||||
vis_code, mode_name = result
|
||||
remaining = vis_detector.remaining_buffer.copy()
|
||||
vis_detector.reset()
|
||||
logger.info(f"VIS detected in file: code={vis_code}, mode={mode_name}")
|
||||
|
||||
mode_spec = get_mode(vis_code)
|
||||
@@ -862,8 +871,8 @@ class SSTVDecoder:
|
||||
mode_spec,
|
||||
sample_rate=SAMPLE_RATE,
|
||||
)
|
||||
else:
|
||||
vis_detector.reset()
|
||||
if len(remaining) > 0:
|
||||
image_decoder.feed(remaining)
|
||||
|
||||
except wave.Error as e:
|
||||
logger.error(f"Error reading WAV file: {e}")
|
||||
|
||||
Reference in New Issue
Block a user