restore background services
This commit is contained in:
parent
869f971ced
commit
120328ce12
@ -74,5 +74,5 @@ class AudioChopper(threading.Thread, Chain, ProfileSourceSubscriber):
|
|||||||
|
|
||||||
def send(self, profile, line):
|
def send(self, profile, line):
|
||||||
data = self.parser.parse(profile, line)
|
data = self.parser.parse(profile, line)
|
||||||
if data is not None:
|
if data is not None and self.writer is not None:
|
||||||
self.writer.write(pickle.dumps(data))
|
self.writer.write(pickle.dumps(data))
|
||||||
|
@ -10,8 +10,8 @@ class Bandpass(object):
|
|||||||
self.high_cut = high_cut
|
self.high_cut = high_cut
|
||||||
|
|
||||||
|
|
||||||
class Mode(object):
|
class Mode:
|
||||||
def __init__(self, modulation, name, bandpass: Bandpass = None, requirements=None, service=False, squelch=True):
|
def __init__(self, modulation: str, name: str, bandpass: Bandpass = None, requirements=None, service=False, squelch=True):
|
||||||
self.modulation = modulation
|
self.modulation = modulation
|
||||||
self.name = name
|
self.name = name
|
||||||
self.requirements = requirements if requirements is not None else []
|
self.requirements = requirements if requirements is not None else []
|
||||||
@ -44,13 +44,16 @@ class DigitalMode(Mode):
|
|||||||
super().__init__(modulation, name, bandpass, requirements, service, squelch)
|
super().__init__(modulation, name, bandpass, requirements, service, squelch)
|
||||||
self.underlying = underlying
|
self.underlying = underlying
|
||||||
|
|
||||||
|
def get_underlying_mode(self):
|
||||||
|
return Modes.findByModulation(self.underlying[0])
|
||||||
|
|
||||||
def get_bandpass(self):
|
def get_bandpass(self):
|
||||||
if self.bandpass is not None:
|
if self.bandpass is not None:
|
||||||
return self.bandpass
|
return self.bandpass
|
||||||
return Modes.findByModulation(self.underlying[0]).get_bandpass()
|
return self.get_underlying_mode().get_bandpass()
|
||||||
|
|
||||||
def get_modulation(self):
|
def get_modulation(self):
|
||||||
return Modes.findByModulation(self.underlying[0]).get_modulation()
|
return self.get_underlying_mode().get_modulation()
|
||||||
|
|
||||||
|
|
||||||
class AudioChopperMode(DigitalMode, metaclass=ABCMeta):
|
class AudioChopperMode(DigitalMode, metaclass=ABCMeta):
|
||||||
|
@ -3,7 +3,6 @@ from owrx.source import SdrSourceEventClient, SdrSourceState, SdrClientClass
|
|||||||
from owrx.sdr import SdrService
|
from owrx.sdr import SdrService
|
||||||
from owrx.bands import Bandplan
|
from owrx.bands import Bandplan
|
||||||
from csdr.output import Output
|
from csdr.output import Output
|
||||||
from csdr import Dsp
|
|
||||||
from owrx.wsjt import WsjtParser
|
from owrx.wsjt import WsjtParser
|
||||||
from owrx.aprs import AprsParser
|
from owrx.aprs import AprsParser
|
||||||
from owrx.js8 import Js8Parser
|
from owrx.js8 import Js8Parser
|
||||||
@ -14,7 +13,12 @@ from owrx.property import PropertyLayer, PropertyDeleted
|
|||||||
from js8py import Js8Frame
|
from js8py import Js8Frame
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
from owrx.service.schedule import ServiceScheduler
|
from owrx.service.schedule import ServiceScheduler
|
||||||
from owrx.modes import Modes
|
from owrx.service.chain import ServiceDemodulatorChain
|
||||||
|
from owrx.modes import Modes, DigitalMode
|
||||||
|
from typing import Union
|
||||||
|
from csdr.chain.demodulator import BaseDemodulatorChain, SecondaryDemodulator, FixedAudioRateChain
|
||||||
|
from csdr.chain.analog import NFm, Ssb
|
||||||
|
from csdr.chain.digimodes import AudioChopperDemodulator
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -294,21 +298,46 @@ class ServiceHandler(SdrSourceEventClient):
|
|||||||
output = Js8ServiceOutput(frequency)
|
output = Js8ServiceOutput(frequency)
|
||||||
else:
|
else:
|
||||||
output = WsjtServiceOutput(frequency)
|
output = WsjtServiceOutput(frequency)
|
||||||
d = Dsp(output)
|
|
||||||
d.nc_port = source.getPort()
|
|
||||||
center_freq = source.getProps()["center_freq"]
|
|
||||||
d.set_offset_freq(frequency - center_freq)
|
|
||||||
d.set_center_freq(center_freq)
|
|
||||||
modeObject = Modes.findByModulation(mode)
|
modeObject = Modes.findByModulation(mode)
|
||||||
d.set_demodulator(modeObject.get_modulation())
|
if not isinstance(modeObject, DigitalMode):
|
||||||
d.set_bandpass(modeObject.get_bandpass())
|
logger.warning("mode is not a digimode: %s", mode)
|
||||||
d.set_secondary_demodulator(mode)
|
return None
|
||||||
d.set_audio_compression("none")
|
|
||||||
d.set_samp_rate(source.getProps()["samp_rate"])
|
demod = self._getDemodulator(modeObject.get_modulation(), source.getProps())
|
||||||
d.set_temporary_directory(CoreConfig().get_temporary_directory())
|
secondaryDemod = self._getSecondaryDemodulator(modeObject.modulation)
|
||||||
d.set_service()
|
center_freq = source.getProps()["center_freq"]
|
||||||
d.start()
|
sampleRate = source.getProps()["samp_rate"]
|
||||||
return d
|
shift = (center_freq - frequency) / sampleRate
|
||||||
|
bandpass = modeObject.get_bandpass()
|
||||||
|
|
||||||
|
chain = ServiceDemodulatorChain(demod, secondaryDemod, sampleRate, shift)
|
||||||
|
chain.setBandPass(bandpass.low_cut, bandpass.high_cut)
|
||||||
|
chain.setReader(source.getBuffer().getReader())
|
||||||
|
return chain
|
||||||
|
|
||||||
|
# TODO move this elsewhere
|
||||||
|
def _getDemodulator(self, demod: Union[str, BaseDemodulatorChain], props):
|
||||||
|
if isinstance(demod, BaseDemodulatorChain):
|
||||||
|
return demod
|
||||||
|
# TODO: move this to Modes
|
||||||
|
demodChain = None
|
||||||
|
if demod == "nfm":
|
||||||
|
demodChain = NFm(props["output_rate"])
|
||||||
|
elif demod in ["usb", "lsb", "cw"]:
|
||||||
|
demodChain = Ssb()
|
||||||
|
|
||||||
|
return demodChain
|
||||||
|
|
||||||
|
# TODO move this elsewhere
|
||||||
|
def _getSecondaryDemodulator(self, mod):
|
||||||
|
if isinstance(mod, SecondaryDemodulator):
|
||||||
|
return mod
|
||||||
|
# TODO add remaining modes
|
||||||
|
if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]:
|
||||||
|
return AudioChopperDemodulator(mod, WsjtParser())
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WsjtHandler(object):
|
class WsjtHandler(object):
|
||||||
|
21
owrx/service/chain.py
Normal file
21
owrx/service/chain.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from csdr.chain import Chain
|
||||||
|
from csdr.chain.selector import Selector
|
||||||
|
from csdr.chain.demodulator import BaseDemodulatorChain, SecondaryDemodulator, FixedAudioRateChain
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceDemodulatorChain(Chain):
|
||||||
|
def __init__(self, demod: BaseDemodulatorChain, secondaryDemod: SecondaryDemodulator, sampleRate: int, shiftRate: float):
|
||||||
|
# TODO magic number... check if this edge case even exsists and change the api if possible
|
||||||
|
rate = secondaryDemod.getFixedAudioRate() if isinstance(secondaryDemod, FixedAudioRateChain) else 1200
|
||||||
|
|
||||||
|
self.selector = Selector(sampleRate, rate, shiftRate)
|
||||||
|
|
||||||
|
workers = [
|
||||||
|
self.selector,
|
||||||
|
demod,
|
||||||
|
secondaryDemod
|
||||||
|
]
|
||||||
|
super().__init__(workers)
|
||||||
|
|
||||||
|
def setBandPass(self, lowCut, highCut):
|
||||||
|
self.selector.setBandpass(lowCut, highCut)
|
Loading…
Reference in New Issue
Block a user