diff --git a/csdr/chain/dablin.py b/csdr/chain/dablin.py index 56eaa9b5..8b2e7c02 100644 --- a/csdr/chain/dablin.py +++ b/csdr/chain/dablin.py @@ -1,21 +1,73 @@ from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio +from csdr.module import PickleModule from csdreti.modules import EtiDecoder from owrx.dab.dablin import DablinModule -from pycsdr.modules import Downmix +from pycsdr.modules import Downmix, Buffer, Shift from pycsdr.types import Format +from typing import Optional +from random import random + +import logging + +logger = logging.getLogger(__name__) + + +class MetaProcessor(PickleModule): + def __init__(self, shifter: Shift): + self.shifter = shifter + self.shift = 0.0 + self.coarse_increment = -32 / 2048000 + self.fine_increment = - (1/3) / 2048000 + super().__init__() + + def process(self, data): + if "coarse_frequency_shift" in data: + value = int(data["coarse_frequency_shift"]) + if value > 0: + self.shift += random() * self.coarse_increment + else: + self.shift -= random() * self.coarse_increment + logger.debug("coarse adjustment - new shift: %f", self.shift) + self.shifter.setRate(self.shift) + if "fine_frequency_shift" in data: + value = float(data["fine_frequency_shift"]) + if abs(value) > 10: + self.shift += self.fine_increment * value + logger.debug("ffs: %f", value) + logger.debug("fine adjustment - new shift: %f", self.shift) + self.shifter.setRate(self.shift) class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio): def __init__(self): + shift = Shift(0) + decoder = EtiDecoder() + + metaBuffer = Buffer(Format.CHAR) + decoder.setMetaWriter(metaBuffer) + self.processor = MetaProcessor(shift) + self.processor.setReader(metaBuffer.getReader()) + self.processor.setWriter(Buffer(Format.CHAR)) + workers = [ - EtiDecoder(), + shift, + decoder, DablinModule(), Downmix(Format.FLOAT), ] super().__init__(workers) + def _connect(self, w1, w2, buffer: Optional[Buffer] = None) -> None: + if isinstance(w2, EtiDecoder): + # eti decoder needs big chunks of data + buffer = Buffer(w1.getOutputFormat(), size=1048576) + super()._connect(w1, w2, buffer) + def getFixedIfSampleRate(self) -> int: return 2048000 def getFixedAudioRate(self) -> int: return 48000 + + def stop(self): + self.processor.stop() diff --git a/owrx/dsp.py b/owrx/dsp.py index 80a2be39..f9f8bb7f 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, size=524288) + self.selectorBuffer = Buffer(Format.COMPLEX_FLOAT) self.audioBuffer = None self.demodulator = demod self.secondaryDemodulator = None