Adding initial DSC support.

This commit is contained in:
Marat Fayzullin 2023-12-06 23:52:34 -05:00
parent d7e0377c1e
commit 805baec3a6
3 changed files with 39 additions and 1 deletions

View File

@ -3,7 +3,7 @@ from csdr.module.msk144 import Msk144Module, ParserAdapter
from owrx.audio.chopper import AudioChopper, AudioChopperParser
from owrx.aprs.kiss import KissDeframer
from owrx.aprs import Ax25Parser, AprsParser
from pycsdr.modules import Convert, FmDemod, Agc, TimingRecovery, DBPskDecoder, VaricodeDecoder, RttyDecoder, BaudotDecoder, Lowpass, MFRttyDecoder, CwDecoder, SstvDecoder, FaxDecoder, SitorDecoder, Ccir476Decoder, Shift
from pycsdr.modules import Convert, FmDemod, Agc, TimingRecovery, DBPskDecoder, VaricodeDecoder, RttyDecoder, BaudotDecoder, Lowpass, MFRttyDecoder, CwDecoder, SstvDecoder, FaxDecoder, SitorDecoder, Ccir476Decoder, DscDecoder, Ccir493Decoder, Shift
from pycsdr.types import Format
from owrx.aprs.direwolf import DirewolfModule
from owrx.sstv import SstvParser
@ -250,3 +250,37 @@ class SitorBDemodulator(SecondaryDemodulator, SecondarySelectorChain):
loop_gain = self.sampleRate / self.getBandwidth() / 5
self.replace(2, Lowpass(Format.FLOAT, cutoff))
self.replace(3, TimingRecovery(Format.FLOAT, secondary_samples_per_bit, loop_gain, 10))
class DscDemodulator(SecondaryDemodulator, SecondarySelectorChain):
def __init__(self, baudRate, bandWidth, invert=False):
self.baudRate = baudRate
self.bandWidth = bandWidth
self.invert = invert
# this is an assumption, we will adjust in setSampleRate
self.sampleRate = 12000
secondary_samples_per_bit = int(round(self.sampleRate / self.baudRate))
cutoff = self.baudRate / self.sampleRate
loop_gain = self.sampleRate / self.getBandwidth() / 5
workers = [
Agc(Format.COMPLEX_FLOAT),
FmDemod(),
Lowpass(Format.FLOAT, cutoff),
TimingRecovery(Format.FLOAT, secondary_samples_per_bit, loop_gain, 10),
Ccir493Decoder(fec=True, invert=invert),
DscDecoder(),
]
super().__init__(workers)
def getBandwidth(self) -> float:
return self.bandWidth
def setSampleRate(self, sampleRate: int) -> None:
if sampleRate == self.sampleRate:
return
self.sampleRate = sampleRate
secondary_samples_per_bit = int(round(self.sampleRate / self.baudRate))
cutoff = self.baudRate / self.sampleRate
loop_gain = self.sampleRate / self.getBandwidth() / 5
self.replace(2, Lowpass(Format.FLOAT, cutoff))
self.replace(3, TimingRecovery(Format.FLOAT, secondary_samples_per_bit, loop_gain, 10))

View File

@ -670,6 +670,9 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
elif mod == "sitorb":
from csdr.chain.digimodes import SitorBDemodulator
return SitorBDemodulator(100, 170)
elif mod == "dsc":
from csdr.chain.digimodes import DscDemodulator
return DscDemodulator(100, 170)
elif mod == "cwdecoder":
from csdr.chain.digimodes import CwDemodulator
return CwDemodulator(75.0)

View File

@ -139,6 +139,7 @@ class Modes(object):
DigitalMode("rtty450", "RTTY-450 (50N)", underlying=["usb", "lsb"]),
DigitalMode("rtty85", "RTTY-85 (50N)", underlying=["usb", "lsb"]),
DigitalMode("sitorb", "SITOR-B", underlying=["usb"]),
DigitalMode("dsc", "DSC", underlying=["usb"]),
WsjtMode("ft8", "FT8"),
WsjtMode("ft4", "FT4"),
WsjtMode("jt65", "JT65"),