move wsjt/js8 decisions out of csdr

This commit is contained in:
Jakob Ketterl
2021-04-09 18:16:25 +02:00
parent 22ec80c8ea
commit bbad34cec3
10 changed files with 135 additions and 95 deletions

View File

@ -10,7 +10,6 @@ from multiprocessing.connection import Pipe, wait
from datetime import datetime, timedelta
from queue import Queue, Full, Empty
import logging
logger = logging.getLogger(__name__)
@ -169,9 +168,8 @@ class AudioChopperProfile(ABC):
class AudioWriter(object):
def __init__(self, dsp, source, profile: AudioChopperProfile):
self.dsp = dsp
self.source = source
def __init__(self, active_dsp: "csdr.csdr.Dsp", profile: AudioChopperProfile):
self.dsp = active_dsp
self.profile = profile
self.tmp_dir = CoreConfig().get_temporary_directory()
self.wavefile = None
@ -289,9 +287,9 @@ class AudioWriter(object):
class AudioChopper(threading.Thread, metaclass=ABCMeta):
def __init__(self, dsp, source, *profiles: AudioChopperProfile):
self.source = source
self.writers = [AudioWriter(dsp, source, p) for p in profiles]
def __init__(self, active_dsp: "csdr.csdr.Dsp", readfn: callable, *profiles: AudioChopperProfile):
self.readfn = readfn
self.writers = [AudioWriter(active_dsp, p) for p in profiles]
self.doRun = True
super().__init__()
@ -302,7 +300,7 @@ class AudioChopper(threading.Thread, metaclass=ABCMeta):
while self.doRun:
data = None
try:
data = self.source.read(256)
data = self.readfn(256)
except ValueError:
pass
if data is None or (isinstance(data, bytes) and len(data) == 0):

22
owrx/audio/handler.py Normal file
View File

@ -0,0 +1,22 @@
from owrx.modes import Modes, AudioChopperMode
from csdr.output import Output
from owrx.audio import AudioChopper
class AudioHandler(Output):
def __init__(self, active_dsp: "csdr.csdr.Dsp", mode: str):
self.dsp = active_dsp
self.mode = Modes.findByModulation(mode)
if mode is None or not isinstance(self.mode, AudioChopperMode):
raise ValueError("Mode {} is not an audio chopper mode".format(mode))
self.chopper = None
def supports_type(self, t):
return t == "audio"
def receive_output(self, t, read_fn):
self.chopper = AudioChopper(self.dsp, read_fn, *self.mode.getProfiles())
self.chopper.start()
def read(self, *args, **kwargs):
return self.chopper.read(*args, **kwargs)

View File

@ -8,7 +8,8 @@ from owrx.property import PropertyStack, PropertyLayer, PropertyValidator
from owrx.property.validators import OrValidator, RegexValidator, BoolValidator
from owrx.modes import Modes
from owrx.config.core import CoreConfig
from csdr import csdr
from csdr.output import Output
from csdr import Dsp
import threading
import re
@ -26,7 +27,7 @@ class ModulationValidator(OrValidator):
super().__init__(BoolValidator(), RegexValidator(re.compile("^[a-z0-9]+$")))
class DspManager(csdr.output, SdrSourceEventClient):
class DspManager(Output, SdrSourceEventClient):
def __init__(self, handler, sdrSource):
self.handler = handler
self.sdrSource = sdrSource
@ -75,7 +76,7 @@ class DspManager(csdr.output, SdrSourceEventClient):
),
)
self.dsp = csdr.dsp(self)
self.dsp = Dsp(self)
self.dsp.nc_port = self.sdrSource.getPort()
def set_low_cut(cut):

View File

@ -1,6 +1,7 @@
from owrx.config.core import CoreConfig
from owrx.config import Config
from csdr import csdr
import csdr
from csdr.output import Output
import threading
from owrx.source import SdrSourceEventClient, SdrSourceState, SdrClientClass
from owrx.property import PropertyStack
@ -10,7 +11,7 @@ import logging
logger = logging.getLogger(__name__)
class SpectrumThread(csdr.output, SdrSourceEventClient):
class SpectrumThread(Output, SdrSourceEventClient):
def __init__(self, sdrSource):
self.sdrSource = sdrSource
super().__init__()
@ -26,7 +27,7 @@ class SpectrumThread(csdr.output, SdrSourceEventClient):
"fft_compression",
)
self.dsp = dsp = csdr.dsp(self)
self.dsp = dsp = csdr.Dsp(self)
dsp.nc_port = self.sdrSource.getPort()
dsp.set_demodulator("fft")

View File

@ -1,5 +1,6 @@
from owrx.feature import FeatureDetector
from functools import reduce
from abc import ABCMeta, abstractmethod
class Bandpass(object):
@ -51,13 +52,39 @@ class DigitalMode(Mode):
return Modes.findByModulation(self.underlying[0]).get_modulation()
class WsjtMode(DigitalMode):
class AudioChopperMode(DigitalMode, metaclass=ABCMeta):
def __init__(self, modulation, name, bandpass=None, requirements=None):
if bandpass is None:
bandpass = Bandpass(0, 3000)
super().__init__(modulation, name, ["usb"], bandpass=bandpass, requirements=requirements, service=True)
@abstractmethod
def getProfiles(self):
pass
class WsjtMode(AudioChopperMode):
def __init__(self, modulation, name, bandpass=None, requirements=None):
if requirements is None:
requirements = ["wsjt-x"]
super().__init__(modulation, name, ["usb"], bandpass=bandpass, requirements=requirements, service=True)
super().__init__(modulation, name, bandpass=bandpass, requirements=requirements)
def getProfiles(self):
# inline import due to circular dependencies
from owrx.wsjt import WsjtProfile
return WsjtProfile.getProfiles(self.modulation)
class Js8Mode(AudioChopperMode):
def __init__(self, modulation, name, bandpass=None, requirements=None):
if requirements is None:
requirements = ["js8call"]
super().__init__(modulation, name, bandpass, requirements)
def getProfiles(self):
# inline import due to circular dependencies
from owrx.js8 import Js8Profiles
return Js8Profiles.getEnabledProfiles()
class Modes(object):
@ -89,9 +116,7 @@ class Modes(object):
WsjtMode("fst4", "FST4", requirements=["wsjt-x-2-3"]),
WsjtMode("fst4w", "FST4W", bandpass=Bandpass(1350, 1650), requirements=["wsjt-x-2-3"]),
WsjtMode("q65", "Q65", requirements=["wsjt-x-2-4"]),
DigitalMode(
"js8", "JS8Call", underlying=["usb"], bandpass=Bandpass(0, 3000), requirements=["js8call"], service=True
),
Js8Mode("js8", "JS8Call"),
DigitalMode(
"packet",
"Packet",

View File

@ -2,7 +2,8 @@ import threading
from owrx.source import SdrSourceEventClient, SdrSourceState, SdrClientClass
from owrx.sdr import SdrService
from owrx.bands import Bandplan
from csdr.csdr import dsp, output
from csdr.output import Output
from csdr import Dsp
from owrx.wsjt import WsjtParser
from owrx.aprs import AprsParser
from owrx.js8 import Js8Parser
@ -20,7 +21,7 @@ import logging
logger = logging.getLogger(__name__)
class ServiceOutput(output, metaclass=ABCMeta):
class ServiceOutput(Output, metaclass=ABCMeta):
def __init__(self, frequency):
self.frequency = frequency
@ -286,7 +287,7 @@ class ServiceHandler(SdrSourceEventClient):
output = Js8ServiceOutput(frequency)
else:
output = WsjtServiceOutput(frequency)
d = dsp(output)
d = Dsp(output)
d.nc_port = source.getPort()
center_freq = source.getProps()["center_freq"]
d.set_offset_freq(frequency - center_freq)

View File

@ -39,6 +39,25 @@ class WsjtProfile(AudioChopperProfile, metaclass=ABCMeta):
def getMode(self):
pass
@staticmethod
def getProfiles(mode: str):
if mode == "ft8":
return [Ft8Profile()]
elif mode == "wspr":
return [WsprProfile()]
elif mode == "jt65":
return [Jt65Profile()]
elif mode == "jt9":
return [Jt9Profile()]
elif mode == "ft4":
return [Ft4Profile()]
elif mode == "fst4":
return Fst4Profile.getEnabledProfiles()
elif mode == "fst4w":
return Fst4wProfile.getEnabledProfiles()
elif mode == "q65":
return Q65Profile.getEnabledProfiles()
class Ft8Profile(WsjtProfile):
def getInterval(self):