Porting MSK144 decoder from the OWRX 'develop' branch.
This commit is contained in:
parent
50c288dfaf
commit
b500367e9a
12
bands.json
12
bands.json
|
|
@ -192,7 +192,8 @@
|
|||
"jt9": 50312000,
|
||||
"ft4": 50318000,
|
||||
"js8": 50318000,
|
||||
"q65": [50211000, 50275000]
|
||||
"q65": [50211000, 50275000],
|
||||
"msk144": 50260000
|
||||
},
|
||||
"tags": ["hamradio"]
|
||||
},
|
||||
|
|
@ -201,7 +202,8 @@
|
|||
"lower_bound": 70150000,
|
||||
"upper_bound": 70200000,
|
||||
"frequencies": {
|
||||
"wspr": 70091000
|
||||
"wspr": 70091000,
|
||||
"msk144": 70230000
|
||||
},
|
||||
"tags": ["hamradio"]
|
||||
},
|
||||
|
|
@ -215,7 +217,8 @@
|
|||
"ft4": 144170000,
|
||||
"jt65": 144120000,
|
||||
"packet": [144800000, 145825000],
|
||||
"q65": 144116000
|
||||
"q65": 144116000,
|
||||
"msk144": 144360000
|
||||
},
|
||||
"tags": ["hamradio"]
|
||||
},
|
||||
|
|
@ -225,7 +228,8 @@
|
|||
"upper_bound": 440000000,
|
||||
"frequencies": {
|
||||
"pocsag": 439987500,
|
||||
"q65": 432065000
|
||||
"q65": 432065000,
|
||||
"msk144": 432360000
|
||||
},
|
||||
"tags": ["hamradio"]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from csdr.chain.demodulator import ServiceDemodulator, SecondaryDemodulator, DialFrequencyReceiver, SecondarySelectorChain
|
||||
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
|
||||
|
|
@ -21,6 +22,23 @@ class AudioChopperDemodulator(ServiceDemodulator, DialFrequencyReceiver):
|
|||
self.chopper.setDialFrequency(frequency)
|
||||
|
||||
|
||||
class Msk144Demodulator(ServiceDemodulator, DialFrequencyReceiver):
|
||||
def __init__(self):
|
||||
self.parser = ParserAdapter()
|
||||
workers = [
|
||||
Convert(Format.FLOAT, Format.SHORT),
|
||||
Msk144Module(),
|
||||
self.parser,
|
||||
]
|
||||
super().__init__(workers)
|
||||
|
||||
def getFixedAudioRate(self) -> int:
|
||||
return 12000
|
||||
|
||||
def setDialFrequency(self, frequency: int) -> None:
|
||||
self.parser.setDialFrequency(frequency)
|
||||
|
||||
|
||||
class PacketDemodulator(ServiceDemodulator, DialFrequencyReceiver):
|
||||
def __init__(self, service: bool = False, ais: bool = False):
|
||||
self.parser = AprsParser()
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ Vcs-Git: https://github.com/luarvique/openwebrx.git
|
|||
Package: openwebrx
|
||||
Architecture: all
|
||||
Depends: adduser, python3 (>= 3.5), python3-pkg-resources, owrx-connector (>= 0.6), soapysdr-tools, python3-csdr (>= 0.18.9), ${python3:Depends}, ${misc:Depends}
|
||||
Recommends: python3-digiham (>= 0.6), direwolf (>= 1.4), wsjtx, js8call, runds-connector (>= 0.2), hpsdrconnector, aprs-symbols, m17-demod, js8call, python3-js8py (>= 0.1), nmux (>= 0.18), codecserver (>= 0.1)
|
||||
Recommends: python3-digiham (>= 0.6), direwolf (>= 1.4), wsjtx, js8call, runds-connector (>= 0.2), hpsdrconnector, aprs-symbols, m17-demod, js8call, python3-js8py (>= 0.1), nmux (>= 0.18), codecserver (>= 0.1), msk144decoder
|
||||
Description: multi-user web sdr
|
||||
Open source, multi-user SDR receiver with a web interface
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ mv /wsjtx.patch ${WSJT_DIR}
|
|||
cmakebuild ${WSJT_DIR}
|
||||
rm ${WSJT_TGZ}
|
||||
|
||||
git clone https://github.com/alexander-sholohov/msk144decoder.git
|
||||
# latest from main as of 2023-02-21
|
||||
MAKEFLAGS="" cmakebuild msk144decoder fe2991681e455636e258e83c29fd4b2a72d16095
|
||||
|
||||
git clone --depth 1 -b 1.6 https://github.com/wb2osz/direwolf.git
|
||||
cd direwolf
|
||||
# hamlib is present (necessary for the wsjt-x and js8call builds) and would be used, but there's no real need.
|
||||
|
|
|
|||
|
|
@ -1331,6 +1331,7 @@ img.openwebrx-mirror-img
|
|||
#openwebrx-panel-digimodes[data-mode="fst4"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="fst4w"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="q65"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="sstv"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="fax"] #openwebrx-digimode-content-container,
|
||||
#openwebrx-panel-digimodes[data-mode="ft8"] #openwebrx-digimode-select-channel,
|
||||
|
|
@ -1345,6 +1346,7 @@ img.openwebrx-mirror-img
|
|||
#openwebrx-panel-digimodes[data-mode="fst4"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="fst4w"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="q65"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="sstv"] #openwebrx-digimode-select-channel,
|
||||
#openwebrx-panel-digimodes[data-mode="fax"] #openwebrx-digimode-select-channel
|
||||
{
|
||||
|
|
@ -1363,6 +1365,7 @@ img.openwebrx-mirror-img
|
|||
#openwebrx-panel-digimodes[data-mode="fst4"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="fst4w"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="q65"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="msk144"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="sstv"] #openwebrx-digimode-canvas-container,
|
||||
#openwebrx-panel-digimodes[data-mode="fax"] #openwebrx-digimode-canvas-container
|
||||
{
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ DemodulatorPanel.prototype.updatePanels = function() {
|
|||
var modulation = this.getDemodulator().get_secondary_demod();
|
||||
$('#openwebrx-panel-digimodes').attr('data-mode', modulation);
|
||||
toggle_panel("openwebrx-panel-digimodes", !!modulation);
|
||||
toggle_panel("openwebrx-panel-wsjt-message", ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"].indexOf(modulation) >= 0);
|
||||
toggle_panel("openwebrx-panel-wsjt-message", ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65", "msk144"].indexOf(modulation) >= 0);
|
||||
toggle_panel("openwebrx-panel-js8-message", modulation == "js8");
|
||||
toggle_panel("openwebrx-panel-packet-message", ["packet", "ais"].indexOf(modulation) >= 0);
|
||||
toggle_panel("openwebrx-panel-pocsag-message", modulation === "pocsag");
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ MessagePanel.prototype.initClearButton = function() {
|
|||
function WsjtMessagePanel(el) {
|
||||
MessagePanel.call(this, el);
|
||||
this.initClearTimer();
|
||||
this.qsoModes = ['FT8', 'JT65', 'JT9', 'FT4', 'FST4', 'Q65'];
|
||||
this.qsoModes = ['FT8', 'JT65', 'JT9', 'FT4', 'FST4', 'Q65', 'MSK144'];
|
||||
this.beaconModes = ['WSPR', 'FST4W'];
|
||||
this.modes = [].concat(this.qsoModes, this.beaconModes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -600,6 +600,9 @@ class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient)
|
|||
from csdr.chain.digimodes import AudioChopperDemodulator
|
||||
from owrx.wsjt import WsjtParser
|
||||
return AudioChopperDemodulator(mod, WsjtParser())
|
||||
elif mod == "msk144":
|
||||
from csdr.chain.digimodes import Msk144Demodulator
|
||||
return Msk144Demodulator()
|
||||
elif mod == "js8":
|
||||
from csdr.chain.digimodes import AudioChopperDemodulator
|
||||
from owrx.js8 import Js8Parser
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ class FeatureDetector(object):
|
|||
"wsjt-x": ["wsjtx"],
|
||||
"wsjt-x-2-3": ["wsjtx_2_3"],
|
||||
"wsjt-x-2-4": ["wsjtx_2_4"],
|
||||
"msk144": ["msk144decoder"],
|
||||
"packet": ["direwolf"],
|
||||
"pocsag": ["digiham"],
|
||||
"js8call": ["js8", "js8py"],
|
||||
|
|
@ -460,6 +461,13 @@ class FeatureDetector(object):
|
|||
"""
|
||||
return self.has_wsjtx() and self._has_wsjtx_version(LooseVersion("2.4"))
|
||||
|
||||
def has_msk144decoder(self):
|
||||
"""
|
||||
To decode the MSK144 digimode please install the "msk144decoder". See the
|
||||
[project page](https://github.com/alexander-sholohov/msk144decoder) for more details.
|
||||
"""
|
||||
return self.command_is_runnable("msk144decoder")
|
||||
|
||||
def has_js8(self):
|
||||
"""
|
||||
To decode JS8, you will need to install [JS8Call](http://js8call.com/)
|
||||
|
|
|
|||
|
|
@ -128,6 +128,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("msk144", "MSK144", requirements=["msk144"], underlying=["usb"], service=True),
|
||||
Js8Mode("js8", "JS8Call"),
|
||||
DigitalMode(
|
||||
"packet",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class PskReporter(Reporter):
|
|||
Current version at the time of the last change:
|
||||
https://www.adif.org/312/ADIF_312.htm#Mode_Enumeration
|
||||
"""
|
||||
return ["FT8", "FT4", "JT9", "JT65", "FST4", "JS8", "Q65", "WSPR", "FST4W"]
|
||||
return ["FT8", "FT4", "JT9", "JT65", "FST4", "JS8", "Q65", "WSPR", "FST4W", "MSK144"]
|
||||
|
||||
def stop(self):
|
||||
self.cancelTimer()
|
||||
|
|
|
|||
|
|
@ -299,6 +299,9 @@ class ServiceHandler(SdrSourceEventClient):
|
|||
from csdr.chain.digimodes import AudioChopperDemodulator
|
||||
from owrx.wsjt import WsjtParser
|
||||
return AudioChopperDemodulator(mod, WsjtParser())
|
||||
elif mod == "msk144":
|
||||
from csdr.chain.digimodes import Msk144Demodulator
|
||||
return Msk144Demodulator()
|
||||
elif mod == "js8":
|
||||
from csdr.chain.digimodes import AudioChopperDemodulator
|
||||
from owrx.js8 import Js8Parser
|
||||
|
|
|
|||
11
owrx/wsjt.py
11
owrx/wsjt.py
|
|
@ -245,6 +245,17 @@ class Q65Profile(WsjtProfile):
|
|||
return ["jt9", "--q65", "-p", str(self.interval), "-b", self.mode.name, "-d", str(self.decoding_depth()), file]
|
||||
|
||||
|
||||
class Msk144Profile(WsjtProfile):
|
||||
def getMode(self):
|
||||
return "MSK144"
|
||||
|
||||
def getInterval(self):
|
||||
return 15
|
||||
|
||||
def decoder_commandline(self, file):
|
||||
return None
|
||||
|
||||
|
||||
class WsjtParser(AudioChopperParser):
|
||||
def parse(self, profile: WsjtProfile, freq: int, raw_msg: bytes):
|
||||
try:
|
||||
|
|
|
|||
Loading…
Reference in New Issue