7N1 support, detect valid sample rates.

pull/13/head
Mark Jessop 2020-07-16 18:40:25 +09:30
rodzic cf9e67691b
commit 2e77ed056b
5 zmienionych plików z 60 dodań i 25 usunięć

Wyświetl plik

@ -2,11 +2,24 @@
Telemetry demodulator for the following modems in use by Project Horus
* Horus Binary Modes (4FSK)
* v1 - Legacy 22 byte mode, Golay FEC
* v2 - 16/32-byte modes, LDPC FEC (Still in development)
* RTTY (7N2 and 8N2, standard UKHAS sentences with CRC16 only)
* v1 - Legacy 22 byte mode, Golay(23,12) FEC
* v2 - 16/32-byte modes, LDPC FEC (Under development)
* RTTY (7N1, 7N2 and 8N2, standard [UKHAS sentences](https://ukhas.org.uk/communication:protocol) with CRC16 only)
This project serves as a graphical front-end to [horusdemodlib](https://github.com/projecthorus/horusdemodlib) a Python/C library of telemetry demodulators based off the [codec2](https://github.com/drowe67/codec2) FSK modem. The core modem used in this library is very well tested, and performs in line with incoherent FSK demodulator theory. The RTTY decoder is approximately [2dB better](http://www.rowetel.com/?p=5906) than dl-fldigi, and the Horus Binary v1 modem approximately 7 dB better again. Once finished, the Horus Binary v2 modes should provide an additional few dB more performance yet again.
This project serves as a graphical front-end to [horusdemodlib](https://github.com/projecthorus/horusdemodlib) a Python/C library of telemetry demodulators based off the [codec2](https://github.com/drowe67/codec2) FSK modem. The core modem used in this library is very well tested, and performs in line with incoherent FSK demodulator theory. The RTTY decoder is approximately [2dB better](http://www.rowetel.com/?p=5906) than dl-fldigi, and the Horus Binary v1 modem approximately 7 dB better again. Once finished, the Horus Binary v2 modes should provide more flexibility over the v1 mode, and provide further performance improvements.
### Important Performance Notes
The FSK demodulator at the core of this application expects the transmitter to behave like a modem. That is, it should:
* Have a symbol rate which is close to the desired symbol rate (within +/- 1000 ppm).
* Maintain that symbol rate throughout a transmission (i.e. not drift in symbol rate across a transmission)
* Not have gaps between transmitted bytes.
* Not drift a lot in frequency during a transmission (a few Hz/sec is probably OK - this needs to be tested further)
All of the above are achievable from a small microcontroller such as an Arduino. The use of [interrupts](https://ukhas.org.uk/guides:interrupt_driven_rtty) (instead of sleep statements) to control symbol timing is recommended. Raspberry Pi UARTs (in particular the 'mini-UART') are known to have gaps between transmitter bytes, so be warned!
If you are having issues decoding telemetry from your payload, then carefully investigate the above points. If you are still having issues, then please contact me with a recording via the e-mail address below.
### Authors
Written by:
* GUI & Glue Code - Mark Jessop <vk5qi@rfhead.net>
@ -14,21 +27,18 @@ Written by:
* FSK Modem Wrapper - XSSFox
* LDPC Codes - Bill Cowley
**Note: This is very much a work in progress!**
![Screenshot](doc/horusgui_screenshot.png)
### Known Issues
* Occasional crash when processing is stopped just as a packet is being processed by horus_api.
* Queue events not processed on OSX when the application is running in the background.
### TODO LIST - Important Stuff
* Better build system via Travis (@xssfox)
### TODO LIST - Extras
* Waterfall Display (? Need something GPU accelerated if possible...)
* rotctld rotator control?
### TODO LIST
* Important Things
* Better build system via Travis (@xssfox)
* Extras
* Waterfall Display (? Need something GPU accelerated if possible...)
* rotctld rotator control?
## Usage
@ -96,9 +106,8 @@ Or run the helper startup script:
$ python horus-gui.py
```
## Updating
As this repository is under regular development, you will likely need to update frequently.
This means updating both this repository, and horusdemodlib, on which it depends.
### Updating
As this repository is under regular development, you will likely need to update frequently. For those using the binary builds, this just means downloading a new file and running it. If you're running from source, this means updating both this repository, and horusdemodlib, on which it depends.
```console
$ cd ~/horusdemodlib

Wyświetl plik

@ -1 +1 @@
__version__ = "0.1.8"
__version__ = "0.1.9"

Wyświetl plik

@ -48,7 +48,7 @@ def init_audio(widgets):
def populate_sample_rates(widgets):
""" Populate the sample rate ComboBox with the sample rates of the currently selected audio device """
global audioDevices
global audioDevices, pyAudio
# Clear list of sample rates.
widgets["audioSampleRateSelector"].clear()
@ -56,18 +56,29 @@ def populate_sample_rates(widgets):
# Get information on current audio device
_dev_name = widgets["audioDeviceSelector"].currentText()
# Add in fixed sample rate for GQRX input.
if _dev_name == 'GQRX UDP':
# Add in fixed sample rate for GQRX input, which only outputs at 48 kHz.
widgets["audioSampleRateSelector"].addItem(str(48000))
widgets["audioSampleRateSelector"].setCurrentIndex(0)
if _dev_name in audioDevices:
# TODO: Determine valid samples rates. For now, just use the default.
# TODO: Add support for resampling.
#_samp_rate = 48000 #
_samp_rate = int(audioDevices[_dev_name]["defaultSampleRate"])
widgets["audioSampleRateSelector"].addItem(str(_samp_rate))
widgets["audioSampleRateSelector"].setCurrentIndex(0)
# Determine which sample rates from a common list are valid for this device.
_possible_rates = [8000.0, 22050.0, 44100.0, 48000.0, 96000.0]
for _rate in _possible_rates:
_dev_info = audioDevices[_dev_name]
_valid = pyAudio.is_format_supported(
_rate,
input_device=_dev_info['index'],
input_channels=1,
input_format=pyaudio.paInt16
)
if _valid:
widgets["audioSampleRateSelector"].addItem(str(int(_rate)))
# Pick the default one.
_default_samp_rate = int(audioDevices[_dev_name]["defaultSampleRate"])
widgets["audioSampleRateSelector"].setCurrentText(str(_default_samp_rate))
else:
logging.error("Audio - Unknown Audio Device")

Wyświetl plik

@ -11,12 +11,14 @@ from pyqtgraph.Qt import QtCore
from ruamel.yaml import YAML
from . import __version__
from .modem import populate_modem_settings
from .audio import populate_sample_rates
from horusdemodlib.payloads import download_latest_payload_id_list, download_latest_custom_field_list
import horusdemodlib.payloads
default_config = {
"version": __version__,
"audio_device": "None",
"audio_sample_rate": "48000",
"modem": "Horus Binary v1 (Legacy)",
"baud_rate": -1,
"habitat_upload_enabled": True,
@ -89,6 +91,11 @@ def read_config(widgets):
# Try and set the audio device.
# If the audio device is not in the available list of devices, this will fail silently.
widgets["audioDeviceSelector"].setCurrentText(default_config["audio_device"])
# Populate the list of valid sample rates
populate_sample_rates(widgets)
# Attempt to set the configured sample rate. This will fail silently if it does not exist.
widgets["audioSampleRateSelector"].setCurrentText(str(default_config["audio_sample_rate"]))
# Try and set the modem. If the modem is not valid, this will fail silently.
widgets["horusModemSelector"].setCurrentText(default_config["modem"])
# Populate the default settings.
@ -127,6 +134,7 @@ def save_config(widgets):
default_config["horus_udp_enabled"] = widgets["horusUploadSelector"].isChecked()
default_config["horus_udp_port"] = int(widgets["horusUDPEntry"].text())
default_config["audio_device"] = widgets["audioDeviceSelector"].currentText()
default_config["audio_sample_rate"] = widgets["audioSampleRateSelector"].currentText()
default_config["modem"] = widgets["horusModemSelector"].currentText()
default_config["baud_rate"] = int(widgets["horusModemRateSelector"].currentText())

Wyświetl plik

@ -12,6 +12,13 @@ HORUS_MODEM_LIST = {
"default_tone_spacing": 270,
"use_mask_estimator": False,
},
"RTTY (7N1)": {
"id": Mode.RTTY_7N1,
"baud_rates": [50, 75, 100, 300, 600, 1000],
"default_baud_rate": 100,
"default_tone_spacing": 425,
"use_mask_estimator": False,
},
"RTTY (7N2)": {
"id": Mode.RTTY_7N2,
"baud_rates": [50, 75, 100, 300, 600, 1000],