Inside rade_c: Neural Network HF Digital Voice for FreeDV in Pure C

Inside rade_c: Neural Network HF Digital Voice for FreeDV in Pure C

TL;DR: rade_c (GitHub) is the official open source C library implementation of RADE (Radio AutoEncoder, formerly RADAE), a neural-network-powered digital voice mode created by David Rowe (VK5DGR) and Jean-Marc Valin for the FreeDV project. Unlike traditional digital voice modes that serialize compressed vocoder bits over a rigid modem, RADE uses an end-to-end deep learning autoencoder combined with the FARGAN neural vocoder to map speech features directly onto an OFDM waveform. Operating in a narrow 1500 Hz RF bandwidth and remaining readable down to -2 dB SNR, RADE eliminates the harsh digital “cliff effect” on fading HF channels. The rade_c repository ports the original Python/PyTorch research code into pure, lightweight C99, embedding the trained neural weights for low-latency, real-time CPU execution in FreeDV GUI and embedded SDRs.

+---------------------------------------------------------------------------------------------------+
|                                  RADE C SIGNAL PIPELINE ARCHITECTURE                              |
+---------------------------------------------------------------------------------------------------+
|                                                                                                   |
|   [ TRANSMIT PATH ]                                                                               |
|                                                                                                   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|   | 16 kHz Audio In   |  -->  | LPCNet Feature Extr.  |  -->  | RADE Neural Encoder (C99)     |   |
|   | (Microphone PCM)  |       | 18 Bark + Pitch + Corr|       | Dense layers -> Latent Vector |   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|                                                                               |                   |
|                                                                               v                   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|   | 1500 Hz RF Signal |  <--  | 8 kHz Audio / IQ Out  |  <--  | OFDM Modulator + Pilot Insert |   |
|   | (SSB Transceiver) |       | (Soundcard TX Stream) |       | Low PAPR subcarrier mapping   |   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|                                                                                                   |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IONOSPHERIC HF MULTIPATH & NOISE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|                                                                                                   |
|   [ RECEIVE PATH ]                                                                                |
|                                                                                                   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|   | 1500 Hz RF Audio  |  -->  | Pilot Frame Sync &    |  -->  | OFDM Demodulator              |   |
|   | (SSB RX Audio/IQ) |       | Doppler/Phase Track   |       | Equalized Latent Symbols      |   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|                                                                               |                   |
|                                                                               v                   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|   | 16 kHz Audio Out  |  <--  | FARGAN Neural Vocoder |  <--  | RADE Neural Decoder (C99)     |   |
|   | (Speaker / Phones)|       | High-fidelity GAN Synth|      | Reconstructed Speech Vectors  |   |
|   +-------------------+       +-----------------------+       +-------------------------------+   |
|                                                                                                   |
+---------------------------------------------------------------------------------------------------+

For decades, amateur radio operators experimenting with digital voice on high frequency (HF) bands faced a fundamental trade-off: the dreaded digital “cliff effect.” On static-filled or multipath-faded channels where analog single sideband (SSB) remains readable with human ear filtering, conventional digital voice (such as FreeDV 1600, DMR, or D-STAR) suddenly collapses into robotic squeaks or complete silence once bit error rates exceed the Forward Error Correction (FEC) threshold.

David Rowe (VK5DGR), creator of Codec 2 and FreeDV, teamed up with machine learning audio pioneer Jean-Marc Valin (creator of Opus, Speex, and LPCNet) to rethink digital voice from first principles. The result is RADE (Radio AutoEncoder). By unifying speech synthesis and radio modulation into a single neural autoencoder, RADE delivers natural speech over fading HF paths at signal levels lower than analog SSB.

The freedv/rade_c repository represents the critical transition of RADE from a heavy Python/PyTorch research experiment into an efficient, production-ready C library that any developer can embed into desktop software, standalone SDR transceivers, and Raspberry Pi field gear.


What Is rade_c?

rade_c is the official, portable C99 library and toolchain implementation of the RADE neural speech codec and OFDM modem developed by the FreeDV project for real-time digital voice communication over noisy, multipath HF radio channels.

While the early prototypes in the drowe67/radae repository relied on Python, PyTorch, and CUDA dependencies, rade_c compiles the trained neural network model weights directly into static C data structures. This allows standard x86 and ARM processors to execute neural speech encoding, OFDM modulation, channel decoding, and FARGAN synthesis in real time with minimal latency and without requiring a GPU.


The Historical Problem: The Digital Cliff on HF

To understand why RADE is a milestone in radio communications, consider how traditional digital voice systems work.

Traditional Digital Voice Pipeline (Cascaded Blocks):
Speech -> [Vocoder] -> Bits -> [Channel Codec (FEC)] -> Coded Bits -> [Modem] -> RF Carrier

In this classical model, each block operates in isolation:

1. The Vocoder (such as Codec 2, AMBE, or MELP) analyzes speech and compresses vocal tract parameters into a strict digital bitstream (typically 700 to 2400 bits per second).

2. The Forward Error Correction (FEC) layer adds redundant parity bits (such as LDPC or convolutional codes) to protect against bit flips.

3. The Modem maps those bits onto PSK, QAM, or FSK subcarriers.

Why Cascaded Systems Fail on HF

HF ionospheric propagation is chaotic. Signals suffer from multi-hop reflection, Doppler spread, rapid Rayleigh fading dips of 20 dB or more, and atmospheric static crashes.

When the signal-to-noise ratio (SNR) is high, classical digital voice sounds clear. But when fading drives the SNR below the FEC decoding threshold, the error rate spikes. A single corrupted bit in an unvoiced/voiced decision or pitch parameter produces jarring acoustic artifacts. If too many frames are lost, the receiver loses synchronization entirely, cutting off audio completely.

Analog SSB, by contrast, has no cliff. As signal strength drops, background hiss increases, but human brain processing can track the speaker voice buried deep in the noise down to approximately 0 dB SNR.

Speech Intelligibility vs SNR:
Intelligibility (%)
100% |     /============== (RADE: Graceful Neural Roll-off)
     |    /  /----------- (Traditional Digital Voice: Sharp Cliff)
     |   /  /
 50% |  /  |     . - - - - (Analog SSB: Linear Degradation)
     | /   |   .
  0% +-----+---+--------------------> SNR (dB)
     -2dB +2dB +6dB

RADE solves this by abandoning separate bitstream serialization. Instead of forcing speech into discrete digital bits, RADE trains a neural network autoencoder to perform Joint Source-Channel Coding (JSCC).


How RADE Works: Joint Source-Channel Autoencoding

RADE merges the vocoder and the radio modem into an end-to-end neural network pipeline optimized against simulated ionospheric channels during training.

+---------------------------------------------------------------------------------------------------+
|                                 RADE AUTOENCODER TRAINING & INFERENCE                             |
+---------------------------------------------------------------------------------------------------+
|                                                                                                   |
|   16 kHz Audio ---> [ Feature Extraction ] ---> 18 Bark Cepstral Features + Pitch + Corr          |
|                                                               |                                   |
|                                                               v                                   |
|                                                    [ Neural Encoder Network ]                     |
|                                                               |                                   |
|                                                               v                                   |
|                                                  Continuous Latent Symbols                        |
|                                                               |                                   |
|                                                               v                                   |
|   Transmitted Waveform <==================== [ OFDM Modulator + Pilot Tones ]                     |
|                                                                                                   |
|   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIMULATED / REAL HF CHANNEL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   |
|   • Additive White Gaussian Noise (AWGN down to -2 dB) • CCIR Poor Rayleigh Multipath             |
|   • 1 Hz Doppler Spread • 2 ms Delay Spread            • Frequency Offset & Phase Jitter          |
|   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   |
|                                                                                                   |
|   Received Waveform    ====================> [ Pilot Tracking & Equalizer ]                       |
|                                                               |                                   |
|                                                               v                                   |
|                                                    [ Neural Decoder Network ]                     |
|                                                               |                                   |
|                                                               v                                   |
|                                                  Reconstructed Speech Features                    |
|                                                               |                                   |
|                                                               v                                   |
|   16 kHz Audio Out <------------------------ [ FARGAN Neural Vocoder Synth ]                      |
|                                                                                                   |
+---------------------------------------------------------------------------------------------------+

1. Feature Extraction

Input speech sampled at 16 kHz is segmented into 20 ms frames. A lightweight DSP frontend extracts 18 Bark-scale cepstral coefficients, fundamental pitch period, and pitch correlation parameters (similar to the frontend of LPCNet). These 20 real-valued numbers capture human vocal tract resonance and excitation.

2. The Neural Encoder

The neural encoder (built with dense and recurrent GRU layers) takes the speech feature frames and compresses them into a continuous latent symbol vector. Crucially, these latent values aren’t quantized into binary 1s and 0s. They remain continuous analog-like floating-point coordinates in multidimensional space.

The encoder is constrained during training to produce symbols with low Peak-to-Average Power Ratio (PAPR), ensuring high transmitter power amplifier efficiency in SSB transceivers.

3. OFDM Channel Modulation

The latent symbols are mapped onto an Orthogonal Frequency Division Multiplexing (OFDM) waveform containing multiple narrow subcarriers. The entire transmission occupies just 1500 Hz of RF bandwidth – half the width of a standard 3.0 kHz SSB channel, and significantly narrower than FreeDV 700D (which requires 1000 Hz) while delivering higher audio fidelity.

Periodic known pilot symbols are inserted across time and frequency grids to allow the receiver to measure channel phase rotation and Doppler drift.

4. Channel Robustness and Graceful Degradation

During machine learning training in PyTorch, the autoencoder was subjected to millions of hours of simulated HF channels:

  • Additive White Gaussian Noise (AWGN) across SNR ranges from +10 dB down to -6 dB.
  • ITU/CCIR Poor ionospheric conditions (multipath delay spreads of 2 ms and Doppler spreads of 1 Hz).
  • Frequency offsets up to $\pm 20$ Hz.

The network learned how to distribute vital speech information across the subcarriers so that if selective fading cancels out one frequency bin, adjacent subcarriers provide sufficient latent context for the decoder to reconstruct the voice without squeaks or muting.

5. FARGAN Neural Vocoder Synthesis

On the receiving end, the neural decoder reconstructs the 18 Bark features. These are passed to FARGAN (Framewise Autoregressive Generative Adversarial Network), a neural vocoder developed by Jean-Marc Valin as part of the Opus audio project.

FARGAN synthesizes clean, natural-sounding 16 kHz audio from the reconstructed features. Unlike early LPC vocoders that produced nasal, robotic tones, FARGAN recreates natural vocal timbre, breath sounds, and inflection.


What rade_c Brings to the Table

While training a deep neural network requires Python, PyTorch, and heavy GPU clusters, deploying that model on a radio operator’s PC or embedded transceiver requires pure, lightweight code. This is the purpose of freedv/rade_c.

+---------------------------------------------------------------------------------------------------+
|                                  RADE_C REPOSITORY ARCHITECTURE                                   |
+---------------------------------------------------------------------------------------------------+
|                                                                                                   |
|   freedv/rade_c                                                                                   |
|   ├── src/                                                                                        |
|   │   ├── rade_api.c         # Public C API implementation (open, tx, rx, close)                  |
|   │   ├── rade_enc.c         # Neural encoder inference engine                                    |
|   │   ├── rade_dec.c         # Neural decoder inference engine                                    |
|   │   ├── rade_enc_data.c    # Static C array containing pre-trained encoder weights              |
|   │   ├── rade_dec_data.c    # Static C array containing pre-trained decoder weights              |
|   │   ├── fargan.c           # Pure C FARGAN neural vocoder synthesizer                           |
|   │   ├── fargan_data.c      # FARGAN pre-trained neural weights array                            |
|   │   ├── ofdm.c             # OFDM modulator, demodulator, FFT routines, and pilots              |
|   │   └── kiss_fft/          # Embedded lightweight KissFFT engine                                |
|   ├── include/                                                                                    |
|   │   └── rade_api.h         # Clean, stable public API header for SDRs and GUIs                  |
|   ├── unittest/              # Automated unit tests and BER validation vectors                    |
|   └── CMakeLists.txt         # Cross-platform CMake build configuration                           |
|                                                                                                   |
+---------------------------------------------------------------------------------------------------+

Key Engineering Features of rade_c

1. Zero External Machine Learning Runtimes: rade_c doesn’t link against ONNX Runtime, TensorFlow Lite, or PyTorch C++. All neural layers (matrix multiplications, GRU cells, activation functions) are hand-crafted in standard C99.

2. Compiled Static Model Weights: The trained neural weights (roughly 47 MB of model data) are converted into static C source files (rade_enc_data.c, rade_dec_data.c, fargan_data.c). When you compile the library, the weights become part of the binary or shared library librade.

3. Optimized for Standard CPUs: Real-time speech decoding runs on modest x86_64 CPUs and ARM Cortex-A processors (such as the Raspberry Pi 4/5) with single-core CPU usage well within normal operational budgets.

4. Low End-to-End Latency: The processing frame size is 20 to 40 ms, keeping round-trip conversational turnaround snappy and suitable for natural amateur radio push-to-talk (PTT) exchanges.


Mode Comparison: RADE vs FreeDV Modes vs SSB vs DMR

Parameter / Feature RADE (rade_c) FreeDV 700D FreeDV 1600 Analog SSB DMR (AMBE+2)
Underlying Tech Neural Autoencoder + FARGAN Codec 2 + OFDM + LDPC Codec 2 + 16-QPSK Linear Analog Amplitude Mod AMBE+2 Vocoder + 4FSK
RF Bandwidth 1500 Hz (Narrow) 1000 Hz (Ultra-narrow) 1250 Hz 2700 – 3000 Hz (Wide) 12.5 kHz (VHF/UHF channel)
SNR Threshold (AWGN) -2 dB +2 dB +6 dB ~0 dB (Human ear limit) +7 dB
Multipath / QSB Handling Exceptional (Graceful roll-off) Good (LDPC FEC) Moderate Moderate (Fading flutter) Fails on HF multipath
Cliff Effect? No (Degrades like SSB) Yes (Sudden loss) Yes (Sudden loss) No (Continuous noise) Yes (Severe digital mute)
Audio Fidelity High (16 kHz speech) Low (Synthesized 8 kHz) Medium (8 kHz speech) Medium (Tuned 3 kHz voice) High (VHF communications)
Patent / Licensing Open Source (LGPL/BSD) Open Source (LGPL) Open Source (LGPL) Unencumbered Proprietary DVSI Patents
Hardware Reqs Modern CPU (x86/ARM) Lightweight micro / PC Lightweight micro / PC Pure analog transceiver Dedicated AMBE ASIC chip

Exploring the rade_c API: Developer Quickstart

Integrating rade_c into software-defined radios or custom digital voice pipelines requires only a few core functions defined in include/rade_api.h.

#include <stdio.h>
#include <stdlib.h>
#include "rade_api.h"

int main() {
    struct RADE *rade;
    int error;

    // 1. Initialize the RADE engine (Modes: RADE_MODE_V1 or RADE_MODE_V2)
    rade = rade_open(RADE_MODE_V2, &error);
    if (!rade) {
        fprintf(stderr, "Failed to initialize RADE engine: %d\n", error);
        return 1;
    }

    printf("RADE Engine initialized successfully.\n");
    printf("Speech Sample Rate:  %d Hz\n", rade_get_speech_sample_rate(rade));
    printf("Modem Sample Rate:   %d Hz\n", rade_get_modem_sample_rate(rade));
    printf("RF Signal Bandwidth: %d Hz\n", rade_get_bandwidth(rade));

    // 2. Transmit Pipeline Example
    // Input: 16 kHz 16-bit PCM speech buffer
    // Output: 8 kHz complex IQ or real audio modem buffer
    short speech_in[320];          // 20 ms frame at 16 kHz
    COMP modem_out[160];          // 20 ms frame at 8 kHz
    
    // Process one transmit frame
    // rade_tx(rade, modem_out, speech_in);

    // 3. Receive Pipeline Example
    // Input: 8 kHz modem audio from radio receiver
    // Output: 16 kHz reconstructed speech audio
    COMP modem_in[160];
    short speech_out[320];
    int sync_status;

    // Process one receive frame
    // sync_status = rade_rx(rade, speech_out, modem_in);

    // 4. Teardown and free memory
    rade_close(rade);
    return 0;
}

Key API Concepts

  • rade_open(int mode, int *error): Instantiates the encoder, decoder, OFDM filters, and FARGAN state machines.
  • rade_tx(struct RADE rade, COMP modem_out, short *speech_in): Consumes 16 kHz acoustic voice samples and emits modulated 8 kHz baseband audio symbols ready for soundcard TX or SDR transmission.
  • rade_rx(struct RADE rade, short speech_out, COMP *modem_in): Consumes incoming radio audio, tracks carrier frequency offsets, decodes the latent symbols, and outputs crisp 16 kHz reconstructed speech.
  • rade_close(struct RADE *rade): Cleans up internal buffers and releases memory.

Building rade_c from Source

Building rade_c on Linux, macOS, or Raspberry Pi OS is straightforward using CMake.

Prerequisites

On Debian, Ubuntu, or Raspberry Pi OS, install build essentials:

sudo apt update
sudo apt install -y build-essential cmake git libsamplerate0-dev libsndfile1-dev

Compiling the Library and CLI Tools

# Clone the official repository
git clone https://github.com/freedv/rade_c.git
cd rade_c

# Create build directory
mkdir build
cd build

# Configure CMake in Release mode (enables compiler vectorization)
cmake -DCMAKE_BUILD_TYPE=Release ..

# Compile using all available CPU cores
make -j$(nproc)

[!NOTE] Compiling rade_enc_data.c and rade_dec_data.c may take 1 to 2 minutes because the compiler is parsing tens of megabytes of static floating-point weight arrays. Ensure your system has at least 2 GB of available RAM during compilation.

Testing with Audio Files

After compilation, test the standalone encoder and decoder binaries directly on .wav files:

# 1. Modulate an input speech file into an HF RF waveform
./src/rade_tx input_speech_16k.wav modulated_hf_8k.wav

# 2. Simulate decoding the RF waveform back into speech
./src/rade_rx modulated_hf_8k.wav decoded_voice_16k.wav

The Broader Ecosystem: FreeDV GUI and Beyond

freedv/rade_c isn’t just a standalone library; it serves as the core engine powering the next generation of open source digital radio applications:

+---------------------------------------------------------------------------------------------------+
|                                  RADE C DEPLOYMENT ECOSYSTEM                                      |
+---------------------------------------------------------------------------------------------------+
|                                                                                                   |
|                                       +-------------------+                                       |
|                                       |   freedv/rade_c   |                                       |
|                                       |   (Pure C99 Lib)  |                                       |
|                                       +-------------------+                                       |
|                                                 |                                                 |
|                 +-------------------------------+-------------------------------+                 |
|                 |                               |                               |                 |
|                 v                               v                               v                 |
|   +---------------------------+   +---------------------------+   +---------------------------+   |
|   |   FREEDV GUI (2.0+)       |   |   RADAE_DECODER & HEADLESS|   |   WEBASSEMBLY / BROWSER   |   |
|   |   • Official desktop GUI  |   |   • Peter Marks (VK3PB)   |   |   • In-browser SDR demod  |   |
|   |   • CAT rig control & PTT |   |   • Linux audio daemon    |   |   • WebAudio streaming    |   |
|   |   • Waterfall & SNR meter |   |   • Headless Pi receivers |   |   • Zero-install testing  |   |
|   +---------------------------+   +---------------------------+   +---------------------------+   |
|                                                                                                   |
+---------------------------------------------------------------------------------------------------+

1. FreeDV GUI 2.0 Integration: The FreeDV desktop client is integrating rade_c as a selectable mode alongside classical 700D and 2020 modes. Operators can tune across HF bands (such as 14.236 MHz or 7.177 MHz) and communicate using neural digital voice using standard USB soundcard interfaces.

2. Peter Marks’ radae_decoder and radae_headless: Australian radio experimenter Peter Marks (VK3PB) created standalone Linux GUI decoders and lightweight headless daemons powered by rade_c, allowing automated remote SDR receiver stations to stream decoded RADE audio to web dashboards.

3. WebAssembly and In-Browser Demodulation: Because rade_c is written in pure ANSI C without proprietary dependencies, developers can compile the library using Emscripten to run directly inside web browsers, enabling WebSDRs to decode RADE transmissions without desktop software.


Real-World On-Air Experience

Operating RADE over real HF ionospheric paths reveals striking differences compared to both analog SSB and earlier digital voice modes:

  • No Robotic Chirps During Fading: When a deep QSB fade occurs, the audio doesn’t glitch with harsh metallic tones. The speech volume attenuates slightly and gains minor background coloration, behaving much like an analog signal while preserving word-for-word intelligibility.
  • Narrow Bandwidth Efficiency: At 1500 Hz bandwidth, two RADE conversations can fit within the spectral footprint of a single standard 3.0 kHz analog SSB transmission. This doubles spectrum efficiency on crowded amateur bands.
  • QRP Performance: Because RADE operates down to -2 dB SNR in 3 kHz noise, low-power QRP operators running 5 to 10 watts can achieve communication reliability comparable to 50 to 100 watt SSB stations.

Frequently Asked Questions

What is the difference between RADE, RADAE, and rade_c?

RADAE was the original working title for the project in David Rowe’s Python prototype repository (drowe67/radae). RADE (Radio AutoEncoder) is the official simplified name, and freedv/rade_c is the portable C99 library implementation.

Does rade_c require a graphics card (GPU) to run?

No. Unlike the Python research prototype which required PyTorch and GPU acceleration, rade_c is fully optimized in pure C99 to run in real time on standard desktop CPUs and ARM processors (like Raspberry Pi).

How does RADE achieve speech communication at -2 dB SNR?

RADE trains an end-to-end neural autoencoder on simulated HF multipath and noise. By bypassing discrete bit quantization and using the FARGAN neural vocoder, it reconstructs vocal tract resonance even when significant portions of the spectrum are buried in noise.

Can I use rade_c with my existing amateur radio transceiver?

Yes. RADE outputs standard audio tones via your computer soundcard into any SSB transceiver (upper sideband), requiring only 1500 Hz of audio bandwidth and a standard audio interface (such as a Digirig, Signalink, or internal USB codec).

Is RADE open source and patent-free?

Yes. rade_c is released under open source licensing (LGPL/BSD compatible), continuing the FreeDV mission of providing 100% open, patent-unencumbered digital voice technology for amateur radio worldwide.


Conclusion

The release of freedv/rade_c marks a major shift in amateur radio digital signal processing. By proving that neural network autoencoders can replace thirty-year-old cascaded vocoder-modem architectures, David Rowe (VK5DGR) and Jean-Marc Valin have shown that deep learning belongs on the airwaves.

With its narrow 1500 Hz bandwidth, resilience down to -2 dB SNR, elimination of the digital cliff effect, and lightweight C implementation, rade_c sets a new benchmark for weak-signal voice communications.

73, and happy experimenting on HF.


Sources and Further Reading

Post Comment