Electronics engineering student at TU Dresden.

Interested in electronics, ham radio, UNIX like OSs and software development (Rust, Julia).

Fulltime GNU+Linux user since 2012.

GitHub: knightshrub

Creative Commons License All text is licensed under CC-BY-SA 4.0 International License

GNU GPLv3 Code is licensed under GPLv3

[ 2019-07-28 ]

Modular digital mode package

Categories: Hamradio Programming

Ham radio digital modes the UNIX way

For a long time now I have been meaning to write my own digital mode program, something similar to fldigi. This seems like the perfect excuse to start a Rust project. Unfortunately the GUI story in Rust at the moment is still not great. I most often see gtk-rs being recommended as the most usable cross platform GUI toolkit right now. I have played around with gtk-rs a little bit but I'm not really happy with the usability of it right now.

I have decided that the best way to tackle this problem is to split the program into different modular components, following the UNIX philosophy. This way each component remains separate and can be easily replaced later if a better alternative is available or I need to do something else.

The individual components read from stdin and write to stdout. In this way the components can be chained together into pipelines as is the case with most traditional UNIX tools.

This also takes care of the headache of interfacing to the particular radio hardware. As long as there is a way to feed the baseband sample stream into the pipeline it doesn't matter where the baseband signal comes from. It could be a recording, a WebSDR, an RTL-SDR or a traditional HF transceiver with the audio output connected to the computers sound card input.

The pipeline to do BPSK31 demodulation could look like this

arecord -t raw -f S32_BE -c 2 -r 8000 - | panadapter | demod --mode bpsk31

Where panadapter opens a GUI waterfall display that allows the user to select which part of the spectrum to isolate and pass on to the demodulator, similar to how it is done in fldigi. The final demodulated output appears in the terminal.

Signal flow

Most amateur radio digital modes follow a similar signal flow in the modulator and demodulator.


The modulator usually includes the following functionality.

1. Source compression (map ASCII to an information bit sequence)
2. Optional: interleave information bit sequence
3. Optional: perform forward error correction (FEC) coding
4. Symbol mapping (map bit sequence onto modulation symbols)
5. Create time-domain baseband signal

In the case of BPSK31 the source compression is done by the varicode alphabet that was specifically chosen for this mode. The time domain baseband signal generation is different for linear (PSK, QAM) and non-linear (FSK) modulation schemes, but that is not an issue since it can be abstracted away as converting symbols to baseband signal.


The demodulator performs the same steps as the modulator only in reverse. The most difficult part is usually the synchronization.

1. Synchronize & sample baseband signal to extract symbols
2. Demap symbols back into bits
3. Optional: decode the FEC code
4. Optional: remove interleaving
5. Decompress the received bitstream into original bistream 

The modulator and demodulator are fed the baseband IQ samples, which is taken care of by the panadapter program mentioned above.

The baseband input sample rate to the demodulator is ideally constant for all modes. The same goes for the output sample rate of the modulator. This will simplify interfacing with the rest of the pipeline.


I have decided to first work on implementing the modulator/demodulator together with some simple modes. This way I don't have to deal with GUI programming in Rust yet. By the time I have those components completed there might have been significant improvements in this area.