re-add m17
This commit is contained in:
parent
f9f0bdde12
commit
f3b05c6318
26
csdr/chain/m17.py
Normal file
26
csdr/chain/m17.py
Normal 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
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
22
owrx/dsp.py
22
owrx/dsp.py
@ -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
42
owrx/m17.py
Normal 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
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user