restore background services

This commit is contained in:
Jakob Ketterl 2021-08-31 21:53:15 +02:00
parent 869f971ced
commit 120328ce12
4 changed files with 74 additions and 21 deletions

View File

@ -74,5 +74,5 @@ class AudioChopper(threading.Thread, Chain, ProfileSourceSubscriber):
def send(self, 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))

View File

@ -10,8 +10,8 @@ class Bandpass(object):
self.high_cut = high_cut
class Mode(object):
def __init__(self, modulation, name, bandpass: Bandpass = None, requirements=None, service=False, squelch=True):
class Mode:
def __init__(self, modulation: str, name: str, bandpass: Bandpass = None, requirements=None, service=False, squelch=True):
self.modulation = modulation
self.name = name
self.requirements = requirements if requirements is not None else []
@ -44,13 +44,16 @@ class DigitalMode(Mode):
super().__init__(modulation, name, bandpass, requirements, service, squelch)
self.underlying = underlying
def get_underlying_mode(self):
return Modes.findByModulation(self.underlying[0])
def get_bandpass(self):
if self.bandpass is not None:
return self.bandpass
return Modes.findByModulation(self.underlying[0]).get_bandpass()
return self.get_underlying_mode().get_bandpass()
def get_modulation(self):
return Modes.findByModulation(self.underlying[0]).get_modulation()
return self.get_underlying_mode().get_modulation()
class AudioChopperMode(DigitalMode, metaclass=ABCMeta):

View File

@ -3,7 +3,6 @@ from owrx.source import SdrSourceEventClient, SdrSourceState, SdrClientClass
from owrx.sdr import SdrService
from owrx.bands import Bandplan
from csdr.output import Output
from csdr import Dsp
from owrx.wsjt import WsjtParser
from owrx.aprs import AprsParser
from owrx.js8 import Js8Parser
@ -14,7 +13,12 @@ from owrx.property import PropertyLayer, PropertyDeleted
from js8py import Js8Frame
from abc import ABCMeta, abstractmethod
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
@ -294,21 +298,46 @@ class ServiceHandler(SdrSourceEventClient):
output = Js8ServiceOutput(frequency)
else:
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)
d.set_demodulator(modeObject.get_modulation())
d.set_bandpass(modeObject.get_bandpass())
d.set_secondary_demodulator(mode)
d.set_audio_compression("none")
d.set_samp_rate(source.getProps()["samp_rate"])
d.set_temporary_directory(CoreConfig().get_temporary_directory())
d.set_service()
d.start()
return d
if not isinstance(modeObject, DigitalMode):
logger.warning("mode is not a digimode: %s", mode)
return None
demod = self._getDemodulator(modeObject.get_modulation(), source.getProps())
secondaryDemod = self._getSecondaryDemodulator(modeObject.modulation)
center_freq = source.getProps()["center_freq"]
sampleRate = source.getProps()["samp_rate"]
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):

21
owrx/service/chain.py Normal file
View 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)