restore wfm deemphasis tau functionality

This commit is contained in:
Jakob Ketterl 2021-09-27 17:46:19 +02:00
parent edace3d451
commit 909a969e04
3 changed files with 45 additions and 17 deletions

View File

@ -1,4 +1,4 @@
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, HdAudio from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, HdAudio, DeemphasisTauChain
from pycsdr.modules import AmDemod, DcBlock, FmDemod, Limit, NfmDeemphasis, Agc, WfmDeemphasis, FractionalDecimator, RealPart from pycsdr.modules import AmDemod, DcBlock, FmDemod, Limit, NfmDeemphasis, Agc, WfmDeemphasis, FractionalDecimator, RealPart
from pycsdr.types import Format, AgcProfile from pycsdr.types import Format, AgcProfile
@ -38,19 +38,34 @@ class NFm(BaseDemodulatorChain):
self.replace(2, NfmDeemphasis(sampleRate)) self.replace(2, NfmDeemphasis(sampleRate))
class WFm(BaseDemodulatorChain, FixedIfSampleRateChain, HdAudio): class WFm(BaseDemodulatorChain, FixedIfSampleRateChain, DeemphasisTauChain, HdAudio):
def __init__(self, sampleRate: int, tau: float): def __init__(self, sampleRate: int, tau: float):
self.sampleRate = sampleRate
self.tau = tau
workers = [ workers = [
FmDemod(), FmDemod(),
Limit(), Limit(),
FractionalDecimator(Format.FLOAT, 200000.0 / sampleRate, prefilter=True), FractionalDecimator(Format.FLOAT, 200000.0 / self.sampleRate, prefilter=True),
WfmDeemphasis(sampleRate, tau), WfmDeemphasis(self.sampleRate, self.tau),
] ]
super().__init__(workers) super().__init__(workers)
def getFixedIfSampleRate(self): def getFixedIfSampleRate(self):
return 200000 return 200000
def setDeemphasisTau(self, tau: float) -> None:
if tau == self.tau:
return
self.tau = tau
self.replace(3, WfmDeemphasis(self.sampleRate, self.tau))
def setSampleRate(self, sampleRate: int) -> None:
if sampleRate == self.sampleRate:
return
self.sampleRate = sampleRate
self.replace(2, FractionalDecimator(Format.FLOAT, 200000.0 / self.sampleRate, prefilter=True))
self.replace(3, WfmDeemphasis(self.sampleRate, self.tau))
class Ssb(BaseDemodulatorChain): class Ssb(BaseDemodulatorChain):
def __init__(self): def __init__(self):

View File

@ -43,6 +43,12 @@ class SecondarySelectorChain(ABC):
pass pass
class DeemphasisTauChain(ABC):
@abstractmethod
def setDeemphasisTau(self, tau: float) -> None:
pass
class BaseDemodulatorChain(Chain): class BaseDemodulatorChain(Chain):
def supportsSquelch(self) -> bool: def supportsSquelch(self) -> bool:
return True return True

View File

@ -3,7 +3,7 @@ from owrx.property import PropertyStack, PropertyLayer, PropertyValidator
from owrx.property.validators import OrValidator, RegexValidator, BoolValidator from owrx.property.validators import OrValidator, RegexValidator, BoolValidator
from owrx.modes import Modes from owrx.modes import Modes
from csdr.chain import Chain from csdr.chain import Chain
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, SecondaryDemodulator, DialFrequencyReceiver, MetaProvider, SlotFilterChain, SecondarySelectorChain from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, SecondaryDemodulator, DialFrequencyReceiver, MetaProvider, SlotFilterChain, SecondarySelectorChain, DeemphasisTauChain
from csdr.chain.selector import Selector, SecondarySelector from csdr.chain.selector import Selector, SecondarySelector
from csdr.chain.clientaudio import ClientAudioChain from csdr.chain.clientaudio import ClientAudioChain
from csdr.chain.fft import FftChain from csdr.chain.fft import FftChain
@ -33,6 +33,7 @@ class ClientDemodulatorChain(Chain):
self.secondaryDemodulator = None self.secondaryDemodulator = None
self.centerFrequency = None self.centerFrequency = None
self.frequencyOffset = None self.frequencyOffset = None
self.wfmDeemphasisTau = 50e-6
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)
@ -106,6 +107,9 @@ class ClientDemodulatorChain(Chain):
else: else:
self.clientAudioChain.setInputRate(outputRate) self.clientAudioChain.setInputRate(outputRate)
if isinstance(self.demodulator, DeemphasisTauChain):
self.demodulator.setDeemphasisTau(self.wfmDeemphasisTau)
self._updateDialFrequency() self._updateDialFrequency()
self._syncSquelch() self._syncSquelch()
@ -227,13 +231,7 @@ class ClientDemodulatorChain(Chain):
if isinstance(self.demodulator, HdAudio): if isinstance(self.demodulator, HdAudio):
return return
if not isinstance(self.demodulator, FixedIfSampleRateChain): self._updateDemodulatorOutputRate(outputRate)
self.selector.setOutputRate(outputRate)
self.demodulator.setSampleRate(outputRate)
if self.secondaryDemodulator is not None:
self.secondaryDemodulator.setSampleRate(outputRate)
if not isinstance(self.demodulator, FixedAudioRateChain):
self.clientAudioChain.setClientRate(outputRate)
def setHdOutputRate(self, outputRate) -> None: def setHdOutputRate(self, outputRate) -> None:
if outputRate == self.hdOutputRate: if outputRate == self.hdOutputRate:
@ -243,8 +241,14 @@ class ClientDemodulatorChain(Chain):
if not isinstance(self.demodulator, HdAudio): if not isinstance(self.demodulator, HdAudio):
return return
self._updateDemodulatorOutputRate(outputRate)
def _updateDemodulatorOutputRate(self, outputRate):
if not isinstance(self.demodulator, FixedIfSampleRateChain): if not isinstance(self.demodulator, FixedIfSampleRateChain):
self.selector.setOutputRate(outputRate) self.selector.setOutputRate(outputRate)
self.demodulator.setSampleRate(outputRate)
if self.secondaryDemodulator is not None:
self.secondaryDemodulator.setSampleRate(outputRate)
if not isinstance(self.demodulator, FixedAudioRateChain): if not isinstance(self.demodulator, FixedAudioRateChain):
self.clientAudioChain.setClientRate(outputRate) self.clientAudioChain.setClientRate(outputRate)
@ -330,6 +334,13 @@ class ClientDemodulatorChain(Chain):
return Format.CHAR return Format.CHAR
return Format.SHORT return Format.SHORT
def setWfmDeemphasisTau(self, tau: float) -> None:
if tau == self.wfmDeemphasisTau:
return
self.wfmDeemphasisTau = tau
if isinstance(self.demodulator, DeemphasisTauChain):
self.demodulator.setDeemphasisTau(self.wfmDeemphasisTau)
class ModulationValidator(OrValidator): class ModulationValidator(OrValidator):
""" """
@ -433,13 +444,9 @@ class DspManager(SdrSourceEventClient):
self.props.wireProperty("high_cut", self.chain.setHighCut), self.props.wireProperty("high_cut", self.chain.setHighCut),
self.props.wireProperty("mod", self.setDemodulator), self.props.wireProperty("mod", self.setDemodulator),
self.props.wireProperty("dmr_filter", self.chain.setSlotFilter), self.props.wireProperty("dmr_filter", self.chain.setSlotFilter),
# TODO self.props.wireProperty("wfm_deemphasis_tau", self.chain.setWfmDeemphasisTau),
# self.props.wireProperty("wfm_deemphasis_tau", self.dsp.set_wfm_deemphasis_tau),
] ]
# TODO
# sp.set_temporary_directory(CoreConfig().get_temporary_directory())
def set_secondary_mod(mod): def set_secondary_mod(mod):
if mod == False: if mod == False:
mod = None mod = None