From fa3b5cd7e6af3a2f1207801016a0c08f1c54dba1 Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Fri, 25 Dec 2020 20:27:30 +0100 Subject: [PATCH] implement new buffer input / output api --- csdr/chain/__init__.py | 31 +++++++++++++++++++++++-------- csdr/chain/fft.py | 34 +++++++++++++++++++++++++++------- csdr/csdr.py | 18 +++++++++++------- owrx/fft.py | 2 +- owrx/source/__init__.py | 11 +++++++++-- 5 files changed, 71 insertions(+), 25 deletions(-) diff --git a/csdr/chain/__init__.py b/csdr/chain/__init__.py index 7197c4e..424d01f 100644 --- a/csdr/chain/__init__.py +++ b/csdr/chain/__init__.py @@ -1,19 +1,34 @@ +from pycsdr import Buffer + +import logging +logger = logging.getLogger(__name__) + + class Chain(object): def __init__(self, *workers): + self.input = None + self.output = None self.workers = workers - stage = None - for w in self.workers: - if stage is not None: - w.setInput(stage.getBuffer()) - stage = w - self.buffer = stage.getBuffer() + for i in range(1, len(self.workers)): + self._connect(self.workers[i - 1], self.workers[i]) + + def _connect(self, w1, w2): + buffer = Buffer() + w1.setOutput(buffer) + w2.setInput(buffer) def stop(self): for w in self.workers: w.stop() def setInput(self, buffer): + if self.input == buffer: + return + self.input = buffer self.workers[0].setInput(buffer) - def getBuffer(self): - return self.buffer + def setOutput(self, buffer): + if self.output == buffer: + return + self.output = buffer + self.workers[-1].setOutput(buffer) diff --git a/csdr/chain/fft.py b/csdr/chain/fft.py index 163bbdf..5813fc6 100644 --- a/csdr/chain/fft.py +++ b/csdr/chain/fft.py @@ -1,25 +1,45 @@ from csdr.chain import Chain -from pycsdr import Fft, LogAveragePower, FftExchangeSides, CompressFftAdpcm +from pycsdr import Fft, LogPower, LogAveragePower, FftExchangeSides, CompressFftAdpcm import logging logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) class FftAverager(Chain): def __init__(self, fft_size, fft_averages): self.fftSize = fft_size - self.fftAverages = fft_averages - self.worker = LogAveragePower(add_db=-70, fft_size=self.fftSize, avg_number=self.fftAverages) + self.fftAverages = None + self.worker = None + self.input = None + self.output = None + self.setFftAverages(fft_averages) workers = [self.worker] super().__init__(*workers) def setFftAverages(self, fft_averages): if self.fftAverages == fft_averages: return + if fft_averages == 0 and self.fftAverages != 0: + if self.worker is not None: + self.worker.stop() + self.worker = LogPower(add_db=70) + if self.output is not None: + self.worker.setOutput(self.output) + if self.input is not None: + self.worker.setInput(self.input) + elif fft_averages != 0: + if self.fftAverages == 0 or self.worker is None: + if self.worker is not None: + self.worker.stop() + self.worker = LogAveragePower(add_db=-70, fft_size=self.fftSize, avg_number=fft_averages) + if self.output is not None: + self.worker.setOutput(self.output) + if self.input is not None: + self.worker.setInput(self.input) + else: + self.worker.setFftAverages(avg_number=fft_averages) + self.workers = [self.worker] self.fftAverages = fft_averages - # TODO replace worker with LogPower if fft_averages == 0 - self.worker.setFftAverages(avg_number=self.fftAverages) class FftChain(Chain): @@ -32,7 +52,7 @@ class FftChain(Chain): self.blockSize = 0 self.fft = Fft(size=self.size, every_n_samples=self.blockSize) - self.averager = FftAverager(fft_size=self.size, fft_averages=0) + self.averager = FftAverager(fft_size=self.size, fft_averages=10) self.fftExchangeSides = FftExchangeSides(fft_size=self.size) workers = [ self.fft, diff --git a/csdr/csdr.py b/csdr/csdr.py index ebd81b9..d663b81 100644 --- a/csdr/csdr.py +++ b/csdr/csdr.py @@ -36,6 +36,8 @@ from owrx.audio import AudioChopper from csdr.pipe import Pipe from csdr.chain.fft import FftChain +from pycsdr import Buffer + import logging logger = logging.getLogger(__name__) @@ -77,7 +79,7 @@ class dsp(object): def __init__(self, output): self.pycsdr_enabled = True self.pycsdr_chain = None - self.socketClient = None + self.buffer = None self.samp_rate = 250000 self.output_rate = 11025 @@ -139,10 +141,10 @@ class dsp(object): self.direwolf_port = None self.process = None - def setSocketClient(self, socketClient): - self.socketClient = socketClient + def setBuffer(self, buffer): + self.buffer = buffer if self.pycsdr_chain is not None: - self.pycsdr_chain.setInput(socketClient.getBuffer()) + self.pycsdr_chain.setInput(buffer) def set_service(self, flag=True): self.is_service = flag @@ -790,10 +792,12 @@ class dsp(object): fft_compression=self.fft_compression ) - if self.socketClient is not None: - self.pycsdr_chain.setInput(self.socketClient.getBuffer()) + if self.buffer is not None: + self.pycsdr_chain.setInput(self.buffer) - self.output.send_output("audio", self.pycsdr_chain.getBuffer().read) + buffer = Buffer() + self.pycsdr_chain.setOutput(buffer) + self.output.send_output("audio", buffer.read) return with self.modification_lock: diff --git a/owrx/fft.py b/owrx/fft.py index 85f6d45..141ca45 100644 --- a/owrx/fft.py +++ b/owrx/fft.py @@ -31,7 +31,7 @@ class SpectrumThread(csdr.output, SdrSourceEventClient): self.dsp = dsp = csdr.dsp(self) dsp.nc_port = self.sdrSource.getPort() - dsp.setSocketClient(self.sdrSource.getSocketClient()) + dsp.setBuffer(self.sdrSource.getBuffer()) dsp.set_demodulator("fft") self.subscriptions = [ diff --git a/owrx/source/__init__.py b/owrx/source/__init__.py index 21d1761..590b301 100644 --- a/owrx/source/__init__.py +++ b/owrx/source/__init__.py @@ -11,7 +11,7 @@ from owrx.command import CommandMapper from owrx.socket import getAvailablePort from owrx.property import PropertyStack, PropertyLayer -from pycsdr import SocketClient +from pycsdr import SocketClient, Buffer import logging @@ -51,6 +51,7 @@ class SdrSource(ABC): self.commandMapper = None self.socketClient = None + self.buffer = None self.props = PropertyStack() # layer 0 reserved for profile properties @@ -144,12 +145,18 @@ class SdrSource(ABC): def getPort(self): return self.port - def getSocketClient(self): + def _getSocketCLient(self): with self.modificationLock: if self.socketClient is None: self.socketClient = SocketClient(self.port) return self.socketClient + def getBuffer(self): + if self.buffer is None: + self.buffer = Buffer() + self._getSocketCLient().setOutput(self.buffer) + return self.buffer + def getCommandValues(self): dict = self.sdrProps.__dict__() if "lfo_offset" in dict and dict["lfo_offset"] is not None: