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):
|
||||
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))
|
||||
|
@ -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):
|
||||
|
@ -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
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