diff --git a/csdr/chain/dablin.py b/csdr/chain/dablin.py new file mode 100644 index 00000000..56eaa9b5 --- /dev/null +++ b/csdr/chain/dablin.py @@ -0,0 +1,21 @@ +from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio +from csdreti.modules import EtiDecoder +from owrx.dab.dablin import DablinModule +from pycsdr.modules import Downmix +from pycsdr.types import Format + + +class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio): + def __init__(self): + workers = [ + EtiDecoder(), + DablinModule(), + Downmix(Format.FLOAT), + ] + super().__init__(workers) + + def getFixedIfSampleRate(self) -> int: + return 2048000 + + def getFixedAudioRate(self) -> int: + return 48000 diff --git a/owrx/dab/dablin.py b/owrx/dab/dablin.py new file mode 100644 index 00000000..78a5f2c4 --- /dev/null +++ b/owrx/dab/dablin.py @@ -0,0 +1,11 @@ +from pycsdr.modules import ExecModule +from pycsdr.types import Format + + +class DablinModule(ExecModule): + def __init__(self): + super().__init__( + Format.CHAR, + Format.FLOAT, + ["dablin", "-s", "0x15DC", "-p"] + ) diff --git a/owrx/dsp.py b/owrx/dsp.py index 78d6f13a..80a2be39 100644 --- a/owrx/dsp.py +++ b/owrx/dsp.py @@ -40,7 +40,7 @@ class ClientDemodulatorChain(Chain): self.hdOutputRate = hdOutputRate self.secondaryDspEventReceiver = secondaryDspEventReceiver self.selector = Selector(sampleRate, outputRate) - self.selectorBuffer = Buffer(Format.COMPLEX_FLOAT) + self.selectorBuffer = Buffer(Format.COMPLEX_FLOAT, size=524288) self.audioBuffer = None self.demodulator = demod self.secondaryDemodulator = None @@ -573,6 +573,9 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient) elif demod == "freedv": from csdr.chain.freedv import FreeDV return FreeDV() + elif demod == "dab": + from csdr.chain.dablin import Dablin + return Dablin() elif demod == "empty": from csdr.chain.analog import Empty return Empty() diff --git a/owrx/feature.py b/owrx/feature.py index c38b0396..8617e159 100644 --- a/owrx/feature.py +++ b/owrx/feature.py @@ -90,6 +90,7 @@ class FeatureDetector(object): "dumphfdl": ["dumphfdl"], "dumpvdl2": ["dumpvdl2"], "redsea": ["redsea"], + "dab": ["csdreti", "dablin"] } def feature_availability(self): @@ -648,3 +649,26 @@ class FeatureDetector(object): `redsea`. """ return self.command_is_runnable("redsea --version") + + def has_csdreti(self): + """ + TODO: feature description + """ + required_version = LooseVersion("0.1") + + try: + from csdreti.modules import csdreti_version + from csdreti.modules import version as pycsdreti_version + + return ( + LooseVersion(csdreti_version) >= required_version + and LooseVersion(pycsdreti_version) >= required_version + ) + except ImportError: + return False + + def has_dablin(self): + """ + TODO: feature description + """ + return self.command_is_runnable("dablin -h") diff --git a/owrx/modes.py b/owrx/modes.py index 94c67744..51017b98 100644 --- a/owrx/modes.py +++ b/owrx/modes.py @@ -132,6 +132,7 @@ class Modes(object): "freedv", "FreeDV", bandpass=Bandpass(300, 3000), requirements=["digital_voice_freedv"], squelch=False ), AnalogMode("drm", "DRM", bandpass=Bandpass(-5000, 5000), requirements=["drm"], squelch=False), + AnalogMode("dab", "DAB", bandpass=Bandpass(-1e6, 1e6), requirements=["dab"], squelch=False), DigitalMode("bpsk31", "BPSK31", underlying=["usb"]), DigitalMode("bpsk63", "BPSK63", underlying=["usb"]), DigitalMode("rtty170", "RTTY 45/170", underlying=["usb", "lsb"]),