HF Multi-Channel Receiver – SDRplay RSPdx and KA9Q-Radio

The OE6VAG HF monitoring station uses a different architecture from a conventional SDR setup.

Instead of assigning one physical SDR receiver to one application, a single SDRplay RSPdx continuously digitizes a wide section of the HF spectrum. KA9Q-Radio then creates several independent virtual receivers from this common RF source.

These virtual receivers operate simultaneously and feed completely different applications such as aircraft data-link decoding, weather broadcasts, weather fax, time-signal analysis, amateur-radio propagation monitoring and live voice reception.

The result is one physical HF receiver acting as a small multi-channel receiving server.

Current applications include:

  • HFDL aircraft data links
  • DWD RTTY and SYNOP weather reports
  • DWD WEFAX weather charts
  • RWM time-signal monitoring
  • FT8 on 30 metres
  • WSPR on 30 metres
  • Shannon VOLMET audio

👉 Radio Monitoring – Autonomous Receiving Stations

👉 Live Data


System Architecture

The basic signal path is:

                         ┌──────────────────────────┐
                         │      Magnetic Loop       │
                         └────────────┬─────────────┘
                                      │
                                      ▼
                         ┌──────────────────────────┐
                         │    SDRplay RSPdx         │
                         │    Antenna input A       │
                         └────────────┬─────────────┘
                                      │ USB
                                      ▼
                    ┌─────────────────────────────────┐
                    │          KA9Q radiod            │
                    │                                 │
                    │  SDR driver                     │
                    │  4 MS/s wideband IQ             │
                    │  Digital down-converters        │
                    │  Filtering / demodulation       │
                    │  RTP / IP multicast outputs     │
                    └───────────────┬─────────────────┘
                                    │
          ┌──────────────┬──────────┼──────────┬───────────┐
          │              │          │          │           │
          ▼              ▼          ▼          ▼           ▼
       HFDL            DWD        WEFAX      FT8/WSPR     RWM
       96 kS/s         RTTY       48 kS/s     12 kS/s     24 kS/s
       IQ              audio      audio       audio        IQ
          │              │          │          │           │
          ▼              ▼          ▼          ▼           ▼
      dumphfdl        fldigi       Ilma       jt9 /       RWM
                                             wsprd       decoder

                                    │
                                    ▼
                              Shannon VOLMET
                               12 kS/s audio
                                    │
                                    ▼
                            Opus live web stream

The important design decision is that only radiod accesses the RSPdx.

Individual applications never open the SDR hardware directly.


Technical Overview

Technical Overview
AntennaMagnetic loop antenna
ReceiverSDRplay RSPdx
Receiver inputAntenna A
Host platformIntel N100 mini-PC
Operating systemUbuntu Server
SDR engineKA9Q-Radio radiod
RF sample rate4 MS/s
RF centre frequencyapproximately 9.632 MHz
Receiver architectureOne physical SDR, multiple virtual receivers
TransportRTP over local IP multicast
Service discoverymDNS / Avahi
Stream accessprimarily pcmrecord
OperationUnattended / continuous
Main applicationsHFDL, DWD RTTY, WEFAX, RWM, FT8, WSPR, Shannon VOLMET

The nominal 4 MS/s complex RF stream covers approximately 4 MHz around the selected centre frequency. Practical channel placement remains inside the usable filter range rather than directly at the spectrum edges.

This is sufficient to cover the currently required services from approximately 7.9 MHz up to 11.4 MHz simultaneously.


Why KA9Q-Radio?

Most desktop SDR applications follow a simple concept:

SDR → one application → one tuned receiver

That model works well for interactive listening but becomes inefficient when many autonomous decoders must run continuously.

KA9Q-Radio uses a different approach.

radiod reads the wideband SDR stream once and performs several digital down-conversions in parallel. Each resulting receiver can have its own:

  • centre frequency
  • bandwidth
  • sample rate
  • modulation mode
  • audio filter
  • gain configuration
  • multicast output

The decoders therefore behave as if they each had their own receiver even though all of them share the same RSPdx.

KA9Q-Radio itself is developed by Phil Karn, KA9Q:

https://github.com/ka9q/ka9q-radio


The radiod Process

The central component is the KA9Q-Radio daemon:

radiod

On the OE6VAG HF server it performs several tasks at the same time:

SDRplay hardware access
        ↓
wideband IQ acquisition
        ↓
digital down-conversion
        ↓
channel filtering
        ↓
optional demodulation
        ↓
sample-rate conversion
        ↓
RTP multicast streams

The active system uses a single radiod instance for all HF services.

This is important because opening the RSPdx independently from several programs would either fail or require multiple physical receivers.

With KA9Q-Radio the hardware is opened once and all subsequent distribution happens in software.


RF Front End

The RSPdx receives the HF spectrum from the magnetic-loop antenna.

The current wideband configuration uses approximately:

ParameterValue
RF centre9.632 MHz
RF sample rate4 MS/s
AntennaAntenna A
LNA state2
IF AGCenabled
FFT processing threads4

The RF centre was selected so that all currently required virtual receivers fit inside the common sampled spectrum.

Conceptually:

7.6 MHz                                  11.6 MHz
   │                                         │
   └──────── nominal 4 MHz RF span ─────────┘
                         │
                      9.632 MHz

The actual services occupy only part of this range, leaving useful guard space near the edges.


Virtual Receiver Channels

The following virtual receivers are currently generated by radiod.

ApplicationVirtual receiver centreOutput rateTypeDownstream application
HFDL group 18.9165 MHz96 kS/scomplex IQdumphfdl
HFDL group 210.0555 MHz96 kS/scomplex IQdumphfdl
HFDL group 311.3660 MHz96 kS/scomplex IQdumphfdl
DWD RTTY10.0995 MHz24 kS/sUSB audiofldigi
DWD WEFAX7.8781 MHz48 kS/sUSB audioIlma
FT8 30 m10.1360 MHz12 kS/sUSB audiojt9
WSPR 30 m10.1387 MHz12 kS/sUSB audiowsprd
RWM / WWV window9.9980 MHz24 kS/scomplex IQRWM decoder
Shannon VOLMET8.9570 MHz12 kS/sUSB audioOpus stream

This table shows an important feature of the architecture: the virtual receiver centre does not always have to be identical to the actual published station frequency.

For example, the RWM analysis channel is centred at approximately 9.998 MHz. With a 24 kS/s complex-IQ bandwidth it contains both the RWM 9.996 MHz signal and the nearby WWV 10 MHz frequency.

Similarly, the WEFAX virtual USB receiver is centred below the nominal 7880 kHz carrier so that the FAX tones appear at the required audio frequencies.


RTP and IP Multicast

KA9Q-Radio distributes signal streams using RTP over IP multicast.

This is one of the fundamental differences from a conventional Linux pipe.

A normal pipe creates a fixed one-to-one connection:

producer → consumer

A multicast stream behaves more like a local RF distribution bus:

                    ┌── consumer A
producer → multicast├── consumer B
                    └── consumer C

Consumers can join or leave the stream independently.

This has several practical advantages:

  • decoders can be restarted without restarting the SDR
  • several programs can observe the same receiver
  • recording can run in parallel with live decoding
  • debugging tools can temporarily join an existing stream
  • applications do not need to know anything about the SDR hardware

The architecture therefore separates the RF producer from the signal consumers.


Local Multicast Only

All current HF decoding applications run on the same N100 server.

There is therefore no reason to send high-rate SDR data across the physical LAN.

The KA9Q configuration uses:

iface=lo

This binds the signal distribution to the Linux loopback interface.

Conceptually:

                     N100 HF server
┌────────────────────────────────────────────────────┐
│                                                    │
│ RSPdx → radiod → RTP multicast → decoder          │
│                      │                             │
│                      ├── decoder                   │
│                      ├── recorder                  │
│                      └── analysis                  │
│                                                    │
└────────────────────────────────────────────────────┘

                 no SDR stream on LAN

Only processed results such as JSON, GeoJSON, text, PNG images or compressed audio are transferred to the web infrastructure.

This reduces unnecessary network traffic and keeps the SDR transport isolated from the rest of the network.


mDNS and Avahi

KA9Q-Radio can advertise streams using multicast DNS.

This allows applications to refer to signal sources by readable names rather than internal multicast addresses.

Examples used by the OE6VAG system include:

hfdl-8916.local
hfdl-10055.local
hfdl-11366.local
dwd-rtty.local
wefax-ilma.local
volmet-8957.local

The Linux Avahi service provides the required mDNS functionality.

The radiod status interface is likewise published under a local service name.

This allows utilities such as control and pcmrecord to discover receiver parameters dynamically.


pcmrecord – The Decoder Interface

One of the most useful KA9Q-Radio utilities in this installation is:

pcmrecord

Despite its name, it is not used only for recording.

It can subscribe to a KA9Q stream and write the received samples directly to standard output:

pcmrecord --reacquire --stdout --raw <stream>

The data can then be piped directly into another decoder.

The --reacquire option is especially useful for unattended operation. If the source stream temporarily disappears because radiod is restarted, pcmrecord can wait for the stream and reconnect.

This produces a robust service boundary:

radiod
   │
   │ RTP multicast
   ▼
pcmrecord --reacquire
   │
   │ stdout
   ▼
decoder

The downstream decoder does not have to implement KA9Q multicast reception itself.


HFDL Processing

HFDL requires complex IQ rather than ordinary demodulated audio.

Three 96 kS/s virtual IQ receivers are used.

HFDL Group 1

Virtual receiver:

centre: 8.9165 MHz
rate:   96 kS/s
type:   complex IQ

This receiver covers:

8885 kHz
8942 kHz
8948 kHz

HFDL Group 2

Virtual receiver:

centre: 10.0555 MHz
rate:   96 kS/s
type:   complex IQ

This receiver covers:

10030 kHz
10081 kHz

HFDL Group 3

Virtual receiver:

centre: 11.366 MHz
rate:   96 kS/s
type:   complex IQ

This receiver covers:

11348 kHz
11384 kHz

The processing chain is:

RSPdx
  ↓
radiod
  ↓
96 kS/s IQ multicast
  ↓
pcmrecord
  ↓
dumphfdl
  ↓
JSON messages
  ↓
aircraft / position processing
  ↓
GeoJSON
  ↓
web server
  ↓
HFDL live map

A simplified diagnostic pipeline looks like:

pcmrecord --reacquire --stdout --raw hfdl-8916.local | \
dumphfdl \
    --iq-file - \
    --sample-rate 96000 \
    --sample-format CF32 \
    --centerfreq 8916500

The three decoder instances are managed independently:

hfdl-group1-ka9q.service
hfdl-group2-ka9q.service
hfdl-group3-ka9q.service

Decoded data are combined by the local HFDL processing services before being transferred to the website.

👉 HFDL Live Map


DWD RTTY and SYNOP

The DWD RTTY receiver does not require IQ data.

radiod performs the USB demodulation and supplies a 24 kS/s audio stream.

RSPdx
  ↓
radiod
  ↓
10.0995 MHz virtual USB receiver
  ↓
24 kS/s audio
  ↓
pcmrecord / audio bridge
  ↓
ALSA loopback
  ↓
fldigi
  ↓
decoded RTTY text
  ↓
SYNOP / SHIP parser
  ↓
GeoJSON + text
  ↓
website

The virtual receiver centre is approximately 10.0995 MHz while the DWD signal being decoded is around 10.1008 MHz. The frequency offset places the FSK tones correctly inside the demodulated USB audio passband.

Several services participate in the chain, including:

dwd-rtty-ka9q.service
dwd-rtty-audio-bridge.service
dwd-rtty-xvfb.service
dwd-rtty-fldigi.service
dwd-rtty-push.service

A separate parser extracts SYNOP and SHIP reports from the received text and converts suitable reports into geographic data for the live map.

👉 DWD RTTY Live


WEFAX and Ilma

WEFAX originally used fldigi, but the productive autonomous receiver now uses Ilma.

The current virtual receiver is:

centre:      7.8781 MHz
sample rate: 48 kS/s
mode:        USB
stream:      wefax-ilma.local

The nominal DWD DDK3 transmission is around 7880 kHz.

The frequency offset places the weather-fax tones inside the required audio range.

The processing chain is:

RSPdx
  ↓
radiod
  ↓
48 kS/s USB audio
  ↓
pcmrecord
  ↓
Ilma
  ↓
start / phasing detection
  ↓
line synchronization
  ↓
timing / drift correction
  ↓
PNG weather chart
  ↓
web publication

The live decoder runs under:

wefax-ilma-live.service

Publication and history handling are automated separately.

The decoder is designed for unattended operation and does not require a graphical desktop.

The older fldigi WEFAX path is no longer the productive decoding path.

👉 DWD WEFAX Live


FT8 on 30 Metres

FT8 uses a narrow virtual USB receiver.

frequency:   10.136 MHz
sample rate: 12 kS/s
mode:        USB

The signal path is:

RSPdx
  ↓
radiod
  ↓
12 kS/s FT8 audio
  ↓
pcmrecord / recorder
  ↓
jt9
  ↓
decoded FT8 messages
  ↓
local processing
  ├── web publication
  └── PSK Reporter

jt9, which is part of the WSJT-X software suite, performs the actual decoding.

Each FT8 transmission interval is approximately 15 seconds, allowing the station to continuously monitor propagation on the 30 m band.

Relevant services include the decoder, recorder, PSK Reporter interface and web publisher.

👉 FT8 30 m Live


WSPR on 30 Metres

WSPR uses its own dedicated virtual receiver rather than sharing the FT8 audio channel.

frequency:   10.138700 MHz
sample rate: 12 kS/s
mode:        USB
decoder:     wsprd

The signal path is:

RSPdx
  ↓
radiod
  ↓
12 kS/s WSPR audio
  ↓
pcmrecord
  ↓
WSPR recording
  ↓
wsprd
  ↓
spots
  ↓
local statistics
  ↓
web publication

The main receiver services are:

wspr30-recorder.service
wspr30-decoder.service

Unlike interactive amateur-radio operation, the WSPR receiver is completely receive-only and autonomous.

The resulting spots are useful for observing propagation over longer periods because WSPR transmissions contain callsign, locator and transmitter-power information.

👉 WSPR 30 m Propagation Monitor


RWM Time-Signal Receiver

The RWM receiver is slightly different from the audio-based decoders.

RWM transmits its standard-frequency and time service on 9.996 MHz.

The KA9Q virtual receiver is centred at approximately:

9.998 MHz

and provides:

24 kS/s complex IQ

This intentionally covers a wider frequency window including both:

RWM  9.996 MHz
WWV 10.000 MHz

The productive RWM decoder currently analyses the RWM transmission.

The signal path is:

RSPdx
  ↓
radiod
  ↓
24 kS/s IQ
  ↓
pcmrecord
  ↓
RWM signal analysis
  ↓
pulse / timing detection
  ↓
DUT1 / dUT1 decoding
  ↓
status JSON
  ↓
web publication

The service runs as:

rwm-live.service

Depending on the current transmission segment, the decoder can identify:

  • second timing
  • minute timing
  • A1X coded timing
  • A1N timing
  • carrier-only intervals
  • DUT1 / dUT1 information
  • derived UT1 − UTC

The published carrier display is a receiver observation and not intended as a calibrated frequency-standard measurement.

👉 RWM Live Monitor


Shannon VOLMET

Shannon VOLMET is an example of the same KA9Q infrastructure being used without a digital message decoder.

The virtual receiver is:

frequency:   8957 kHz
mode:        USB
sample rate: 12 kS/s
audio:       approximately 300–3000 Hz
stream:      volmet-8957.local

The signal path is:

RSPdx
  ↓
radiod
  ↓
12 kS/s USB speech audio
  ↓
pcmrecord
  ↓
ffmpeg
  ↓
audio level adjustment
  ↓
Opus encoding
  ↓
streaming server
  ↓
web server
  ↓
browser

The complete stream is managed by:

volmet-stream.service

A simplified version of the receiver side is:

pcmrecord --reacquire --stdout --raw volmet-8957.local

The raw 12 kHz mono audio is converted and encoded as Opus before it is forwarded to the public web server.

This is a good example of multicast fan-out: an additional recorder or decoder could subscribe to the same VOLMET receiver without modifying the existing live stream.

👉 Shannon VOLMET Live


systemd Service Architecture

The complete system is designed to start automatically after boot.

At the lowest level is the SDRplay software service required for hardware access.

Above it is the single KA9Q radiod instance.

Conceptually:

network-online.target
        │
        ├──────────────┐
        │              │
        ▼              ▼
     Avahi        SDRplay service
        │              │
        └──────┬───────┘
               ▼
      radiod-hfdl.service
               │
               │ RTP multicast
               │
       ┌───────┼─────────────────────────────┐
       │       │       │       │       │     │
       ▼       ▼       ▼       ▼       ▼     ▼
     HFDL     DWD    WEFAX    FT8    WSPR   RWM
                                              │
                                              ▼
                                           VOLMET

The main KA9Q service is:

radiod-hfdl.service

The name is historical. It originally served HFDL, but the same radiod process has since developed into the central HF receiver for all current applications.

Renaming the service is therefore not technically required and would create unnecessary migration work.

The service depends on the SDRplay API and network/mDNS infrastructure being available before radiod starts.

The HFDL group services are linked to the main receiver service so that they follow the state of radiod.

Other applications use independently managed services and, where appropriate, pcmrecord --reacquire to recover automatically when their multicast stream reappears.


Failure Isolation

A major advantage of this architecture is that a failure in one decoder does not normally affect the other receivers.

For example:

HFDL decoder crashes
        │
        ▼
HFDL decoding stops

but:

radiod          continues
DWD RTTY        continues
WEFAX           continues
FT8             continues
WSPR            continues
RWM             continues
VOLMET          continues

Likewise, restarting the WSPR decoder does not require the RSPdx or KA9Q-Radio to be restarted.

Only a restart of radiod interrupts all virtual receivers because radiod is the common RF source.

For consumers using pcmrecord --reacquire, this interruption can usually be handled automatically.


Status and Diagnostics

The first diagnostic step is normally to verify the SDRplay and KA9Q services:

systemctl status sdrplay.service
systemctl status radiod-hfdl.service

Recent KA9Q log messages can be displayed with:

journalctl -u radiod-hfdl.service -n 100 --no-pager

All failed systemd services can be checked with:

systemctl --failed

KA9Q provides the control utility for inspecting the active virtual receivers:

control hfdl.local

A typical overview shows the receiver SSRC, mode, sample rate, centre frequency and multicast destination.

This is particularly useful after modifying the radiod configuration because all required channels should appear simultaneously.

Expected channel rates include:

HFDL          96 kS/s
DWD RTTY      24 kS/s
WEFAX         48 kS/s
FT8           12 kS/s
WSPR          12 kS/s
RWM / WWV     24 kS/s
VOLMET        12 kS/s

Checking Individual Services

A service can be inspected independently with systemd.

Examples:

systemctl status hfdl-group1-ka9q.service
systemctl status dwd-rtty-fldigi.service
systemctl status wefax-ilma-live.service
systemctl status wspr30-decoder.service
systemctl status rwm-live.service
systemctl status volmet-stream.service

Live logs can be followed with:

journalctl -fu <service-name>

For example:

journalctl -fu volmet-stream.service

or:

journalctl -fu rwm-live.service

This separation makes troubleshooting considerably easier than with a single monolithic SDR application.


Testing a Multicast Stream

Because the signal streams are independent of the decoders, a stream can be tested directly.

For a named KA9Q receiver:

pcmrecord --reacquire --stdout --raw <receiver>.local

For HFDL, the raw IQ stream can be piped directly into dumphfdl.

For an audio service, the same stream can temporarily be recorded or passed to an audio conversion tool.

This is one of the most useful properties of the architecture during development: the RF receiver does not have to be modified simply to test another decoder.


Adding Another HF Service

Adding another autonomous HF application normally does not require another SDR.

As long as the new signal lies within the sampled RF range, the typical procedure is:

  1. Select an appropriate virtual receiver centre frequency.
  2. Choose IQ or demodulated audio.
  3. Select a suitable output sample rate.
  4. Define the required filter bandwidth.
  5. Add the channel to the KA9Q configuration.
  6. Restart radiod.
  7. Verify the new channel with control.
  8. Create a separate decoder or recorder service.
  9. Use pcmrecord --reacquire where appropriate.
  10. Publish only the processed result to the web server.

A new service therefore becomes another branch of the existing receiver tree:

                    radiod
                      │
        ┌─────────────┼─────────────┐
        │             │             │
     existing      existing       new
     receiver      receiver      receiver
                                      │
                                      ▼
                                  new decoder

This is the main reason the system scales much better than an architecture based on one USB SDR per application.


Data Processing Versus Web Publishing

The SDR server is responsible for radio reception and signal processing.

The public web server does not directly access the SDR.

Only processed data are transferred outward.

Depending on the service this may be:

HFDL       → JSON / GeoJSON
DWD RTTY   → decoded text
SYNOP      → GeoJSON
WEFAX      → PNG images
FT8        → decoded message data
WSPR       → spot and propagation statistics
RWM        → JSON status
VOLMET     → compressed Opus audio

The general architecture is therefore:

RF
 ↓
SDR server
 ↓
decoder
 ↓
processed result
 ↓
web server
 ↓
browser

rather than:

RF
 ↓
raw SDR stream
 ↓
public Internet

This keeps the high-rate radio processing local while the public side only handles comparatively lightweight results.


Why Not Use a Separate SDR for Every Service?

Using one SDR per application would certainly be possible.

However, the current set of services would require several receivers, USB ports, cables and antenna splitters.

The shared KA9Q architecture avoids this.

Traditional approach:

antenna
   │
splitter
   ├── SDR → HFDL
   ├── SDR → RTTY
   ├── SDR → WEFAX
   ├── SDR → FT8
   ├── SDR → WSPR
   ├── SDR → RWM
   └── SDR → VOLMET

The actual OE6VAG architecture is:

antenna
   │
RSPdx
   │
radiod
   ├── HFDL
   ├── RTTY
   ├── WEFAX
   ├── FT8
   ├── WSPR
   ├── RWM
   └── VOLMET

The second approach also guarantees that all applications observe the same antenna and RF front end.


Limitations

The shared receiver concept also has limitations.

All active channels must fit inside the RF spectrum currently sampled by the RSPdx.

A service far outside this range cannot simply be added as another virtual receiver without changing the RF centre frequency or increasing the sampled bandwidth.

All applications also share the same physical antenna and front-end gain environment.

A gain setting that is optimal for one weak signal may not necessarily be ideal for every other signal in the sampled spectrum.

Finally, radiod is a common dependency. If the central KA9Q receiver stops, every downstream HF service temporarily loses its signal source.

These trade-offs are acceptable for the present monitoring system because the required services occupy a relatively compact section of HF and the architecture greatly simplifies continuous multi-service reception.


Current HF Signal Distribution

The resulting OE6VAG HF station can be summarized as:

Magnetic Loop
     │
     ▼
SDRplay RSPdx
     │
     │ 4 MS/s wideband IQ
     ▼
KA9Q-Radio / radiod
     │
     ├── 8.9165 MHz / 96 kS/s IQ ──→ HFDL group 1
     │
     ├── 8.9570 MHz / 12 kS/s USB ─→ Shannon VOLMET
     │
     ├── 9.9980 MHz / 24 kS/s IQ ──→ RWM / WWV window
     │
     ├── 10.0555 MHz / 96 kS/s IQ ─→ HFDL group 2
     │
     ├── 10.0995 MHz / 24 kS/s USB → DWD RTTY / SYNOP
     │
     ├── 10.1360 MHz / 12 kS/s USB → FT8
     │
     ├── 10.1387 MHz / 12 kS/s USB → WSPR
     │
     ├── 11.3660 MHz / 96 kS/s IQ ─→ HFDL group 3
     │
     └── 7.8781 MHz / 48 kS/s USB ─→ DWD WEFAX / Ilma

The order in this diagram represents logical signal distribution rather than frequency order.


Live Results

The individual outputs can be viewed on the OE6VAG website:

All receivers are also summarized on:

👉 OE6VAG Live Data


Related Pages

For the overall receiving-station architecture:

👉 Radio Monitoring – Autonomous Receiving Stations

For signal descriptions, decoder experiments and LF/HF reception examples:

👉 LF and HF Utility Monitoring


About This Implementation

This installation is not intended as a generic KA9Q-Radio reference configuration.

It documents one practical use of KA9Q-Radio as the centre of a continuously operating multi-channel HF monitoring station.

The important architectural idea is simple:

Digitize the RF spectrum once, then create as many independent software receivers as required.

For this station, that turns one RSPdx and one magnetic-loop antenna into several simultaneously operating autonomous receivers, each with its own decoder, processing chain and live web output.