diff --git a/csdr/__init__.py b/csdr/__init__.py index 561997ab..9ea983bb 100644 --- a/csdr/__init__.py +++ b/csdr/__init__.py @@ -671,7 +671,7 @@ class Dsp(DirewolfConfigSubscriber): if self.has_pipe("dmr_control_pipe"): self.pipes["dmr_control_pipe"].write("{0}\n".format(filter)) if self.pycsdr_enabled and self.pycsdr_chain is not None and isinstance(self.pycsdr_chain, DemodulatorChain): - self.pycsdr_chain.setDmrFilter(filter) + self.pycsdr_chain.setSlotFilter(filter) def set_wfm_deemphasis_tau(self, tau): if self.wfm_deemphasis_tau == tau: diff --git a/csdr/chain/demodulator.py b/csdr/chain/demodulator.py index ceb6bdba..b65a8bc9 100644 --- a/csdr/chain/demodulator.py +++ b/csdr/chain/demodulator.py @@ -1,5 +1,6 @@ from csdr.chain import Chain from abc import ABC, abstractmethod +from pycsdr.modules import Writer class BaseDemodulatorChain(Chain): @@ -36,3 +37,15 @@ class DialFrequencyReceiver(ABC): # marker interface class HdAudio: pass + + +class MetaProvider(ABC): + @abstractmethod + def setMetaWriter(self, writer: Writer) -> None: + pass + + +class SlotFilterChain(ABC): + @abstractmethod + def setSlotFilter(self, filter: int) -> None: + pass diff --git a/csdr/chain/digiham.py b/csdr/chain/digiham.py index 8409dff8..f5863585 100644 --- a/csdr/chain/digiham.py +++ b/csdr/chain/digiham.py @@ -1,4 +1,4 @@ -from csdr.chain.demodulator import BaseDemodulatorChain, FixedAudioRateChain, FixedIfSampleRateChain, DialFrequencyReceiver +from csdr.chain.demodulator import BaseDemodulatorChain, FixedAudioRateChain, FixedIfSampleRateChain, DialFrequencyReceiver, MetaProvider, SlotFilterChain from pycsdr.modules import FmDemod, Agc, Writer, Buffer from pycsdr.types import Format from digiham.modules import DstarDecoder, DcBlock, FskDemodulator, GfskDemodulator, DigitalVoiceFilter, MbeSynthesizer, NarrowRrcFilter, NxdnDecoder, DmrDecoder, WideRrcFilter, YsfDecoder @@ -6,7 +6,7 @@ from digiham.ambe import Modes from owrx.meta import MetaParser -class DigihamChain(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, DialFrequencyReceiver): +class DigihamChain(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, DialFrequencyReceiver, MetaProvider): def __init__(self, fskDemodulator, decoder, mbeMode, filter=None, codecserver: str = ""): self.decoder = decoder if codecserver is None: @@ -34,7 +34,7 @@ class DigihamChain(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateC def getFixedAudioRate(self): return 8000 - def setMetaWriter(self, writer: Writer): + def setMetaWriter(self, writer: Writer) -> None: if self.metaParser is None: self.metaParser = MetaParser() buffer = Buffer(Format.CHAR) @@ -80,7 +80,7 @@ class Nxdn(DigihamChain): ) -class Dmr(DigihamChain): +class Dmr(DigihamChain, SlotFilterChain): def __init__(self, codecserver: str = ""): super().__init__( fskDemodulator=GfskDemodulator(samplesPerSymbol=10), diff --git a/owrx/dsp.py b/owrx/dsp.py index c13957c5..7869fbef 100644 --- a/owrx/dsp.py +++ b/owrx/dsp.py @@ -5,14 +5,9 @@ from owrx.property import PropertyStack, PropertyLayer, PropertyValidator from owrx.property.validators import OrValidator, RegexValidator, BoolValidator from owrx.modes import Modes from csdr.chain import Chain -from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, SecondaryDemodulator, DialFrequencyReceiver +from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, SecondaryDemodulator, DialFrequencyReceiver, MetaProvider, SlotFilterChain from csdr.chain.selector import Selector from csdr.chain.clientaudio import ClientAudioChain -from csdr.chain.analog import NFm, WFm, Am, Ssb -from csdr.chain.digiham import DigihamChain, Dmr, Dstar, Nxdn, Ysf -from csdr.chain.m17 import M17 -from csdr.chain.freedv import FreeDV -from csdr.chain.drm import Drm from csdr.chain.fft import FftChain from csdr.chain.digimodes import AudioChopperDemodulator, PacketDemodulator, PocsagDemodulator from pycsdr.modules import Buffer, Writer @@ -113,7 +108,7 @@ class ClientDemodulatorChain(Chain): self.clientAudioChain.setClientRate(outputRate) - if self.metaWriter is not None and isinstance(demodulator, DigihamChain): + if self.metaWriter is not None and isinstance(demodulator, MetaProvider): demodulator.setMetaWriter(self.metaWriter) def _getSelectorOutputRate(self): @@ -249,7 +244,7 @@ class ClientDemodulatorChain(Chain): if writer is self.metaWriter: return self.metaWriter = writer - if isinstance(self.demodulator, DigihamChain): + if isinstance(self.demodulator, MetaProvider): self.demodulator.setMetaWriter(self.metaWriter) def setSecondaryFftWriter(self, writer: Writer) -> None: @@ -267,8 +262,8 @@ class ClientDemodulatorChain(Chain): if self.secondaryDemodulator is not None: self.secondaryDemodulator.setWriter(writer) - def setDmrFilter(self, filter: int) -> None: - if not isinstance(self.demodulator, Dmr): + def setSlotFilter(self, filter: int) -> None: + if not isinstance(self.demodulator, SlotFilterChain): return self.demodulator.setSlotFilter(filter) @@ -398,7 +393,7 @@ class DspManager(SdrSourceEventClient): self.props.wireProperty("low_cut", self.chain.setLowCut), self.props.wireProperty("high_cut", self.chain.setHighCut), self.props.wireProperty("mod", self.setDemodulator), - self.props.wireProperty("dmr_filter", self.chain.setDmrFilter), + self.props.wireProperty("dmr_filter", self.chain.setSlotFilter), # TODO # self.props.wireProperty("wfm_deemphasis_tau", self.dsp.set_wfm_deemphasis_tau), # TODO @@ -433,26 +428,37 @@ class DspManager(SdrSourceEventClient): return demod # TODO: move this to Modes if demod == "nfm": + from csdr.chain.analog import NFm return NFm(self.props["output_rate"]) elif demod == "wfm": + from csdr.chain.analog import WFm return WFm(self.props["hd_output_rate"], self.props["wfm_deemphasis_tau"]) elif demod == "am": + from csdr.chain.analog import Am return Am() elif demod in ["usb", "lsb", "cw"]: + from csdr.chain.analog import Ssb return Ssb() elif demod == "dmr": + from csdr.chain.digiham import Dmr return Dmr(self.props["digital_voice_codecserver"]) elif demod == "dstar": + from csdr.chain.digiham import Dstar return Dstar(self.props["digital_voice_codecserver"]) elif demod == "ysf": + from csdr.chain.digiham import Ysf return Ysf(self.props["digital_voice_codecserver"]) elif demod == "nxdn": + from csdr.chain.digiham import Nxdn return Nxdn(self.props["digital_voice_codecserver"]) elif demod == "m17": + from csdr.chain.m17 import M17 return M17() elif demod == "drm": + from csdr.chain.drm import Drm return Drm() elif demod == "freedv": + from csdr.chain.freedv import FreeDV return FreeDV() def setDemodulator(self, mod): diff --git a/owrx/service/__init__.py b/owrx/service/__init__.py index d6d66982..cc160e2f 100644 --- a/owrx/service/__init__.py +++ b/owrx/service/__init__.py @@ -12,8 +12,6 @@ from owrx.service.chain import ServiceDemodulatorChain from owrx.modes import Modes, DigitalMode from typing import Union from csdr.chain.demodulator import BaseDemodulatorChain, SecondaryDemodulator, DialFrequencyReceiver -from csdr.chain.analog import NFm, Ssb -from csdr.chain.digimodes import AudioChopperDemodulator, PacketDemodulator from pycsdr.modules import Buffer import logging @@ -274,8 +272,10 @@ class ServiceHandler(SdrSourceEventClient): return demod # TODO: move this to Modes if demod == "nfm": + from csdr.chain.analog import NFm return NFm(48000) elif demod in ["usb", "lsb", "cw"]: + from csdr.chain.analog import Ssb return Ssb() # TODO move this elsewhere @@ -284,10 +284,13 @@ class ServiceHandler(SdrSourceEventClient): return mod # TODO add remaining modes if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]: + from csdr.chain.digimodes import AudioChopperDemodulator return AudioChopperDemodulator(mod, WsjtParser()) elif mod == "js8": + from csdr.chain.digimodes import AudioChopperDemodulator return AudioChopperDemodulator(mod, Js8Parser()) elif mod == "packet": + from csdr.chain.digimodes import PacketDemodulator return PacketDemodulator(service=True) return None