re-add m17

This commit is contained in:
Jakob Ketterl 2021-09-07 14:45:52 +02:00
parent f9f0bdde12
commit f3b05c6318
6 changed files with 98 additions and 28 deletions

26
csdr/chain/m17.py Normal file
View File

@ -0,0 +1,26 @@
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain
from owrx.m17 import M17Module
from pycsdr.modules import FmDemod, Limit, Convert
from pycsdr.types import Format
from digiham.modules import DcBlock
class M17Chain(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain):
def __init__(self):
workers = [
FmDemod(),
DcBlock(),
Limit(),
Convert(Format.FLOAT, Format.SHORT),
M17Module(),
]
super().__init__(workers)
def getFixedIfSampleRate(self) -> int:
return 48000
def getFixedAudioRate(self) -> int:
return 8000
def supportsSquelch(self) -> bool:
return False

View File

@ -28,12 +28,7 @@ class Module(BaseModule, metaclass=ABCMeta):
pass pass
class ThreadModule(Module, Thread, metaclass=ABCMeta): class AutoStartModule(Module, metaclass=ABCMeta):
def __init__(self):
self.doRun = True
super().__init__()
Thread.__init__(self)
def _checkStart(self) -> None: def _checkStart(self) -> None:
if self.reader is not None and self.writer is not None: if self.reader is not None and self.writer is not None:
self.start() self.start()
@ -46,6 +41,17 @@ class ThreadModule(Module, Thread, metaclass=ABCMeta):
super().setWriter(writer) super().setWriter(writer)
self._checkStart() self._checkStart()
@abstractmethod
def start(self):
pass
class ThreadModule(AutoStartModule, Thread, metaclass=ABCMeta):
def __init__(self):
self.doRun = True
super().__init__()
Thread.__init__(self)
@abstractmethod @abstractmethod
def run(self): def run(self):
pass pass
@ -54,6 +60,9 @@ class ThreadModule(Module, Thread, metaclass=ABCMeta):
self.doRun = False self.doRun = False
self.reader.stop() self.reader.stop()
def start(self):
Thread.start(self)
class PickleModule(ThreadModule): class PickleModule(ThreadModule):
def getInputFormat(self) -> Format: def getInputFormat(self) -> Format:

View File

@ -1,4 +1,4 @@
from csdr.module import Module from csdr.module import AutoStartModule
from pycsdr.types import Format from pycsdr.types import Format
from pycsdr.modules import Reader, Writer, TcpSource from pycsdr.modules import Reader, Writer, TcpSource
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
@ -12,7 +12,7 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class DirewolfModule(Module): class DirewolfModule(AutoStartModule):
def __init__(self, service: bool = False): def __init__(self, service: bool = False):
self.process = None self.process = None
self.inputReader = None self.inputReader = None
@ -20,10 +20,6 @@ class DirewolfModule(Module):
self.service = service self.service = service
super().__init__() super().__init__()
def setReader(self, reader: Reader) -> None:
super().setReader(reader)
self.start()
def setWriter(self, writer: Writer) -> None: def setWriter(self, writer: Writer) -> None:
super().setWriter(writer) super().setWriter(writer)
if self.tcpSource is not None: if self.tcpSource is not None:

View File

@ -12,6 +12,7 @@ from csdr.chain.selector import Selector
from csdr.chain.clientaudio import ClientAudioChain from csdr.chain.clientaudio import ClientAudioChain
from csdr.chain.analog import NFm, WFm, Am, Ssb from csdr.chain.analog import NFm, WFm, Am, Ssb
from csdr.chain.digiham import DigihamChain, Dmr, Dstar, Nxdn, Ysf from csdr.chain.digiham import DigihamChain, Dmr, Dstar, Nxdn, Ysf
from csdr.chain.m17 import M17Chain
from csdr.chain.fft import FftChain from csdr.chain.fft import FftChain
from csdr.chain.digimodes import AudioChopperDemodulator, PacketDemodulator, PocsagDemodulator from csdr.chain.digimodes import AudioChopperDemodulator, PacketDemodulator, PocsagDemodulator
from pycsdr.modules import Buffer, Writer from pycsdr.modules import Buffer, Writer
@ -425,25 +426,24 @@ class DspManager(Output, SdrSourceEventClient):
if isinstance(demod, BaseDemodulatorChain): if isinstance(demod, BaseDemodulatorChain):
return demod return demod
# TODO: move this to Modes # TODO: move this to Modes
demodChain = None
if demod == "nfm": if demod == "nfm":
demodChain = NFm(self.props["output_rate"]) return NFm(self.props["output_rate"])
elif demod == "wfm": elif demod == "wfm":
demodChain = WFm(self.props["hd_output_rate"], self.props["wfm_deemphasis_tau"]) return WFm(self.props["hd_output_rate"], self.props["wfm_deemphasis_tau"])
elif demod == "am": elif demod == "am":
demodChain = Am() return Am()
elif demod in ["usb", "lsb", "cw"]: elif demod in ["usb", "lsb", "cw"]:
demodChain = Ssb() return Ssb()
elif demod == "dmr": elif demod == "dmr":
demodChain = Dmr(self.props["digital_voice_codecserver"]) return Dmr(self.props["digital_voice_codecserver"])
elif demod == "dstar": elif demod == "dstar":
demodChain = Dstar(self.props["digital_voice_codecserver"]) return Dstar(self.props["digital_voice_codecserver"])
elif demod == "ysf": elif demod == "ysf":
demodChain = Ysf(self.props["digital_voice_codecserver"]) return Ysf(self.props["digital_voice_codecserver"])
elif demod == "nxdn": elif demod == "nxdn":
demodChain = Nxdn(self.props["digital_voice_codecserver"]) return Nxdn(self.props["digital_voice_codecserver"])
elif demod == "m17":
return demodChain return M17Chain()
def setDemodulator(self, mod): def setDemodulator(self, mod):
demodulator = self._getDemodulator(mod) demodulator = self._getDemodulator(mod)

42
owrx/m17.py Normal file
View File

@ -0,0 +1,42 @@
from csdr.module import AutoStartModule
from pycsdr.types import Format
from subprocess import Popen, PIPE
import threading
class M17Module(AutoStartModule):
def __init__(self):
self.process = None
super().__init__()
def getInputFormat(self) -> Format:
return Format.SHORT
def getOutputFormat(self) -> Format:
return Format.SHORT
def start(self):
self.process = Popen(["m17-demod"], stdin=PIPE, stdout=PIPE)
threading.Thread(target=self.pump(self.reader.read, self.process.stdin.write)).start()
threading.Thread(target=self.pump(self.process.stdout.read, self.writer.write)).start()
def stop(self):
if self.process is not None:
self.process.terminate()
self.process.wait()
self.process = None
self.reader.stop()
def pump(self, read, write):
def copy():
while True:
data = None
try:
data = read()
except ValueError:
pass
if data is None or isinstance(data, bytes) and len(data) == 0:
break
write(data)
return copy

View File

@ -273,13 +273,10 @@ class ServiceHandler(SdrSourceEventClient):
if isinstance(demod, BaseDemodulatorChain): if isinstance(demod, BaseDemodulatorChain):
return demod return demod
# TODO: move this to Modes # TODO: move this to Modes
demodChain = None
if demod == "nfm": if demod == "nfm":
demodChain = NFm(48000) return NFm(48000)
elif demod in ["usb", "lsb", "cw"]: elif demod in ["usb", "lsb", "cw"]:
demodChain = Ssb() return Ssb()
return demodChain
# TODO move this elsewhere # TODO move this elsewhere
def _getSecondaryDemodulator(self, mod): def _getSecondaryDemodulator(self, mod):