abstract chain features; use local imports to avoid hard dependencies

This commit is contained in:
Jakob Ketterl 2021-09-20 16:14:23 +02:00
parent b2e15c559e
commit 81ed1a9ebb
5 changed files with 40 additions and 18 deletions

View File

@ -671,7 +671,7 @@ class Dsp(DirewolfConfigSubscriber):
if self.has_pipe("dmr_control_pipe"): if self.has_pipe("dmr_control_pipe"):
self.pipes["dmr_control_pipe"].write("{0}\n".format(filter)) 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): 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): def set_wfm_deemphasis_tau(self, tau):
if self.wfm_deemphasis_tau == tau: if self.wfm_deemphasis_tau == tau:

View File

@ -1,5 +1,6 @@
from csdr.chain import Chain from csdr.chain import Chain
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from pycsdr.modules import Writer
class BaseDemodulatorChain(Chain): class BaseDemodulatorChain(Chain):
@ -36,3 +37,15 @@ class DialFrequencyReceiver(ABC):
# marker interface # marker interface
class HdAudio: class HdAudio:
pass pass
class MetaProvider(ABC):
@abstractmethod
def setMetaWriter(self, writer: Writer) -> None:
pass
class SlotFilterChain(ABC):
@abstractmethod
def setSlotFilter(self, filter: int) -> None:
pass

View File

@ -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.modules import FmDemod, Agc, Writer, Buffer
from pycsdr.types import Format from pycsdr.types import Format
from digiham.modules import DstarDecoder, DcBlock, FskDemodulator, GfskDemodulator, DigitalVoiceFilter, MbeSynthesizer, NarrowRrcFilter, NxdnDecoder, DmrDecoder, WideRrcFilter, YsfDecoder 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 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 = ""): def __init__(self, fskDemodulator, decoder, mbeMode, filter=None, codecserver: str = ""):
self.decoder = decoder self.decoder = decoder
if codecserver is None: if codecserver is None:
@ -34,7 +34,7 @@ class DigihamChain(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateC
def getFixedAudioRate(self): def getFixedAudioRate(self):
return 8000 return 8000
def setMetaWriter(self, writer: Writer): def setMetaWriter(self, writer: Writer) -> None:
if self.metaParser is None: if self.metaParser is None:
self.metaParser = MetaParser() self.metaParser = MetaParser()
buffer = Buffer(Format.CHAR) buffer = Buffer(Format.CHAR)
@ -80,7 +80,7 @@ class Nxdn(DigihamChain):
) )
class Dmr(DigihamChain): class Dmr(DigihamChain, SlotFilterChain):
def __init__(self, codecserver: str = ""): def __init__(self, codecserver: str = ""):
super().__init__( super().__init__(
fskDemodulator=GfskDemodulator(samplesPerSymbol=10), fskDemodulator=GfskDemodulator(samplesPerSymbol=10),

View File

@ -5,14 +5,9 @@ from owrx.property import PropertyStack, PropertyLayer, PropertyValidator
from owrx.property.validators import OrValidator, RegexValidator, BoolValidator from owrx.property.validators import OrValidator, RegexValidator, BoolValidator
from owrx.modes import Modes from owrx.modes import Modes
from csdr.chain import Chain 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.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.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.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
@ -113,7 +108,7 @@ class ClientDemodulatorChain(Chain):
self.clientAudioChain.setClientRate(outputRate) 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) demodulator.setMetaWriter(self.metaWriter)
def _getSelectorOutputRate(self): def _getSelectorOutputRate(self):
@ -249,7 +244,7 @@ class ClientDemodulatorChain(Chain):
if writer is self.metaWriter: if writer is self.metaWriter:
return return
self.metaWriter = writer self.metaWriter = writer
if isinstance(self.demodulator, DigihamChain): if isinstance(self.demodulator, MetaProvider):
self.demodulator.setMetaWriter(self.metaWriter) self.demodulator.setMetaWriter(self.metaWriter)
def setSecondaryFftWriter(self, writer: Writer) -> None: def setSecondaryFftWriter(self, writer: Writer) -> None:
@ -267,8 +262,8 @@ class ClientDemodulatorChain(Chain):
if self.secondaryDemodulator is not None: if self.secondaryDemodulator is not None:
self.secondaryDemodulator.setWriter(writer) self.secondaryDemodulator.setWriter(writer)
def setDmrFilter(self, filter: int) -> None: def setSlotFilter(self, filter: int) -> None:
if not isinstance(self.demodulator, Dmr): if not isinstance(self.demodulator, SlotFilterChain):
return return
self.demodulator.setSlotFilter(filter) self.demodulator.setSlotFilter(filter)
@ -398,7 +393,7 @@ class DspManager(SdrSourceEventClient):
self.props.wireProperty("low_cut", self.chain.setLowCut), self.props.wireProperty("low_cut", self.chain.setLowCut),
self.props.wireProperty("high_cut", self.chain.setHighCut), self.props.wireProperty("high_cut", self.chain.setHighCut),
self.props.wireProperty("mod", self.setDemodulator), self.props.wireProperty("mod", self.setDemodulator),
self.props.wireProperty("dmr_filter", self.chain.setDmrFilter), self.props.wireProperty("dmr_filter", self.chain.setSlotFilter),
# TODO # TODO
# self.props.wireProperty("wfm_deemphasis_tau", self.dsp.set_wfm_deemphasis_tau), # self.props.wireProperty("wfm_deemphasis_tau", self.dsp.set_wfm_deemphasis_tau),
# TODO # TODO
@ -433,26 +428,37 @@ class DspManager(SdrSourceEventClient):
return demod return demod
# TODO: move this to Modes # TODO: move this to Modes
if demod == "nfm": if demod == "nfm":
from csdr.chain.analog import NFm
return NFm(self.props["output_rate"]) return NFm(self.props["output_rate"])
elif demod == "wfm": elif demod == "wfm":
from csdr.chain.analog import WFm
return 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":
from csdr.chain.analog import Am
return Am() return Am()
elif demod in ["usb", "lsb", "cw"]: elif demod in ["usb", "lsb", "cw"]:
from csdr.chain.analog import Ssb
return Ssb() return Ssb()
elif demod == "dmr": elif demod == "dmr":
from csdr.chain.digiham import Dmr
return Dmr(self.props["digital_voice_codecserver"]) return Dmr(self.props["digital_voice_codecserver"])
elif demod == "dstar": elif demod == "dstar":
from csdr.chain.digiham import Dstar
return Dstar(self.props["digital_voice_codecserver"]) return Dstar(self.props["digital_voice_codecserver"])
elif demod == "ysf": elif demod == "ysf":
from csdr.chain.digiham import Ysf
return Ysf(self.props["digital_voice_codecserver"]) return Ysf(self.props["digital_voice_codecserver"])
elif demod == "nxdn": elif demod == "nxdn":
from csdr.chain.digiham import Nxdn
return Nxdn(self.props["digital_voice_codecserver"]) return Nxdn(self.props["digital_voice_codecserver"])
elif demod == "m17": elif demod == "m17":
from csdr.chain.m17 import M17
return M17() return M17()
elif demod == "drm": elif demod == "drm":
from csdr.chain.drm import Drm
return Drm() return Drm()
elif demod == "freedv": elif demod == "freedv":
from csdr.chain.freedv import FreeDV
return FreeDV() return FreeDV()
def setDemodulator(self, mod): def setDemodulator(self, mod):

View File

@ -12,8 +12,6 @@ from owrx.service.chain import ServiceDemodulatorChain
from owrx.modes import Modes, DigitalMode from owrx.modes import Modes, DigitalMode
from typing import Union from typing import Union
from csdr.chain.demodulator import BaseDemodulatorChain, SecondaryDemodulator, DialFrequencyReceiver 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 from pycsdr.modules import Buffer
import logging import logging
@ -274,8 +272,10 @@ class ServiceHandler(SdrSourceEventClient):
return demod return demod
# TODO: move this to Modes # TODO: move this to Modes
if demod == "nfm": if demod == "nfm":
from csdr.chain.analog import NFm
return NFm(48000) return NFm(48000)
elif demod in ["usb", "lsb", "cw"]: elif demod in ["usb", "lsb", "cw"]:
from csdr.chain.analog import Ssb
return Ssb() return Ssb()
# TODO move this elsewhere # TODO move this elsewhere
@ -284,10 +284,13 @@ class ServiceHandler(SdrSourceEventClient):
return mod return mod
# TODO add remaining modes # TODO add remaining modes
if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]: if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]:
from csdr.chain.digimodes import AudioChopperDemodulator
return AudioChopperDemodulator(mod, WsjtParser()) return AudioChopperDemodulator(mod, WsjtParser())
elif mod == "js8": elif mod == "js8":
from csdr.chain.digimodes import AudioChopperDemodulator
return AudioChopperDemodulator(mod, Js8Parser()) return AudioChopperDemodulator(mod, Js8Parser())
elif mod == "packet": elif mod == "packet":
from csdr.chain.digimodes import PacketDemodulator
return PacketDemodulator(service=True) return PacketDemodulator(service=True)
return None return None