restore aprs functionality

This commit is contained in:
Jakob Ketterl
2021-09-06 15:05:33 +02:00
parent 7c43c78c4b
commit b9f43654cd
18 changed files with 390 additions and 190 deletions

View File

@ -15,7 +15,7 @@ from csdr.chain.clientaudio import ClientAudioChain
from csdr.chain.analog import NFm, WFm, Am, Ssb
from csdr.chain.digiham import DigihamChain, Dmr, Dstar, Nxdn, Ysf
from csdr.chain.fft import FftChain
from csdr.chain.digimodes import AudioChopperDemodulator
from csdr.chain.digimodes import AudioChopperDemodulator, PacketDemodulator
from pycsdr.modules import Buffer, Writer
from pycsdr.types import Format
from typing import Union
@ -66,7 +66,7 @@ class ClientDemodulatorChain(Chain):
format = w1.getOutputFormat()
if self.audioBuffer is None or self.audioBuffer.getFormat() != format:
self.audioBuffer = Buffer(format)
if self.secondaryDemodulator is not None:
if self.secondaryDemodulator is not None and self.secondaryDemodulator.getInputFormat() is not Format.COMPLEX_FLOAT:
self.secondaryDemodulator.setReader(self.audioBuffer.getReader())
super()._connect(w1, w2, self.audioBuffer)
else:
@ -94,28 +94,33 @@ class ClientDemodulatorChain(Chain):
if isinstance(self.demodulator, FixedIfSampleRateChain):
self.selector.setOutputRate(self.demodulator.getFixedIfSampleRate())
elif self.secondaryDemodulator is not None and isinstance(self.secondaryDemodulator, FixedAudioRateChain):
elif isinstance(self.secondaryDemodulator, FixedAudioRateChain):
self.selector.setOutputRate(self.secondaryDemodulator.getFixedAudioRate())
else:
self.selector.setOutputRate(outputRate)
self.demodulator.setSampleRate(outputRate)
if isinstance(self.demodulator, FixedAudioRateChain):
self.clientAudioChain.setInputRate(self.demodulator.getFixedAudioRate())
elif self.secondaryDemodulator is not None and isinstance(self.secondaryDemodulator, FixedAudioRateChain):
elif isinstance(self.secondaryDemodulator, FixedAudioRateChain):
self.clientAudioChain.setInputRate(self.secondaryDemodulator.getFixedAudioRate())
else:
self.clientAudioChain.setInputRate(outputRate)
if not demodulator.supportsSquelch():
self.selector.setSquelchLevel(-150)
else:
self.selector.setSquelchLevel(self.squelchLevel)
self._syncSquelch()
self.clientAudioChain.setClientRate(outputRate)
if self.metaWriter is not None and isinstance(demodulator, DigihamChain):
demodulator.setMetaWriter(self.metaWriter)
def _getSelectorOutputRate(self):
if isinstance(self.secondaryDemodulator, FixedAudioRateChain):
if isinstance(self.demodulator, FixedAudioRateChain) and self.demodulator.getFixedAudioRate() != self.secondaryDemodulator.getFixedAudioRate():
raise ValueError("secondary and primary demodulator chain audio rates do not match!")
return self.secondaryDemodulator.getFixedAudioRate()
return self.outputRate
def setSecondaryDemodulator(self, demod: Union[SecondaryDemodulator, None]):
if demod is self.secondaryDemodulator:
return
@ -125,19 +130,18 @@ class ClientDemodulatorChain(Chain):
self.secondaryDemodulator = demod
if self.secondaryDemodulator is not None and isinstance(self.secondaryDemodulator, FixedAudioRateChain):
if isinstance(self.demodulator, FixedAudioRateChain) and self.demodulator.getFixedAudioRate() != self.secondaryDemodulator.getFixedAudioRate():
raise ValueError("secondary and primary demodulator chain audio rates do not match!")
else:
rate = self.secondaryDemodulator.getFixedAudioRate()
else:
rate = self.outputRate
rate = self._getSelectorOutputRate()
self.selector.setOutputRate(rate)
self.clientAudioChain.setInputRate(rate)
self.demodulator.setSampleRate(rate)
self._updateDialFrequency()
self._syncSquelch()
if self.secondaryDemodulator is not None:
self.secondaryDemodulator.setReader(self.audioBuffer.getReader())
if self.secondaryDemodulator.getInputFormat() is Format.COMPLEX_FLOAT:
self.secondaryDemodulator.setReader(self.selectorBuffer.getReader())
else:
self.secondaryDemodulator.setReader(self.audioBuffer.getReader())
self.secondaryDemodulator.setWriter(self.secondaryWriter)
if self.secondaryDemodulator is None and self.secondaryFftChain is not None:
@ -146,10 +150,19 @@ class ClientDemodulatorChain(Chain):
if self.secondaryDemodulator is not None and self.secondaryFftChain is None:
# TODO eliminate constants
self.secondaryFftChain = FftChain(self.outputRate, 2048, 0.3, 9, "adpcm")
self.secondaryFftChain = FftChain(self._getSelectorOutputRate(), 2048, 0.3, 9, "adpcm")
self.secondaryFftChain.setReader(self.selectorBuffer.getReader())
self.secondaryFftChain.setWriter(self.secondaryFftWriter)
if self.secondaryFftChain is not None:
self.secondaryFftChain.setSampleRate(rate)
def _syncSquelch(self):
if not self.demodulator.supportsSquelch() or (self.secondaryDemodulator is not None and not self.secondaryDemodulator.supportsSquelch()):
self.selector.setSquelchLevel(-150)
else:
self.selector.setSquelchLevel(self.squelchLevel)
def setLowCut(self, lowCut):
self.selector.setLowCut(lowCut)
@ -189,9 +202,7 @@ class ClientDemodulatorChain(Chain):
if level == self.squelchLevel:
return
self.squelchLevel = level
if not self.demodulator.supportsSquelch():
return
self.selector.setSquelchLevel(level)
self._syncSquelch()
def setOutputRate(self, outputRate) -> None:
if outputRate == self.outputRate:
@ -203,6 +214,7 @@ class ClientDemodulatorChain(Chain):
return
if not isinstance(self.demodulator, FixedIfSampleRateChain):
self.selector.setOutputRate(outputRate)
self.demodulator.setSampleRate(outputRate)
if not isinstance(self.demodulator, FixedAudioRateChain):
self.clientAudioChain.setClientRate(outputRate)
@ -271,7 +283,6 @@ class DspManager(Output, SdrSourceEventClient):
self.sdrSource = sdrSource
self.parsers = {
"meta": MetaParser(self.handler),
"packet_demod": AprsParser(self.handler),
"pocsag_demod": PocsagParser(self.handler),
"js8_demod": Js8Parser(self.handler),
}
@ -354,7 +365,7 @@ class DspManager(Output, SdrSourceEventClient):
buffer = Buffer(Format.CHAR)
self.chain.setSecondaryWriter(buffer)
# TODO there's multiple outputs depending on the modulation right now
self.wireOutput("wsjt_demod", buffer)
self.wireOutput("secondary_demod", buffer)
def set_dial_freq(changes):
if (
@ -481,6 +492,8 @@ class DspManager(Output, SdrSourceEventClient):
# TODO add remaining modes
if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]:
return AudioChopperDemodulator(mod, WsjtParser())
elif mod == "packet":
return PacketDemodulator()
return None
def setSecondaryDemodulator(self, mod):
@ -520,7 +533,6 @@ class DspManager(Output, SdrSourceEventClient):
"smeter": self.handler.write_s_meter_level,
"secondary_fft": self.handler.write_secondary_fft,
"secondary_demod": self.handler.write_secondary_demod,
"wsjt_demod": self.handler.write_wsjt_message,
}
for demod, parser in self.parsers.items():
writers[demod] = parser.parse