restore secondary fft

This commit is contained in:
Jakob Ketterl 2021-08-28 00:10:46 +02:00
parent 47e78579d4
commit 4a4901fa38
2 changed files with 63 additions and 24 deletions

View File

@ -14,10 +14,11 @@ class Chain:
def empty(self): def empty(self):
return not self.workers return not self.workers
def _connect(self, w1, w2): def _connect(self, w1, w2, buffer: Union[Buffer, None] = None) -> None:
writer = Buffer(w1.getOutputFormat()) if buffer is None:
w1.setWriter(writer) buffer = Buffer(w1.getOutputFormat())
w2.setReader(writer.getReader()) w1.setWriter(buffer)
w2.setReader(buffer.getReader())
def setReader(self, reader): def setReader(self, reader):
if self.reader is reader: if self.reader is reader:

View File

@ -14,6 +14,7 @@ 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.analog import NFm, WFm, Am, Ssb
from csdr.chain.digiham import DigihamChain, Dmr, Dstar, Nxdn, Ysf from csdr.chain.digiham import DigihamChain, Dmr, Dstar, Nxdn, Ysf
from csdr.chain.fft import FftChain
from pycsdr.modules import Buffer, Writer from pycsdr.modules import Buffer, Writer
from pycsdr.types import Format from pycsdr.types import Format
from typing import Union from typing import Union
@ -32,14 +33,22 @@ class ClientDemodulatorChain(Chain):
self.hdOutputRate = hdOutputRate self.hdOutputRate = hdOutputRate
self.selector = Selector(sampleRate, outputRate, 0.0) self.selector = Selector(sampleRate, outputRate, 0.0)
self.selector.setBandpass(-4000, 4000) self.selector.setBandpass(-4000, 4000)
self.selectorBuffer = Buffer(Format.COMPLEX_FLOAT)
self.demodulator = demod self.demodulator = demod
inputRate = demod.getFixedAudioRate() if isinstance(demod, FixedAudioRateChain) else outputRate inputRate = demod.getFixedAudioRate() if isinstance(demod, FixedAudioRateChain) else outputRate
oRate = hdOutputRate if isinstance(demod, HdAudio) else outputRate oRate = hdOutputRate if isinstance(demod, HdAudio) else outputRate
self.clientAudioChain = ClientAudioChain(demod.getOutputFormat(), inputRate, oRate, audioCompression) self.clientAudioChain = ClientAudioChain(demod.getOutputFormat(), inputRate, oRate, audioCompression)
self.secondaryFftChain = None
self.metaWriter = None self.metaWriter = None
self.squelchLevel = -150 self.squelchLevel = -150
super().__init__([self.selector, self.demodulator, self.clientAudioChain]) super().__init__([self.selector, self.demodulator, self.clientAudioChain])
def _connect(self, w1, w2, buffer: Union[Buffer, None] = None) -> None:
if w1 is self.selector:
super()._connect(w1, w2, self.selectorBuffer)
else:
super()._connect(w1, w2)
def setDemodulator(self, demodulator: BaseDemodulatorChain): def setDemodulator(self, demodulator: BaseDemodulatorChain):
try: try:
self.clientAudioChain.setFormat(demodulator.getOutputFormat()) self.clientAudioChain.setFormat(demodulator.getOutputFormat())
@ -127,6 +136,13 @@ class ClientDemodulatorChain(Chain):
if not isinstance(self.demodulator, FixedAudioRateChain): if not isinstance(self.demodulator, FixedAudioRateChain):
self.clientAudioChain.setClientRate(outputRate) self.clientAudioChain.setClientRate(outputRate)
def setSampleRate(self, sampleRate: int) -> None:
if sampleRate == self.sampleRate:
return
self.sampleRate = sampleRate
self.selector.setInputRate(sampleRate)
# TODO update secondary FFT
def setPowerWriter(self, writer: Writer) -> None: def setPowerWriter(self, writer: Writer) -> None:
self.selector.setPowerWriter(writer) self.selector.setPowerWriter(writer)
@ -137,11 +153,22 @@ class ClientDemodulatorChain(Chain):
if isinstance(self.demodulator, DigihamChain): if isinstance(self.demodulator, DigihamChain):
self.demodulator.setMetaWriter(self.metaWriter) self.demodulator.setMetaWriter(self.metaWriter)
def setSampleRate(self, sampleRate: int) -> None: def setSecondaryFftWriter(self, writer: Union[Writer, None]) -> None:
if sampleRate == self.sampleRate: if writer is None:
return if self.secondaryFftChain is not None:
self.sampleRate = sampleRate self.secondaryFftChain.stop()
self.selector.setInputRate(sampleRate) self.secondaryFftChain = None
else:
if self.secondaryFftChain is None:
# TODO eliminate constants
self.secondaryFftChain = FftChain(self.outputRate, 2048, 0.3, 9, "adpcm")
self.secondaryFftChain.setReader(self.selectorBuffer.getReader())
self.secondaryFftChain.setWriter(writer)
def setSecondaryFftSize(self, size: int) -> None:
# TODO
pass
class ModulationValidator(OrValidator): class ModulationValidator(OrValidator):
@ -262,8 +289,7 @@ class DspManager(Output, SdrSourceEventClient):
self.props.wireProperty("audio_compression", self.setAudioCompression), self.props.wireProperty("audio_compression", self.setAudioCompression),
# probably unused: # probably unused:
# self.props.wireProperty("fft_compression", self.dsp.set_fft_compression), # self.props.wireProperty("fft_compression", self.dsp.set_fft_compression),
# TODO self.props.wireProperty("digimodes_fft_size", self.chain.setSecondaryFftSize),
# self.props.wireProperty("digimodes_fft_size", self.dsp.set_secondary_fft_size),
self.props.wireProperty("samp_rate", self.chain.setSampleRate), self.props.wireProperty("samp_rate", self.chain.setSampleRate),
self.props.wireProperty("output_rate", self.chain.setOutputRate), self.props.wireProperty("output_rate", self.chain.setOutputRate),
self.props.wireProperty("hd_output_rate", self.chain.setHdOutputRate), self.props.wireProperty("hd_output_rate", self.chain.setHdOutputRate),
@ -286,26 +312,17 @@ class DspManager(Output, SdrSourceEventClient):
# TODO # TODO
# sp.set_temporary_directory(CoreConfig().get_temporary_directory()) # sp.set_temporary_directory(CoreConfig().get_temporary_directory())
def send_secondary_config(*args):
self.handler.write_secondary_dsp_config(
{
"secondary_fft_size": self.props["digimodes_fft_size"],
"if_samp_rate": self.dsp.if_samp_rate(),
"secondary_bw": self.dsp.secondary_bw(),
}
)
def set_secondary_mod(mod): def set_secondary_mod(mod):
if mod == False: if mod == False:
mod = None mod = None
self.dsp.set_secondary_demodulator(mod) self.dsp.set_secondary_demodulator(mod)
if mod is not None: #if mod is not None:
send_secondary_config() #send_secondary_config()
self.subscriptions += [ self.subscriptions += [
self.props.wireProperty("secondary_mod", self.setSecondaryDemodulator),
self.props.wireProperty("digimodes_fft_size", self.chain.setSecondaryFftSize),
# TODO # TODO
# self.props.wireProperty("secondary_mod", set_secondary_mod),
# self.props.wireProperty("digimodes_fft_size", send_secondary_config),
# self.props.wireProperty("secondary_offset_freq", self.dsp.set_secondary_offset_freq), # self.props.wireProperty("secondary_offset_freq", self.dsp.set_secondary_offset_freq),
] ]
@ -353,6 +370,27 @@ class DspManager(Output, SdrSourceEventClient):
else: else:
self.wireOutput("audio", buffer) self.wireOutput("audio", buffer)
def sendSecondaryConfig(self):
self.handler.write_secondary_dsp_config(
{
"secondary_fft_size": self.props["digimodes_fft_size"],
"if_samp_rate": self.props["output_rate"],
# TODO
"secondary_bw": 31.25
}
)
def setSecondaryDemodulator(self, mod):
if not mod:
self.chain.setSecondaryFftWriter(None)
else:
buffer = Buffer(Format.CHAR)
self.chain.setSecondaryFftWriter(buffer)
self.wireOutput("secondary_fft", buffer)
self.sendSecondaryConfig()
#self.chain.setSecondaryDemodulator(mod)
def setAudioCompression(self, comp): def setAudioCompression(self, comp):
try: try:
self.chain.setAudioCompression(comp) self.chain.setAudioCompression(comp)