mirror of
https://github.com/jketterl/openwebrx.git
synced 2025-12-06 07:12:09 +01:00
preliminary work to allow dynamic audio format switching
This commit is contained in:
parent
a9f47be96d
commit
853ee5b024
|
|
@ -1,4 +1,4 @@
|
||||||
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, \
|
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, DynamicAudioRateChain, HdAudio, \
|
||||||
MetaProvider, DabServiceSelector, DialFrequencyReceiver
|
MetaProvider, DabServiceSelector, DialFrequencyReceiver
|
||||||
from csdr.module import PickleModule
|
from csdr.module import PickleModule
|
||||||
from csdreti.modules import EtiDecoder
|
from csdreti.modules import EtiDecoder
|
||||||
|
|
@ -58,8 +58,10 @@ class MetaProcessor(PickleModule):
|
||||||
self.shifter.setRate(0)
|
self.shifter.setRate(0)
|
||||||
|
|
||||||
|
|
||||||
class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, MetaProvider, DabServiceSelector, DialFrequencyReceiver):
|
class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, DynamicAudioRateChain, HdAudio, MetaProvider, DabServiceSelector, DialFrequencyReceiver):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.audioRate = 48000
|
||||||
|
|
||||||
shift = Shift(0)
|
shift = Shift(0)
|
||||||
self.decoder = EtiDecoder()
|
self.decoder = EtiDecoder()
|
||||||
|
|
||||||
|
|
@ -77,7 +79,7 @@ class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain,
|
||||||
shift,
|
shift,
|
||||||
self.decoder,
|
self.decoder,
|
||||||
self.dablin,
|
self.dablin,
|
||||||
Downmix(Format.FLOAT),
|
Downmix(Format.SHORT),
|
||||||
]
|
]
|
||||||
super().__init__(workers)
|
super().__init__(workers)
|
||||||
|
|
||||||
|
|
@ -90,8 +92,8 @@ class Dablin(BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain,
|
||||||
def getFixedIfSampleRate(self) -> int:
|
def getFixedIfSampleRate(self) -> int:
|
||||||
return 2048000
|
return 2048000
|
||||||
|
|
||||||
def getFixedAudioRate(self) -> int:
|
def getAudioRate(self) -> int:
|
||||||
return 48000
|
return self.audioRate
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.processor.stop()
|
self.processor.stop()
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ from csdr.chain import Chain
|
||||||
from abc import ABC, ABCMeta, abstractmethod
|
from abc import ABC, ABCMeta, abstractmethod
|
||||||
from pycsdr.modules import Writer
|
from pycsdr.modules import Writer
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FixedAudioRateChain(ABC):
|
class FixedAudioRateChain(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|
@ -9,6 +13,39 @@ class FixedAudioRateChain(ABC):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DynamicAudioRateListener(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def onAudioRateChange(self, rate: int):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DynamicAudioRateChain(ABC):
|
||||||
|
def __init__(self):
|
||||||
|
self.listeners = []
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def addListener(self, listener: DynamicAudioRateListener):
|
||||||
|
if listener in self.listeners:
|
||||||
|
return
|
||||||
|
self.listeners.append(listener)
|
||||||
|
|
||||||
|
def removeListener(self, listener: DynamicAudioRateListener):
|
||||||
|
if listener not in self.listeners:
|
||||||
|
return
|
||||||
|
self.listeners.remove(listener)
|
||||||
|
|
||||||
|
def fireAudioRateChange(self, rate: int):
|
||||||
|
for listener in self.listeners:
|
||||||
|
try:
|
||||||
|
listener.onAudioRateChange(rate)
|
||||||
|
except:
|
||||||
|
logger.exception("error while sending audio rate change")
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def getAudioRate(self) -> int:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FixedIfSampleRateChain(ABC):
|
class FixedIfSampleRateChain(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def getFixedIfSampleRate(self) -> int:
|
def getFixedIfSampleRate(self) -> int:
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ class DablinModule(ExecModule):
|
||||||
self.serviceId = 0
|
self.serviceId = 0
|
||||||
super().__init__(
|
super().__init__(
|
||||||
Format.CHAR,
|
Format.CHAR,
|
||||||
Format.FLOAT,
|
Format.SHORT,
|
||||||
self._buildArgs()
|
self._buildArgs()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
14
owrx/dsp.py
14
owrx/dsp.py
|
|
@ -5,7 +5,7 @@ from owrx.modes import Modes, DigitalMode
|
||||||
from csdr.chain import Chain
|
from csdr.chain import Chain
|
||||||
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, \
|
from csdr.chain.demodulator import BaseDemodulatorChain, FixedIfSampleRateChain, FixedAudioRateChain, HdAudio, \
|
||||||
SecondaryDemodulator, DialFrequencyReceiver, MetaProvider, SlotFilterChain, SecondarySelectorChain, \
|
SecondaryDemodulator, DialFrequencyReceiver, MetaProvider, SlotFilterChain, SecondarySelectorChain, \
|
||||||
DeemphasisTauChain, DemodulatorError, RdsChain, DabServiceSelector
|
DeemphasisTauChain, DemodulatorError, RdsChain, DabServiceSelector, DynamicAudioRateChain, DynamicAudioRateListener
|
||||||
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
|
||||||
|
|
@ -35,7 +35,7 @@ class ClientDemodulatorSecondaryDspEventClient(ABC):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ClientDemodulatorChain(Chain):
|
class ClientDemodulatorChain(Chain, DynamicAudioRateListener):
|
||||||
def __init__(self, demod: BaseDemodulatorChain, sampleRate: int, outputRate: int, hdOutputRate: int, audioCompression: str, secondaryDspEventReceiver: ClientDemodulatorSecondaryDspEventClient):
|
def __init__(self, demod: BaseDemodulatorChain, sampleRate: int, outputRate: int, hdOutputRate: int, audioCompression: str, secondaryDspEventReceiver: ClientDemodulatorSecondaryDspEventClient):
|
||||||
self.sampleRate = sampleRate
|
self.sampleRate = sampleRate
|
||||||
self.outputRate = outputRate
|
self.outputRate = outputRate
|
||||||
|
|
@ -101,11 +101,16 @@ class ClientDemodulatorChain(Chain):
|
||||||
|
|
||||||
if self.demodulator is not None:
|
if self.demodulator is not None:
|
||||||
self.demodulator.stop()
|
self.demodulator.stop()
|
||||||
|
if isinstance(self.demodulator, DynamicAudioRateChain):
|
||||||
|
self.demodulator.removeListener(self)
|
||||||
|
|
||||||
self.demodulator = demodulator
|
self.demodulator = demodulator
|
||||||
|
|
||||||
self.selector.setOutputRate(self._getSelectorOutputRate())
|
self.selector.setOutputRate(self._getSelectorOutputRate())
|
||||||
|
|
||||||
|
if isinstance(self.demodulator, DynamicAudioRateChain):
|
||||||
|
self.demodulator.addListener(self)
|
||||||
|
|
||||||
clientRate = self._getClientAudioInputRate()
|
clientRate = self._getClientAudioInputRate()
|
||||||
self.demodulator.setSampleRate(clientRate)
|
self.demodulator.setSampleRate(clientRate)
|
||||||
|
|
||||||
|
|
@ -155,6 +160,8 @@ class ClientDemodulatorChain(Chain):
|
||||||
def _getClientAudioInputRate(self):
|
def _getClientAudioInputRate(self):
|
||||||
if isinstance(self.demodulator, FixedAudioRateChain):
|
if isinstance(self.demodulator, FixedAudioRateChain):
|
||||||
return self.demodulator.getFixedAudioRate()
|
return self.demodulator.getFixedAudioRate()
|
||||||
|
elif isinstance(self.demodulator, DynamicAudioRateChain):
|
||||||
|
return self.demodulator.getAudioRate()
|
||||||
elif isinstance(self.secondaryDemodulator, FixedAudioRateChain):
|
elif isinstance(self.secondaryDemodulator, FixedAudioRateChain):
|
||||||
return self.secondaryDemodulator.getFixedAudioRate()
|
return self.secondaryDemodulator.getFixedAudioRate()
|
||||||
else:
|
else:
|
||||||
|
|
@ -395,6 +402,9 @@ class ClientDemodulatorChain(Chain):
|
||||||
if isinstance(self.demodulator, RdsChain):
|
if isinstance(self.demodulator, RdsChain):
|
||||||
self.demodulator.setRdsRbds(self.rdsRbds)
|
self.demodulator.setRdsRbds(self.rdsRbds)
|
||||||
|
|
||||||
|
def onAudioRateChange(self, rate: int):
|
||||||
|
self.clientAudioChain.setInputRate(self._getClientAudioInputRate())
|
||||||
|
|
||||||
|
|
||||||
class ModulationValidator(OrValidator):
|
class ModulationValidator(OrValidator):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue