introduce rtty mode

This commit is contained in:
Jakob Ketterl 2023-08-15 16:42:59 +02:00
parent c3ebb0d2c5
commit 473929ce97
4 changed files with 45 additions and 9 deletions

View File

@ -3,7 +3,7 @@ from csdr.module.msk144 import Msk144Module, ParserAdapter
from owrx.audio.chopper import AudioChopper, AudioChopperParser from owrx.audio.chopper import AudioChopper, AudioChopperParser
from owrx.aprs.kiss import KissDeframer from owrx.aprs.kiss import KissDeframer
from owrx.aprs import Ax25Parser, AprsParser from owrx.aprs import Ax25Parser, AprsParser
from pycsdr.modules import Convert, FmDemod, Agc, TimingRecovery, DBPskDecoder, VaricodeDecoder from pycsdr.modules import Convert, FmDemod, Agc, TimingRecovery, DBPskDecoder, VaricodeDecoder, RttyDecoder, BaudotDecoder
from pycsdr.types import Format from pycsdr.types import Format
from owrx.aprs.module import DirewolfModule from owrx.aprs.module import DirewolfModule
@ -83,4 +83,32 @@ class PskDemodulator(SecondaryDemodulator, SecondarySelectorChain):
return return
self.sampleRate = sampleRate self.sampleRate = sampleRate
secondary_samples_per_bits = int(round(self.sampleRate / self.baudRate)) & ~3 secondary_samples_per_bits = int(round(self.sampleRate / self.baudRate)) & ~3
self.replace(1, TimingRecovery(Format.FLOAT, secondary_samples_per_bits, 0.5, 2)) self.replace(1, TimingRecovery(Format.COMPLEX_FLOAT, secondary_samples_per_bits, 0.5, 2))
class RttyDemodulator(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))
workers = [
Agc(Format.COMPLEX_FLOAT),
FmDemod(),
TimingRecovery(Format.FLOAT, secondary_samples_per_bit, 0.5, 2),
RttyDecoder(invert),
BaudotDecoder(),
]
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))
self.replace(2, TimingRecovery(Format.FLOAT, secondary_samples_per_bit, 0.5, 2))

View File

@ -32,13 +32,13 @@ popd
rm -rf js8py rm -rf js8py
git clone https://github.com/jketterl/csdr.git git clone https://github.com/jketterl/csdr.git
# latest develop as of 2023-06-30 (csdr cleanup) # latest develop as of 2023-08-15 (rtty and baudot)
cmakebuild csdr 7e7a7f27b9fd1a65d4a9d0725583dfe6309a5245 cmakebuild csdr 8966688f748d04486560e973a599c26ed4297f34
git clone https://github.com/jketterl/pycsdr.git git clone https://github.com/jketterl/pycsdr.git
cd pycsdr cd pycsdr
# latest develop as of 2023-06-30 (csdr cleanup) # latest develop as of 2023-08-15 (rtty and baudot)
git checkout be8b0e5e0b972ebb302e7397bac0058f620ec374 git checkout 4e30b6c6a4d73ab4cf99698847c4df68e8206f73
./setup.py install install_headers ./setup.py install install_headers
cd .. cd ..
rm -rf pycsdr rm -rf pycsdr

View File

@ -600,6 +600,12 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
elif mod == "bpsk63": elif mod == "bpsk63":
from csdr.chain.digimodes import PskDemodulator from csdr.chain.digimodes import PskDemodulator
return PskDemodulator(62.5) return PskDemodulator(62.5)
elif mod == "rtty170":
from csdr.chain.digimodes import RttyDemodulator
return RttyDemodulator(45.45, 170)
elif mod == "rtty450":
from csdr.chain.digimodes import RttyDemodulator
return RttyDemodulator(50, 450, invert=True)
def setSecondaryDemodulator(self, mod): def setSecondaryDemodulator(self, mod):
demodulator = self._getSecondaryDemodulator(mod) demodulator = self._getSecondaryDemodulator(mod)

View File

@ -106,19 +106,21 @@ class Modes(object):
AnalogMode("lsb", "LSB", bandpass=Bandpass(-3000, -300)), AnalogMode("lsb", "LSB", bandpass=Bandpass(-3000, -300)),
AnalogMode("usb", "USB", bandpass=Bandpass(300, 3000)), AnalogMode("usb", "USB", bandpass=Bandpass(300, 3000)),
AnalogMode("cw", "CW", bandpass=Bandpass(700, 900)), AnalogMode("cw", "CW", bandpass=Bandpass(700, 900)),
AnalogMode("dmr", "DMR", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_digiham"], squelch=False), AnalogMode("dmr", "DMR", bandpass=Bandpass(-6250, 6250), requirements=["digital_voice_digiham"], squelch=False),
AnalogMode( AnalogMode(
"dstar", "D-Star", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_digiham"], squelch=False "dstar", "D-Star", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_digiham"], squelch=False
), ),
AnalogMode("nxdn", "NXDN", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_digiham"], squelch=False), AnalogMode("nxdn", "NXDN", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_digiham"], squelch=False),
AnalogMode("ysf", "YSF", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_digiham"], squelch=False), AnalogMode("ysf", "YSF", bandpass=Bandpass(-6250, 6250), requirements=["digital_voice_digiham"], squelch=False),
AnalogMode("m17", "M17", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_m17"], squelch=False), AnalogMode("m17", "M17", bandpass=Bandpass(-6250, 6250), requirements=["digital_voice_m17"], squelch=False),
AnalogMode( AnalogMode(
"freedv", "FreeDV", bandpass=Bandpass(300, 3000), requirements=["digital_voice_freedv"], squelch=False "freedv", "FreeDV", bandpass=Bandpass(300, 3000), requirements=["digital_voice_freedv"], squelch=False
), ),
AnalogMode("drm", "DRM", bandpass=Bandpass(-5000, 5000), requirements=["drm"], squelch=False), AnalogMode("drm", "DRM", bandpass=Bandpass(-5000, 5000), requirements=["drm"], squelch=False),
DigitalMode("bpsk31", "BPSK31", underlying=["usb"]), DigitalMode("bpsk31", "BPSK31", underlying=["usb"]),
DigitalMode("bpsk63", "BPSK63", underlying=["usb"]), DigitalMode("bpsk63", "BPSK63", underlying=["usb"]),
DigitalMode("rtty170", "RTTY 45/170", underlying=["usb", "lsb"]),
DigitalMode("rtty450", "RTTY 50N/450", underlying=["lsb", "usb"]),
WsjtMode("ft8", "FT8"), WsjtMode("ft8", "FT8"),
WsjtMode("ft4", "FT4"), WsjtMode("ft4", "FT4"),
WsjtMode("jt65", "JT65"), WsjtMode("jt65", "JT65"),