openwebrx-clone/owrx/wsjt.py

80 lines
2.5 KiB
Python
Raw Normal View History

import threading
import wave
from datetime import datetime, timedelta
import time
import sched
import subprocess
import logging
logger = logging.getLogger(__name__)
class Ft8Chopper(threading.Thread):
def __init__(self, source):
self.source = source
(self.wavefilename, self.wavefile) = self.getWaveFile()
self.scheduler = sched.scheduler(time.time, time.sleep)
self.queue = []
self.doRun = True
super().__init__()
def getWaveFile(self):
filename = "/tmp/openwebrx-ft8chopper-{0}.wav".format(datetime.now().strftime("%Y%m%d-%H%M%S"))
wavefile = wave.open(filename, "wb")
wavefile.setnchannels(1)
wavefile.setsampwidth(2)
wavefile.setframerate(12000)
return (filename, wavefile)
def getNextDecodingTime(self):
t = datetime.now()
seconds = (int(t.second / 15) + 1) * 15
if seconds >= 60:
t = t + timedelta(minutes = 1)
seconds = 0
t = t.replace(second = seconds, microsecond = 0)
logger.debug("scheduling: {0}".format(t))
return t.timestamp()
def startScheduler(self):
self._scheduleNextSwitch()
threading.Thread(target = self.scheduler.run).start()
def emptyScheduler(self):
for event in self.scheduler.queue:
self.scheduler.cancel(event)
def _scheduleNextSwitch(self):
self.scheduler.enterabs(self.getNextDecodingTime(), 1, self.switchFiles)
def switchFiles(self):
file = self.wavefile
filename = self.wavefilename
(self.wavefilename, self.wavefile) = self.getWaveFile()
file.close()
self.queue.append(filename)
self._scheduleNextSwitch()
def decode(self):
if self.queue:
file = self.queue.pop()
logger.debug("processing file {0}".format(file))
#TODO expose decoding quality parameters through config
self.decoder = subprocess.Popen(["jt9", "--ft8", "-d", "3", file])
def run(self) -> None:
logger.debug("FT8 chopper starting up")
self.startScheduler()
while self.doRun:
data = self.source.read(256)
if data is None or (isinstance(data, bytes) and len(data) == 0):
logger.warning("zero read on ft8 chopper")
self.doRun = False
else:
self.wavefile.writeframes(data)
self.decode()
logger.debug("FT8 chopper shutting down")
self.emptyScheduler()