restore aprs functionality
This commit is contained in:
@ -2,68 +2,25 @@ import threading
|
||||
from owrx.source import SdrSourceEventClient, SdrSourceState, SdrClientClass
|
||||
from owrx.sdr import SdrService
|
||||
from owrx.bands import Bandplan
|
||||
from csdr.output import Output
|
||||
from owrx.wsjt import WsjtParser
|
||||
from owrx.aprs import AprsParser
|
||||
from owrx.js8 import Js8Parser
|
||||
from owrx.config import Config
|
||||
from owrx.source.resampler import Resampler
|
||||
from owrx.property import PropertyLayer, PropertyDeleted
|
||||
from js8py import Js8Frame
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from owrx.service.schedule import ServiceScheduler
|
||||
from owrx.service.chain import ServiceDemodulatorChain
|
||||
from owrx.modes import Modes, DigitalMode
|
||||
from typing import Union
|
||||
from csdr.chain.demodulator import BaseDemodulatorChain, SecondaryDemodulator, DialFrequencyReceiver
|
||||
from csdr.chain.analog import NFm, Ssb
|
||||
from csdr.chain.digimodes import AudioChopperDemodulator
|
||||
from csdr.chain.digimodes import AudioChopperDemodulator, PacketDemodulator
|
||||
from pycsdr.modules import Buffer
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ServiceOutput(Output, metaclass=ABCMeta):
|
||||
def __init__(self, frequency):
|
||||
self.frequency = frequency
|
||||
|
||||
@abstractmethod
|
||||
def getParser(self):
|
||||
# abstract method; implement in subclasses
|
||||
pass
|
||||
|
||||
def receive_output(self, t, read_fn):
|
||||
parser = self.getParser()
|
||||
parser.setDialFrequency(self.frequency)
|
||||
target = self.pump(read_fn, parser.parse)
|
||||
threading.Thread(target=target, name="service_output_receive").start()
|
||||
|
||||
|
||||
class WsjtServiceOutput(ServiceOutput):
|
||||
def getParser(self):
|
||||
return WsjtParser(WsjtHandler())
|
||||
|
||||
def supports_type(self, t):
|
||||
return t == "wsjt_demod"
|
||||
|
||||
|
||||
class AprsServiceOutput(ServiceOutput):
|
||||
def getParser(self):
|
||||
return AprsParser(AprsHandler())
|
||||
|
||||
def supports_type(self, t):
|
||||
return t == "packet_demod"
|
||||
|
||||
|
||||
class Js8ServiceOutput(ServiceOutput):
|
||||
def getParser(self):
|
||||
return Js8Parser(Js8Handler())
|
||||
|
||||
def supports_type(self, t):
|
||||
return t == "js8_demod"
|
||||
|
||||
|
||||
class ServiceHandler(SdrSourceEventClient):
|
||||
def __init__(self, source):
|
||||
self.lock = threading.RLock()
|
||||
@ -287,13 +244,6 @@ class ServiceHandler(SdrSourceEventClient):
|
||||
|
||||
def setupService(self, mode, frequency, source):
|
||||
logger.debug("setting up service {0} on frequency {1}".format(mode, frequency))
|
||||
# TODO selecting outputs will need some more intelligence here
|
||||
if mode == "packet":
|
||||
output = AprsServiceOutput(frequency)
|
||||
elif mode == "js8":
|
||||
output = Js8ServiceOutput(frequency)
|
||||
else:
|
||||
output = WsjtServiceOutput(frequency)
|
||||
|
||||
modeObject = Modes.findByModulation(mode)
|
||||
if not isinstance(modeObject, DigitalMode):
|
||||
@ -312,6 +262,10 @@ class ServiceHandler(SdrSourceEventClient):
|
||||
chain = ServiceDemodulatorChain(demod, secondaryDemod, sampleRate, shift)
|
||||
chain.setBandPass(bandpass.low_cut, bandpass.high_cut)
|
||||
chain.setReader(source.getBuffer().getReader())
|
||||
|
||||
# dummy buffer, we don't use the output right now
|
||||
buffer = Buffer(chain.getOutputFormat())
|
||||
chain.setWriter(buffer)
|
||||
return chain
|
||||
|
||||
# TODO move this elsewhere
|
||||
@ -321,7 +275,7 @@ class ServiceHandler(SdrSourceEventClient):
|
||||
# TODO: move this to Modes
|
||||
demodChain = None
|
||||
if demod == "nfm":
|
||||
demodChain = NFm(props["output_rate"])
|
||||
demodChain = NFm(48000)
|
||||
elif demod in ["usb", "lsb", "cw"]:
|
||||
demodChain = Ssb()
|
||||
|
||||
@ -334,24 +288,11 @@ class ServiceHandler(SdrSourceEventClient):
|
||||
# TODO add remaining modes
|
||||
if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]:
|
||||
return AudioChopperDemodulator(mod, WsjtParser())
|
||||
elif mod == "packet":
|
||||
return PacketDemodulator(service=True)
|
||||
return None
|
||||
|
||||
|
||||
class WsjtHandler(object):
|
||||
def write_wsjt_message(self, msg):
|
||||
pass
|
||||
|
||||
|
||||
class AprsHandler(object):
|
||||
def write_aprs_data(self, data):
|
||||
pass
|
||||
|
||||
|
||||
class Js8Handler(object):
|
||||
def write_js8_message(self, frame: Js8Frame, freq: int):
|
||||
pass
|
||||
|
||||
|
||||
class Services(object):
|
||||
handlers = {}
|
||||
schedulers = {}
|
||||
|
@ -1,6 +1,7 @@
|
||||
from csdr.chain import Chain
|
||||
from csdr.chain.selector import Selector
|
||||
from csdr.chain.demodulator import BaseDemodulatorChain, SecondaryDemodulator, FixedAudioRateChain
|
||||
from pycsdr.types import Format
|
||||
|
||||
|
||||
class ServiceDemodulatorChain(Chain):
|
||||
@ -8,13 +9,16 @@ class ServiceDemodulatorChain(Chain):
|
||||
# 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)
|
||||
self.selector = Selector(sampleRate, rate, shiftRate, withSquelch=False)
|
||||
|
||||
workers = [self.selector]
|
||||
|
||||
# primary demodulator is only necessary if the secondary does not accept IQ input
|
||||
if secondaryDemod.getInputFormat() is not Format.COMPLEX_FLOAT:
|
||||
workers += [demod]
|
||||
|
||||
workers += [secondaryDemod]
|
||||
|
||||
workers = [
|
||||
self.selector,
|
||||
demod,
|
||||
secondaryDemod
|
||||
]
|
||||
super().__init__(workers)
|
||||
|
||||
def setBandPass(self, lowCut, highCut):
|
||||
|
Reference in New Issue
Block a user