diff --git a/CHANGELOG.md b/CHANGELOG.md index 8456653..4af0dc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Introduced `squelch_auto_margin` config option that allows configuring the auto squelch level - Removed `port` configuration option; `rtltcp_compat` takes the port number with the new connectors - Added support for new WSJT-X modes FST4 and FST4W (only available with WSJT-X 2.3) +- Added support for demodulating M17 digital voice signals using m17-cxx-demod - New devices supported: - HPSDR devices (Hermes Lite 2) - BBRF103 / RX666 / RX888 devices supported by libsddc diff --git a/csdr/csdr.py b/csdr/csdr.py index d663b81..b95c10f 100644 --- a/csdr/csdr.py +++ b/csdr/csdr.py @@ -216,11 +216,11 @@ class dsp(object): "csdr convert_f_s16" ] elif self.isDigitalVoice(which): - chain += ["csdr fmdemod_quadri_cf", "dc_block "] + chain += ["csdr fmdemod_quadri_cf"] chain += last_decimation_block # dsd modes if which in ["dstar", "nxdn"]: - chain += ["csdr limit_ff", "csdr convert_f_s16"] + chain += ["dc_block", "csdr limit_ff", "csdr convert_f_s16"] if which == "dstar": chain += ["dsd -fd -i - -o - -u {unvoiced_quality} -g -1 "] elif which == "nxdn": @@ -230,9 +230,18 @@ class dsp(object): "CSDR_FIXED_BUFSIZE=32 csdr agc_s16 --max 30 --initial 3", "sox -t raw -r 8000 -e signed-integer -b 16 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - ", ] + # m17 + elif which == "m17": + chain += [ + "csdr limit_ff", + "csdr convert_f_s16", + "m17-demod", + "CSDR_FIXED_BUFSIZE=32 csdr agc_s16 --max 30 --initial 3", + "sox -t raw -r 8000 -e signed-integer -b 16 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - ", + ] # digiham modes else: - chain += ["rrc_filter", "gfsk_demodulator"] + chain += ["dc_block", "rrc_filter", "gfsk_demodulator"] if which == "dmr": chain += [ "dmr_decoder --fifo {meta_pipe} --control-fifo {dmr_control_pipe}", @@ -585,7 +594,7 @@ class dsp(object): def isDigitalVoice(self, demodulator=None): if demodulator is None: demodulator = self.get_demodulator() - return demodulator in ["dmr", "dstar", "nxdn", "ysf"] + return demodulator in ["dmr", "dstar", "nxdn", "ysf", "m17"] def isWsjtMode(self, demodulator=None): if demodulator is None: diff --git a/debian/changelog b/debian/changelog index c7dc727..b4f9544 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,8 @@ openwebrx (0.21.0) UNRELEASED; urgency=low with the new connectors * Added support for new WSJT-X modes FST4 and FST4W (only available with WSJT-X 2.3) + * Added support for demodulating M17 digital voice signals using + m17-cxx-demod * New devices supported: - HPSDR devices (Hermes Lite 2) (`"type": "hpsdr"`) - BBRF103 / RX666 / RX888 devices supported by libsddc (`"type": "sddc"`) diff --git a/docker/scripts/install-dependencies.sh b/docker/scripts/install-dependencies.sh index 338201c..55a95e7 100755 --- a/docker/scripts/install-dependencies.sh +++ b/docker/scripts/install-dependencies.sh @@ -18,8 +18,8 @@ function cmakebuild() { cd /tmp -STATIC_PACKAGES="sox libfftw3-bin python3 python3-setuptools netcat-openbsd libsndfile1 liblapack3 libusb-1.0-0 libqt5core5a libreadline7 libgfortran4 libgomp1 libasound2 libudev1 ca-certificates libqt5gui5 libqt5sql5 libqt5printsupport5 libpulse0 libfaad2 libopus0" -BUILD_PACKAGES="wget git libsndfile1-dev libfftw3-dev cmake make gcc g++ liblapack-dev texinfo gfortran libusb-1.0-0-dev qtbase5-dev qtmultimedia5-dev qttools5-dev libqt5serialport5-dev qttools5-dev-tools asciidoctor asciidoc libasound2-dev libudev-dev libhamlib-dev patch xsltproc qt5-default libfaad-dev libopus-dev" +STATIC_PACKAGES="sox libfftw3-bin python3 python3-setuptools netcat-openbsd libsndfile1 liblapack3 libusb-1.0-0 libqt5core5a libreadline7 libgfortran4 libgomp1 libasound2 libudev1 ca-certificates libqt5gui5 libqt5sql5 libqt5printsupport5 libpulse0 libfaad2 libopus0 libboost-program-options1.67.0" +BUILD_PACKAGES="wget git libsndfile1-dev libfftw3-dev cmake make gcc g++ liblapack-dev texinfo gfortran libusb-1.0-0-dev qtbase5-dev qtmultimedia5-dev qttools5-dev libqt5serialport5-dev qttools5-dev-tools asciidoctor asciidoc libasound2-dev libudev-dev libhamlib-dev patch xsltproc qt5-default libfaad-dev libopus-dev libgtest-dev libboost-dev libboost-program-options-dev" apt-get update apt-get -y install auto-apt-proxy apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES @@ -110,6 +110,10 @@ popd rm -rf dream rm dream-2.1.1-svn808.tar.gz +git clone https://github.com/mobilinkd/m17-cxx-demod.git +# latest master as of 2020-12-27 (new sync words) +cmakebuild m17-cxx-demod 2b84657676efb3b07b33de3ab3d0a6218e9d88b5 + git clone https://github.com/hessu/aprs-symbols /usr/share/aprs-symbols pushd /usr/share/aprs-symbols git checkout 5c2abe2658ee4d2563f3c73b90c6f59124839802 diff --git a/owrx/feature.py b/owrx/feature.py index 39c6c20..fbdb425 100644 --- a/owrx/feature.py +++ b/owrx/feature.py @@ -75,6 +75,7 @@ class FeatureDetector(object): "digital_voice_digiham": ["digiham", "sox"], "digital_voice_dsd": ["dsd", "sox", "digiham"], "digital_voice_freedv": ["freedv_rx", "sox"], + "digital_voice_m17": ["m17_demod", "sox"], "wsjt-x": ["wsjtx", "sox"], "packet": ["direwolf", "sox"], "pocsag": ["digiham", "sox"], @@ -150,7 +151,7 @@ class FeatureDetector(object): # prevent X11 programs from opening windows if called from a GUI shell env.pop("DISPLAY", None) try: - process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=tmp_dir, env=env) + process = subprocess.Popen(cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=tmp_dir, env=env) rc = process.wait() if expected_result is None: return rc != 32512 @@ -419,6 +420,14 @@ class FeatureDetector(object): """ return self.command_is_runnable("dsd") + def has_m17_demod(self): + """ + The `m17-demod` tool is used to demodulate M17 digital voice signals. + + You can find more information [here](https://github.com/mobilinkd/m17-cxx-demod) + """ + return self.command_is_runnable("m17-demod") + def has_sox(self): """ The sox audio library is used to convert between the typical 8 kHz audio sampling rate used by digital modes and diff --git a/owrx/modes.py b/owrx/modes.py index 0d1561f..8b642e1 100644 --- a/owrx/modes.py +++ b/owrx/modes.py @@ -63,6 +63,7 @@ class Modes(object): AnalogMode("dstar", "D-Star", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_dsd"], squelch=False), AnalogMode("nxdn", "NXDN", bandpass=Bandpass(-3250, 3250), requirements=["digital_voice_dsd"], squelch=False), AnalogMode("ysf", "YSF", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_digiham"], squelch=False), + AnalogMode("m17", "M17", bandpass=Bandpass(-4000, 4000), requirements=["digital_voice_m17"], squelch=False), AnalogMode("freedv", "FreeDV", bandpass=Bandpass(300, 3000), requirements=["digital_voice_freedv"], squelch=False), AnalogMode("drm", "DRM", bandpass=Bandpass(-5000, 5000), requirements=["drm"], squelch=False), DigitalMode("bpsk31", "BPSK31", underlying=["usb"]), diff --git a/owrx/source/sdrplay.py b/owrx/source/sdrplay.py index da2398a..5fb2f4c 100644 --- a/owrx/source/sdrplay.py +++ b/owrx/source/sdrplay.py @@ -10,6 +10,7 @@ class SdrplaySource(SoapyConnectorSource): "rf_notch": "rfnotch_ctrl", "dab_notch": "dabnotch_ctrl", "if_mode": "if_mode", + "external_reference": "extref_ctrl", } ) return mappings