fix hd audio

This commit is contained in:
Jakob Ketterl 2021-08-27 18:30:46 +02:00
parent 4c1777dc19
commit 54a1cae352

View File

@ -9,7 +9,7 @@ from owrx.property.validators import OrValidator, RegexValidator, BoolValidator
from owrx.modes import Modes from owrx.modes import Modes
from csdr.output import Output from csdr.output import Output
from csdr.chain import Chain from csdr.chain import Chain
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio
from csdr.chain.selector import Selector 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
@ -26,13 +26,16 @@ logger = logging.getLogger(__name__)
class ClientDemodulatorChain(Chain): class ClientDemodulatorChain(Chain):
def __init__(self, demod: BaseDemodulatorChain, sampleRate: int, outputRate: int, audioCompression: str): def __init__(self, demod: BaseDemodulatorChain, sampleRate: int, outputRate: int, hdOutputRate: int, audioCompression: str):
self.sampleRate = sampleRate self.sampleRate = sampleRate
self.outputRate = outputRate self.outputRate = outputRate
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.demodulator = demod self.demodulator = demod
self.clientAudioChain = ClientAudioChain(demod.getOutputFormat(), outputRate, outputRate, audioCompression) inputRate = demod.getFixedAudioRate() if isinstance(demod, FixedAudioRateChain) else outputRate
oRate = hdOutputRate if isinstance(demod, HdAudio) else outputRate
self.clientAudioChain = ClientAudioChain(demod.getOutputFormat(), inputRate, oRate, audioCompression)
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])
@ -52,21 +55,25 @@ class ClientDemodulatorChain(Chain):
self.demodulator = demodulator self.demodulator = demodulator
outputRate = self.hdOutputRate if isinstance(self.demodulator, HdAudio) else self.outputRate
if isinstance(self.demodulator, FixedIfSampleRateChain): if isinstance(self.demodulator, FixedIfSampleRateChain):
self.selector.setOutputRate(self.demodulator.getFixedIfSampleRate()) self.selector.setOutputRate(self.demodulator.getFixedIfSampleRate())
else: else:
self.selector.setOutputRate(self.outputRate) self.selector.setOutputRate(outputRate)
if isinstance(self.demodulator, FixedAudioRateChain): if isinstance(self.demodulator, FixedAudioRateChain):
self.clientAudioChain.setInputRate(self.demodulator.getFixedAudioRate()) self.clientAudioChain.setInputRate(self.demodulator.getFixedAudioRate())
else: else:
self.clientAudioChain.setInputRate(self.outputRate) self.clientAudioChain.setInputRate(outputRate)
if not demodulator.supportsSquelch(): if not demodulator.supportsSquelch():
self.selector.setSquelchLevel(-150) self.selector.setSquelchLevel(-150)
else: else:
self.selector.setSquelchLevel(self.squelchLevel) self.selector.setSquelchLevel(self.squelchLevel)
self.clientAudioChain.setClientRate(outputRate)
if self.metaWriter is not None and isinstance(demodulator, DigihamChain): if self.metaWriter is not None and isinstance(demodulator, DigihamChain):
demodulator.setMetaWriter(self.metaWriter) demodulator.setMetaWriter(self.metaWriter)
@ -99,6 +106,22 @@ class ClientDemodulatorChain(Chain):
return return
self.outputRate = outputRate self.outputRate = outputRate
if isinstance(self.demodulator, HdAudio):
return
if not isinstance(self.demodulator, FixedIfSampleRateChain):
self.selector.setOutputRate(outputRate)
if not isinstance(self.demodulator, FixedAudioRateChain):
self.clientAudioChain.setClientRate(outputRate)
def setHdOutputRate(self, outputRate) -> None:
if outputRate == self.hdOutputRate:
return
self.hdOutputRate = outputRate
if not isinstance(self.demodulator, HdAudio):
return
if not isinstance(self.demodulator, FixedIfSampleRateChain): if not isinstance(self.demodulator, FixedIfSampleRateChain):
self.selector.setOutputRate(outputRate) self.selector.setOutputRate(outputRate)
if not isinstance(self.demodulator, FixedAudioRateChain): if not isinstance(self.demodulator, FixedAudioRateChain):
@ -181,11 +204,14 @@ class DspManager(Output, SdrSourceEventClient):
# TODO wait for the rate to come from the client # TODO wait for the rate to come from the client
if "output_rate" not in self.props: if "output_rate" not in self.props:
self.props["output_rate"] = 12000 self.props["output_rate"] = 12000
if "hd_output_rate" not in self.props:
self.props["hd_output_rate"] = 48000
self.chain = ClientDemodulatorChain( self.chain = ClientDemodulatorChain(
self._getDemodulator("nfm"), self._getDemodulator("nfm"),
self.props["samp_rate"], self.props["samp_rate"],
self.props["output_rate"], self.props["output_rate"],
self.props["hd_output_rate"],
self.props["audio_compression"] self.props["audio_compression"]
) )
@ -194,6 +220,7 @@ class DspManager(Output, SdrSourceEventClient):
# wire audio output # wire audio output
buffer = Buffer(self.chain.getOutputFormat()) buffer = Buffer(self.chain.getOutputFormat())
self.chain.setWriter(buffer) self.chain.setWriter(buffer)
# TODO check for hd audio
self.wireOutput("audio", buffer) self.wireOutput("audio", buffer)
# wire power level output # wire power level output
@ -239,8 +266,7 @@ class DspManager(Output, SdrSourceEventClient):
# self.props.wireProperty("digimodes_fft_size", self.dsp.set_secondary_fft_size), # 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),
# TODO self.props.wireProperty("hd_output_rate", self.chain.setHdOutputRate),
# self.props.wireProperty("hd_output_rate", self.dsp.set_hd_output_rate),
self.props.wireProperty("offset_freq", self.chain.setFrequencyOffset), self.props.wireProperty("offset_freq", self.chain.setFrequencyOffset),
# TODO check, this was used for wsjt-x # TODO check, this was used for wsjt-x
# self.props.wireProperty("center_freq", self.dsp.set_center_freq), # self.props.wireProperty("center_freq", self.dsp.set_center_freq),
@ -297,7 +323,7 @@ class DspManager(Output, SdrSourceEventClient):
if demod == "nfm": if demod == "nfm":
demodChain = NFm(self.props["output_rate"]) demodChain = NFm(self.props["output_rate"])
elif demod == "wfm": elif demod == "wfm":
demodChain = WFm(self.props["output_rate"], self.props["wfm_deemphasis_tau"]) demodChain = WFm(self.props["hd_output_rate"], self.props["wfm_deemphasis_tau"])
elif demod == "am": elif demod == "am":
demodChain = Am() demodChain = Am()
elif demod in ["usb", "lsb", "cw"]: elif demod in ["usb", "lsb", "cw"]:
@ -319,6 +345,14 @@ class DspManager(Output, SdrSourceEventClient):
raise ValueError("unsupported demodulator: {}".format(mod)) raise ValueError("unsupported demodulator: {}".format(mod))
self.chain.setDemodulator(demodulator) self.chain.setDemodulator(demodulator)
# re-wire the audio to the correct client API
buffer = Buffer(self.chain.getOutputFormat())
self.chain.setWriter(buffer)
if isinstance(demodulator, HdAudio):
self.wireOutput("hd_audio", buffer)
else:
self.wireOutput("audio", buffer)
def setAudioCompression(self, comp): def setAudioCompression(self, comp):
try: try:
self.chain.setAudioCompression(comp) self.chain.setAudioCompression(comp)
@ -326,6 +360,7 @@ class DspManager(Output, SdrSourceEventClient):
# wrong output format... need to re-wire # wrong output format... need to re-wire
buffer = Buffer(self.chain.getOutputFormat()) buffer = Buffer(self.chain.getOutputFormat())
self.chain.setWriter(buffer) self.chain.setWriter(buffer)
# TODO check if this is hd audio
self.wireOutput("audio", buffer) self.wireOutput("audio", buffer)
def start(self): def start(self):
@ -334,6 +369,11 @@ class DspManager(Output, SdrSourceEventClient):
else: else:
self.startOnAvailable = True self.startOnAvailable = True
def unwireOutput(self, t: str):
if t in self.readers:
self.readers[t].stop()
del self.readers[t]
def wireOutput(self, t: str, buffer: Buffer): def wireOutput(self, t: str, buffer: Buffer):
logger.debug("wiring new output of type %s", t) logger.debug("wiring new output of type %s", t)
writers = { writers = {
@ -348,8 +388,7 @@ class DspManager(Output, SdrSourceEventClient):
write = writers[t] write = writers[t]
if t in self.readers: self.unwireOutput(t)
self.readers[t].stop()
reader = buffer.getReader() reader = buffer.getReader()
self.readers[t] = reader self.readers[t] = reader