add MSK144 parsing
This commit is contained in:
parent
525b70d495
commit
afcd8277d1
@ -1,5 +1,5 @@
|
|||||||
from csdr.chain.demodulator import ServiceDemodulator, SecondaryDemodulator, DialFrequencyReceiver, SecondarySelectorChain
|
from csdr.chain.demodulator import ServiceDemodulator, SecondaryDemodulator, DialFrequencyReceiver, SecondarySelectorChain
|
||||||
from csdr.module.msk144 import Msk144Module
|
from csdr.module.msk144 import Msk144Module, ParserAdapter
|
||||||
from owrx.audio.chopper import AudioChopper, AudioChopperParser
|
from owrx.audio.chopper import AudioChopper, AudioChopperParser
|
||||||
from owrx.aprs.kiss import KissDeframer
|
from owrx.aprs.kiss import KissDeframer
|
||||||
from owrx.aprs import Ax25Parser, AprsParser
|
from owrx.aprs import Ax25Parser, AprsParser
|
||||||
@ -21,17 +21,22 @@ class AudioChopperDemodulator(ServiceDemodulator, DialFrequencyReceiver):
|
|||||||
self.chopper.setDialFrequency(frequency)
|
self.chopper.setDialFrequency(frequency)
|
||||||
|
|
||||||
|
|
||||||
class Msk144Demodulator(ServiceDemodulator):
|
class Msk144Demodulator(ServiceDemodulator, DialFrequencyReceiver):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.parser = ParserAdapter()
|
||||||
workers = [
|
workers = [
|
||||||
Convert(Format.FLOAT, Format.SHORT),
|
Convert(Format.FLOAT, Format.SHORT),
|
||||||
Msk144Module(),
|
Msk144Module(),
|
||||||
|
self.parser,
|
||||||
]
|
]
|
||||||
super().__init__(workers)
|
super().__init__(workers)
|
||||||
|
|
||||||
def getFixedAudioRate(self) -> int:
|
def getFixedAudioRate(self) -> int:
|
||||||
return 12000
|
return 12000
|
||||||
|
|
||||||
|
def setDialFrequency(self, frequency: int) -> None:
|
||||||
|
self.parser.setDialFrequency(frequency)
|
||||||
|
|
||||||
|
|
||||||
class PacketDemodulator(ServiceDemodulator, DialFrequencyReceiver):
|
class PacketDemodulator(ServiceDemodulator, DialFrequencyReceiver):
|
||||||
def __init__(self, service: bool = False):
|
def __init__(self, service: bool = False):
|
||||||
|
@ -126,7 +126,7 @@ class PopenModule(AutoStartModule, metaclass=ABCMeta):
|
|||||||
# resume in case the reader has been stop()ed before
|
# resume in case the reader has been stop()ed before
|
||||||
self.reader.resume()
|
self.reader.resume()
|
||||||
Thread(target=self.pump(self.reader.read, self.process.stdin.write)).start()
|
Thread(target=self.pump(self.reader.read, self.process.stdin.write)).start()
|
||||||
Thread(target=self.pump(partial(self.process.stdout.read, 1024), self.writer.write)).start()
|
Thread(target=self.pump(partial(self.process.stdout.read1, 1024), self.writer.write)).start()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self.process is not None:
|
if self.process is not None:
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
from pycsdr.types import Format
|
from pycsdr.types import Format
|
||||||
from csdr.module import PopenModule
|
from csdr.module import PopenModule, ThreadModule
|
||||||
|
from owrx.wsjt import WsjtParser, Msk144Profile
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Msk144Module(PopenModule):
|
class Msk144Module(PopenModule):
|
||||||
@ -11,3 +16,45 @@ class Msk144Module(PopenModule):
|
|||||||
|
|
||||||
def getOutputFormat(self) -> Format:
|
def getOutputFormat(self) -> Format:
|
||||||
return Format.CHAR
|
return Format.CHAR
|
||||||
|
|
||||||
|
|
||||||
|
class ParserAdapter(ThreadModule):
|
||||||
|
def __init__(self):
|
||||||
|
self.retained = bytes()
|
||||||
|
self.parser = WsjtParser()
|
||||||
|
self.dialFrequency = 0
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
profile = Msk144Profile()
|
||||||
|
|
||||||
|
while self.doRun:
|
||||||
|
data = self.reader.read()
|
||||||
|
if data is None:
|
||||||
|
self.doRun = False
|
||||||
|
else:
|
||||||
|
logger.debug('raw data: ' + str(bytes(data)))
|
||||||
|
self.retained += data
|
||||||
|
lines = self.retained.split(b"\n")
|
||||||
|
|
||||||
|
# keep the last line
|
||||||
|
# this should either be empty if the last char was \n
|
||||||
|
# or an incomplete line if the read returned early
|
||||||
|
self.retained = lines[-1]
|
||||||
|
|
||||||
|
# parse all completed lines
|
||||||
|
for line in lines[0:-1]:
|
||||||
|
# actual messages from msk144decoder should start with "*** "
|
||||||
|
if line[0:4] == b"*** ":
|
||||||
|
self.writer.write(pickle.dumps(self.parser.parse(profile, self.dialFrequency, line[4:])))
|
||||||
|
else:
|
||||||
|
logger.debug("ignoring static: %s", line.decode())
|
||||||
|
|
||||||
|
def getInputFormat(self) -> Format:
|
||||||
|
return Format.CHAR
|
||||||
|
|
||||||
|
def getOutputFormat(self) -> Format:
|
||||||
|
return Format.CHAR
|
||||||
|
|
||||||
|
def setDialFrequency(self, frequency: int) -> None:
|
||||||
|
self.dialFrequency = frequency
|
||||||
|
13
owrx/wsjt.py
13
owrx/wsjt.py
@ -245,6 +245,17 @@ class Q65Profile(WsjtProfile):
|
|||||||
return ["jt9", "--q65", "-p", str(self.interval), "-b", self.mode.name, "-d", str(self.decoding_depth()), file]
|
return ["jt9", "--q65", "-p", str(self.interval), "-b", self.mode.name, "-d", str(self.decoding_depth()), file]
|
||||||
|
|
||||||
|
|
||||||
|
class Msk144Profile(WsjtProfile):
|
||||||
|
def getMode(self):
|
||||||
|
return "MSK144"
|
||||||
|
|
||||||
|
def getInterval(self):
|
||||||
|
return 15
|
||||||
|
|
||||||
|
def decoder_commandline(self, file):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class WsjtParser(AudioChopperParser):
|
class WsjtParser(AudioChopperParser):
|
||||||
def parse(self, profile: WsjtProfile, freq: int, raw_msg: bytes):
|
def parse(self, profile: WsjtProfile, freq: int, raw_msg: bytes):
|
||||||
try:
|
try:
|
||||||
@ -366,6 +377,8 @@ class Jt9Decoder(Decoder):
|
|||||||
# '0003 -4 0.4 1762 # CQ R2ABM KO85'
|
# '0003 -4 0.4 1762 # CQ R2ABM KO85'
|
||||||
# fst4 sample
|
# fst4 sample
|
||||||
# '**** -23 0.6 3023 ` <...> <...> R 591631 BI53PV'
|
# '**** -23 0.6 3023 ` <...> <...> R 591631 BI53PV'
|
||||||
|
# MSK144 sample
|
||||||
|
# '221602 8 0.4 1488 & K1JT WA4CQG EM72'
|
||||||
msg, timestamp = self.parse_timestamp(msg)
|
msg, timestamp = self.parse_timestamp(msg)
|
||||||
wsjt_msg = msg[17:53].strip()
|
wsjt_msg = msg[17:53].strip()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user