implement new buffer input / output api

This commit is contained in:
Jakob Ketterl 2020-12-25 20:27:30 +01:00
parent 2df527ed20
commit fa3b5cd7e6
5 changed files with 71 additions and 25 deletions

View File

@ -1,19 +1,34 @@
from pycsdr import Buffer
import logging
logger = logging.getLogger(__name__)
class Chain(object): class Chain(object):
def __init__(self, *workers): def __init__(self, *workers):
self.input = None
self.output = None
self.workers = workers self.workers = workers
stage = None for i in range(1, len(self.workers)):
for w in self.workers: self._connect(self.workers[i - 1], self.workers[i])
if stage is not None:
w.setInput(stage.getBuffer()) def _connect(self, w1, w2):
stage = w buffer = Buffer()
self.buffer = stage.getBuffer() w1.setOutput(buffer)
w2.setInput(buffer)
def stop(self): def stop(self):
for w in self.workers: for w in self.workers:
w.stop() w.stop()
def setInput(self, buffer): def setInput(self, buffer):
if self.input == buffer:
return
self.input = buffer
self.workers[0].setInput(buffer) self.workers[0].setInput(buffer)
def getBuffer(self): def setOutput(self, buffer):
return self.buffer if self.output == buffer:
return
self.output = buffer
self.workers[-1].setOutput(buffer)

View File

@ -1,25 +1,45 @@
from csdr.chain import Chain from csdr.chain import Chain
from pycsdr import Fft, LogAveragePower, FftExchangeSides, CompressFftAdpcm from pycsdr import Fft, LogPower, LogAveragePower, FftExchangeSides, CompressFftAdpcm
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
class FftAverager(Chain): class FftAverager(Chain):
def __init__(self, fft_size, fft_averages): def __init__(self, fft_size, fft_averages):
self.fftSize = fft_size self.fftSize = fft_size
self.fftAverages = fft_averages self.fftAverages = None
self.worker = LogAveragePower(add_db=-70, fft_size=self.fftSize, avg_number=self.fftAverages) self.worker = None
self.input = None
self.output = None
self.setFftAverages(fft_averages)
workers = [self.worker] workers = [self.worker]
super().__init__(*workers) super().__init__(*workers)
def setFftAverages(self, fft_averages): def setFftAverages(self, fft_averages):
if self.fftAverages == fft_averages: if self.fftAverages == fft_averages:
return 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 self.fftAverages = fft_averages
# TODO replace worker with LogPower if fft_averages == 0
self.worker.setFftAverages(avg_number=self.fftAverages)
class FftChain(Chain): class FftChain(Chain):
@ -32,7 +52,7 @@ class FftChain(Chain):
self.blockSize = 0 self.blockSize = 0
self.fft = Fft(size=self.size, every_n_samples=self.blockSize) 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) self.fftExchangeSides = FftExchangeSides(fft_size=self.size)
workers = [ workers = [
self.fft, self.fft,

View File

@ -36,6 +36,8 @@ from owrx.audio import AudioChopper
from csdr.pipe import Pipe from csdr.pipe import Pipe
from csdr.chain.fft import FftChain from csdr.chain.fft import FftChain
from pycsdr import Buffer
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -77,7 +79,7 @@ class dsp(object):
def __init__(self, output): def __init__(self, output):
self.pycsdr_enabled = True self.pycsdr_enabled = True
self.pycsdr_chain = None self.pycsdr_chain = None
self.socketClient = None self.buffer = None
self.samp_rate = 250000 self.samp_rate = 250000
self.output_rate = 11025 self.output_rate = 11025
@ -139,10 +141,10 @@ class dsp(object):
self.direwolf_port = None self.direwolf_port = None
self.process = None self.process = None
def setSocketClient(self, socketClient): def setBuffer(self, buffer):
self.socketClient = socketClient self.buffer = buffer
if self.pycsdr_chain is not None: if self.pycsdr_chain is not None:
self.pycsdr_chain.setInput(socketClient.getBuffer()) self.pycsdr_chain.setInput(buffer)
def set_service(self, flag=True): def set_service(self, flag=True):
self.is_service = flag self.is_service = flag
@ -790,10 +792,12 @@ class dsp(object):
fft_compression=self.fft_compression fft_compression=self.fft_compression
) )
if self.socketClient is not None: if self.buffer is not None:
self.pycsdr_chain.setInput(self.socketClient.getBuffer()) 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 return
with self.modification_lock: with self.modification_lock:

View File

@ -31,7 +31,7 @@ class SpectrumThread(csdr.output, SdrSourceEventClient):
self.dsp = dsp = csdr.dsp(self) self.dsp = dsp = csdr.dsp(self)
dsp.nc_port = self.sdrSource.getPort() dsp.nc_port = self.sdrSource.getPort()
dsp.setSocketClient(self.sdrSource.getSocketClient()) dsp.setBuffer(self.sdrSource.getBuffer())
dsp.set_demodulator("fft") dsp.set_demodulator("fft")
self.subscriptions = [ self.subscriptions = [

View File

@ -11,7 +11,7 @@ from owrx.command import CommandMapper
from owrx.socket import getAvailablePort from owrx.socket import getAvailablePort
from owrx.property import PropertyStack, PropertyLayer from owrx.property import PropertyStack, PropertyLayer
from pycsdr import SocketClient from pycsdr import SocketClient, Buffer
import logging import logging
@ -51,6 +51,7 @@ class SdrSource(ABC):
self.commandMapper = None self.commandMapper = None
self.socketClient = None self.socketClient = None
self.buffer = None
self.props = PropertyStack() self.props = PropertyStack()
# layer 0 reserved for profile properties # layer 0 reserved for profile properties
@ -144,12 +145,18 @@ class SdrSource(ABC):
def getPort(self): def getPort(self):
return self.port return self.port
def getSocketClient(self): def _getSocketCLient(self):
with self.modificationLock: with self.modificationLock:
if self.socketClient is None: if self.socketClient is None:
self.socketClient = SocketClient(self.port) self.socketClient = SocketClient(self.port)
return self.socketClient 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): def getCommandValues(self):
dict = self.sdrProps.__dict__() dict = self.sdrProps.__dict__()
if "lfo_offset" in dict and dict["lfo_offset"] is not None: if "lfo_offset" in dict and dict["lfo_offset"] is not None: