Formatting fixes
parent
ac8cbd47b9
commit
e7999be191
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
"""Imports used when importing 'sstv'"""
|
||||||
|
|
||||||
from .command import SSTVCommand
|
from .command import SSTVCommand
|
||||||
from .decode import SSTVDecoder
|
from .decode import SSTVDecoder
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
"""Main entry point for command line program"""
|
||||||
|
|
||||||
import sstv
|
import sstv
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!usr/bin/env python
|
"""Parsing arguments and starting program from command line"""
|
||||||
|
|
||||||
from sys import exit
|
|
||||||
from .decode import SSTVDecoder
|
from .decode import SSTVDecoder
|
||||||
|
from sys import exit
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!usr/bin/env python
|
"""Shared methods"""
|
||||||
|
|
||||||
from sys import stderr, stdout
|
|
||||||
from os import get_terminal_size
|
from os import get_terminal_size
|
||||||
|
from sys import stderr, stdout
|
||||||
|
|
||||||
|
|
||||||
def log_message(message="", show=True, err=False, recur=False, prefix=True):
|
def log_message(message="", show=True, err=False, recur=False, prefix=True):
|
||||||
|
|
|
@ -1,23 +1,18 @@
|
||||||
#!usr/bin/env python
|
"""Class and methods to decode SSTV signal"""
|
||||||
|
|
||||||
from . import spec
|
from . import spec
|
||||||
from .common import log_message, progress_bar
|
from .common import log_message, progress_bar
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from scipy.signal.windows import hann
|
from scipy.signal.windows import hann
|
||||||
import soundfile
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import soundfile
|
||||||
|
|
||||||
|
|
||||||
class SSTVDecoder(object):
|
class SSTVDecoder(object):
|
||||||
|
|
||||||
|
"""Create an SSTV decoder for decoding audio data"""
|
||||||
|
|
||||||
def __init__(self, audio_file):
|
def __init__(self, audio_file):
|
||||||
"""
|
|
||||||
Initialise SSTV decoder
|
|
||||||
|
|
||||||
audio_data - Can be a path to an audio file OR a tuple containing
|
|
||||||
samples and the sampling rate of audio data
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.log_basic = True
|
self.log_basic = True
|
||||||
self.mode = None
|
self.mode = None
|
||||||
|
|
||||||
|
@ -38,12 +33,14 @@ class SSTVDecoder(object):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def decode(self, skip=0):
|
def decode(self, skip=0):
|
||||||
"""
|
"""Attempts to decode the audio data as an SSTV signal
|
||||||
Attempts to decode the audio data as an SSTV signal
|
|
||||||
|
|
||||||
Returns a PIL image on success, and None on error
|
Returns a PIL image on success, and None on error
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if skip > 0:
|
||||||
|
self._samples = self._samples[skip:]
|
||||||
|
|
||||||
header_start = self._find_header()
|
header_start = self._find_header()
|
||||||
|
|
||||||
if header_start is None:
|
if header_start is None:
|
||||||
|
@ -64,11 +61,12 @@ class SSTVDecoder(object):
|
||||||
return self._draw_image(image_data)
|
return self._draw_image(image_data)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
""" Closes any input files if they exist """
|
"""Closes any input files if they exist"""
|
||||||
if self._audio_file is not None and not self._audio_file.closed:
|
if self._audio_file is not None and not self._audio_file.closed:
|
||||||
self._audio_file.close()
|
self._audio_file.close()
|
||||||
|
|
||||||
def _barycentric_peak_interp(bins, x):
|
def _barycentric_peak_interp(bins, x):
|
||||||
|
"""Interpolate between frequency bins to find x value of peak"""
|
||||||
# Takes x as the index of the largest bin and interpolates the
|
# Takes x as the index of the largest bin and interpolates the
|
||||||
# x value of the peak using neighbours in the bins array
|
# x value of the peak using neighbours in the bins array
|
||||||
|
|
||||||
|
@ -90,7 +88,7 @@ class SSTVDecoder(object):
|
||||||
return (y3 - y1) / denom + x
|
return (y3 - y1) / denom + x
|
||||||
|
|
||||||
def _peak_fft_freq(self, data):
|
def _peak_fft_freq(self, data):
|
||||||
# Finds the peak frequency from a section of audio data
|
"""Finds the peak frequency from a section of audio data"""
|
||||||
|
|
||||||
windowed_data = data * hann(len(data))
|
windowed_data = data * hann(len(data))
|
||||||
fft = np.abs(np.fft.rfft(windowed_data))
|
fft = np.abs(np.fft.rfft(windowed_data))
|
||||||
|
@ -104,7 +102,7 @@ class SSTVDecoder(object):
|
||||||
return peak * self._sample_rate / len(windowed_data)
|
return peak * self._sample_rate / len(windowed_data)
|
||||||
|
|
||||||
def _find_header(self):
|
def _find_header(self):
|
||||||
# Finds the approx sample of the calibration header
|
"""Finds the approx sample of the calibration header"""
|
||||||
|
|
||||||
break_sample = round(spec.BREAK_OFFSET * self._sample_rate)
|
break_sample = round(spec.BREAK_OFFSET * self._sample_rate)
|
||||||
leader_sample = round(spec.LEADER_OFFSET * self._sample_rate)
|
leader_sample = round(spec.LEADER_OFFSET * self._sample_rate)
|
||||||
|
@ -144,7 +142,7 @@ class SSTVDecoder(object):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _decode_vis(self, vis_section):
|
def _decode_vis(self, vis_section):
|
||||||
# Decodes the vis value from the audio data and returns the SSTV mode
|
"""Decodes the vis from the audio data and returns the SSTV mode"""
|
||||||
bit_size = round(spec.VIS_BIT_SIZE * self._sample_rate)
|
bit_size = round(spec.VIS_BIT_SIZE * self._sample_rate)
|
||||||
vis_bits = []
|
vis_bits = []
|
||||||
|
|
||||||
|
@ -175,7 +173,7 @@ class SSTVDecoder(object):
|
||||||
return mode
|
return mode
|
||||||
|
|
||||||
def _calc_lum(freq):
|
def _calc_lum(freq):
|
||||||
# Converts SSTV pixel frequency range into 0-255 luminance byte
|
"""Converts SSTV pixel frequency range into 0-255 luminance byte"""
|
||||||
lum = int(round((freq - 1500) / 3.1372549))
|
lum = int(round((freq - 1500) / 3.1372549))
|
||||||
if lum > 255:
|
if lum > 255:
|
||||||
return 255
|
return 255
|
||||||
|
@ -185,7 +183,7 @@ class SSTVDecoder(object):
|
||||||
return lum
|
return lum
|
||||||
|
|
||||||
def _align_sync(self, align_section, start_of_sync=True):
|
def _align_sync(self, align_section, start_of_sync=True):
|
||||||
# Returns sample where the beginning of the sync pulse was found
|
"""Returns sample where the beginning of the sync pulse was found"""
|
||||||
sync_window = round(self.mode.SYNC_PULSE * 1.4 * self._sample_rate)
|
sync_window = round(self.mode.SYNC_PULSE * 1.4 * self._sample_rate)
|
||||||
search_end = len(align_section) - sync_window
|
search_end = len(align_section) - sync_window
|
||||||
|
|
||||||
|
@ -205,7 +203,7 @@ class SSTVDecoder(object):
|
||||||
return end_sync
|
return end_sync
|
||||||
|
|
||||||
def _decode_image_data(self, transmission):
|
def _decode_image_data(self, transmission):
|
||||||
# Decodes image data from the transmission section of an sstv signal
|
"""Decodes image from the transmission section of an sstv signal"""
|
||||||
|
|
||||||
window_factor = self.mode.WINDOW_FACTOR
|
window_factor = self.mode.WINDOW_FACTOR
|
||||||
|
|
||||||
|
@ -269,7 +267,7 @@ class SSTVDecoder(object):
|
||||||
return image_data
|
return image_data
|
||||||
|
|
||||||
def _draw_image(self, image_data):
|
def _draw_image(self, image_data):
|
||||||
# Renders the image from the decoded sstv signal
|
"""Renders the image from the decoded sstv signal"""
|
||||||
|
|
||||||
if self.mode.COLOR == spec.COL_FMT.YUV:
|
if self.mode.COLOR == spec.COL_FMT.YUV:
|
||||||
col_mode = "YCbCr"
|
col_mode = "YCbCr"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!usr/bin/env python
|
"""Constants for SSTV specification and each supported mode"""
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue