diff --git a/sstv/decode.py b/sstv/decode.py index 3d405fd..329b3da 100644 --- a/sstv/decode.py +++ b/sstv/decode.py @@ -82,13 +82,11 @@ class SSTVDecoder(object): if header_end is None: return None + self.mode = self._decode_vis(header_end) + vis_end = header_end + round(spec.VIS_BIT_SIZE * 9 * self._sample_rate) - vis_section = self._samples[header_end:vis_end] - self.mode = self._decode_vis(vis_section) - - transmission_area = self._samples[vis_end:] - image_data = self._decode_image_data(transmission_area) + image_data = self._decode_image_data(vis_end) return self._draw_image(image_data) @@ -165,22 +163,22 @@ class SSTVDecoder(object): err=True) return None - def _decode_vis(self, vis_section): + def _decode_vis(self, vis_start): """Decodes the vis from the audio data and returns the SSTV mode""" bit_size = round(spec.VIS_BIT_SIZE * self._sample_rate) vis_bits = [] for bit_idx in range(8): - bit_offset = bit_idx * bit_size - section = vis_section[bit_offset:bit_offset+bit_size] + bit_offset = vis_start + bit_idx * bit_size + section = self._samples[bit_offset:bit_offset+bit_size] freq = self._peak_fft_freq(section) vis_bits.append(int(freq <= 1200)) - # check for even parity in last bit + # Check for even parity in last bit parity = sum(vis_bits) % 2 == 0 if not parity: - raise ValueError("error decoding VIS header (invalid parity bit)") + raise ValueError("Error decoding VIS header (invalid parity bit)") # LSB first so we must reverse and ignore the parity bit vis_value = 0 @@ -196,17 +194,17 @@ class SSTVDecoder(object): return mode - def _align_sync(self, align_section, start_of_sync=True): + def _align_sync(self, align_start, start_of_sync=True): """Returns sample where the beginning of the sync pulse was found""" # TODO - improve this sync_window = round(self.mode.SYNC_PULSE * 1.4 * self._sample_rate) - search_end = len(align_section) - sync_window + align_stop = len(self._samples) - sync_window - for current_sample in range(search_end): - align_end = current_sample + sync_window - search_section = align_section[current_sample:align_end] + for current_sample in range(align_start, align_stop): + section_end = current_sample + sync_window + search_section = self._samples[current_sample:section_end] if self._peak_fft_freq(search_section) > 1350: break @@ -218,7 +216,7 @@ class SSTVDecoder(object): else: return end_sync - def _decode_image_data(self, transmission): + def _decode_image_data(self, image_start): """Decodes image from the transmission section of an sstv signal""" window_factor = self.mode.WINDOW_FACTOR @@ -227,10 +225,10 @@ class SSTVDecoder(object): image_data = [] - seq_start = 0 + seq_start = image_start if self.mode.HAS_START_SYNC: # Start at the end of the initial sync pulse - seq_start = self._align_sync(transmission, start_of_sync=False) + seq_start = self._align_sync(image_start, start_of_sync=False) for line in range(self.mode.LINE_COUNT): image_data.append([]) @@ -251,7 +249,7 @@ class SSTVDecoder(object): self._sample_rate) # Align to start of sync pulse - seq_start += self._align_sync(transmission[seq_start:]) + seq_start = self._align_sync(seq_start) pixel_time = self.mode.PIXEL_TIME if self.mode.HAS_HALF_SCAN: @@ -267,10 +265,10 @@ class SSTVDecoder(object): chan_offset = self.mode.CHAN_OFFSETS[chan] - px_sample = round(seq_start + (chan_offset + px * - pixel_time - centre_window_time) * - self._sample_rate) - pixel_area = transmission[px_sample:px_sample+pixel_window] + px_pos = round(seq_start + (chan_offset + px * + pixel_time - centre_window_time) * + self._sample_rate) + pixel_area = self._samples[px_pos:px_pos+pixel_window] freq = self._peak_fft_freq(pixel_area) image_data[line][chan].append(calc_lum(freq))