What
Add a client-side CQUAM (Compatible Quadrature Amplitude Modulation) AM Stereo decoder
to AetherSDR, enabling the radio to receive and decode AM Stereo broadcasts — those
transmitted using the Motorola C-QUAM standard — and output them as proper stereo audio.
When tuned to an AM station that is broadcasting C-QUAM stereo, the user would enable
the decoder (e.g. via a toggle in the RX Applet or VFO widget AM tab), and the audio
output would change from mono to stereo, with audible left/right channel separation
and a stereo indicator displayed in the UI.
Why
AM Stereo via C-QUAM is a real and still-active broadcast standard. A number of AM
stations worldwide (particularly in the US, Canada, Japan, and Australia) continue to
transmit C-QUAM stereo today. Conventional SDR clients receive AM as mono and discard
the stereo subcarrier entirely.
FlexRadio hardware is well-suited for AM Stereo reception — it has sufficient ADC
dynamic range and bandwidth, and delivers raw IQ-derived audio to the client. However,
SmartSDR for Windows has no C-QUAM decoder, so AetherSDR would have a genuine
capability advantage here. This is a feature that has long been requested by
broadcast-band listeners and vintage radio enthusiasts in the SDR community.
The problem being solved: AM Stereo audio is collapsed to mono by the current
AudioEngine pipeline. The stereo information encoded in the quadrature component
of the C-QUAM signal is simply discarded.
How Other Clients Do It
SDR# (SDRsharp) — Windows
SDR# supports AM Stereo via a community plugin that implements C-QUAM decoding
on the raw IQ baseband. It exposes a plugin panel with a stereo/mono lock indicator
and a pilot detection LED. When the decoder locks, audio switches to stereo
automatically.
GQRX — Linux/macOS
GQRX does not natively support C-QUAM as of writing. AM mode outputs mono only.
This is a known gap in the Linux SDR ecosystem — implementing this in AetherSDR
would be a meaningful differentiator.
Airspy HF+ Discovery / Spy Server
The Airspy ecosystem (via SDR#) supports C-QUAM natively when used with compatible
plugins. Documented in the Airspy community forums.
Vintage hardware reference
The Motorola MC13028A and MC13020P chips were the canonical C-QUAM decoder ICs.
Their datasheets describe the demodulation algorithm precisely and are freely
available — they are an excellent implementation reference for software decoding.
Suggested Behavior
Mode trigger
- The decoder activates only when the slice mode is
AM or SAM — it is
irrelevant in USB/LSB/FM/CW/etc.
- A "AM Stereo" toggle button appears in the RX Applet (or the VFO AM tab,
similar to how CW decode options appear in the CW tab).
Signal flow
The C-QUAM signal is received as stereo float32 audio (PCC 0x03E3) at 24 kHz.
C-QUAM encodes stereo as:
L+R → AM envelope (standard AM demodulation, already decoded by the radio DSP)
L-R → quadrature (Q) component of the composite carrier
The radio's AM mode demodulates only the envelope (L+R). To recover the Q
component (L-R difference signal), the decoder would need access to the IQ
baseband before AM envelope detection — or operate on the raw audio delivered
in the VITA-49 stream if the radio provides the full complex baseband.
Note: This may require requesting a DAX IQ stream (issue #124) rather
than the standard remote audio stream, since envelope-detected AM audio has
already discarded the Q component. Alternatively, if the radio can be put into
a wide USB/LSB mode centered on the AM carrier, the client could perform its
own envelope detection and recover both L+R and L-R from the IQ pair in the
audio stream. This needs investigation.
Decoding steps (software)
- Receive IQ pair from VITA-49 audio (float32 stereo, big-endian, 24 kHz)
- Envelope detect:
mono = sqrt(I² + Q²) → L+R signal
- Phase-lock loop: lock onto the 25 Hz pilot (or the carrier itself) to
establish the C-QUAM phase reference
- Multiply Q component by PLL reference → L-R difference signal
- Matrix:
L = (L+R + L-R) / 2, R = (L+R - L-R) / 2
- Feed L and R to the stereo
QAudioSink pipeline
UI indicators
- "ST" indicator (cyan, similar to CwDecoder's confidence display) shown in
the VFO widget or RX Applet when stereo lock is achieved
- "MONO" fallback when pilot is not detected or SNR is too low
- Optional: stereo separation meter (L-R level as a small horizontal gauge)
Settings persistence
// In AppSettings
s.setValue("AmStereoEnabled", "True"); // per-slice or global
s.setValue("AmStereoMinSnr", "15"); // dB threshold for auto-lock
New class: CquamDecoder
Modeled after CwDecoder — takes feedAudio(float* left, float* right, int frames)
and emits:
signals:
void stereoLockChanged(bool locked);
void audioReady(QVector<float> left, QVector<float> right);
Wired into AudioEngine::feedAudioData() when AM Stereo is enabled and mode is AM/SAM,
replacing the mono envelope output with the decoded stereo pair.
Protocol Hints
Standard remote audio (current)
stream create type=remote_audio_rx compression=none
PCC 0x03E3 delivers float32 stereo at 24 kHz — but in AM mode, the radio's own
DSP has already performed envelope detection, and both channels carry the same mono
audio. The Q component is lost at this point.
DAX IQ (needed — see issue #124)
stream create type=dax_iq daxIQ=1 pan=0x40000000
PCC unknown — needs Wireshark capture. This would deliver raw complex baseband IQ
before the radio's own demodulation, allowing full client-side C-QUAM decode.
Mode forcing workaround (to investigate)
Setting the slice to a narrow DSB or raw IQ mode while tuning to an AM carrier
may expose both I and Q components via the existing audio stream. Needs testing
with firmware v1.4.0.0.
Overall protocol status: Partially known — DAX IQ stream format needs research
(see #124). Standard remote audio stream is insufficient for full C-QUAM decode.
Labels
feature · audio · dsp · help wanted
Related Issues
What
Add a client-side CQUAM (Compatible Quadrature Amplitude Modulation) AM Stereo decoder
to AetherSDR, enabling the radio to receive and decode AM Stereo broadcasts — those
transmitted using the Motorola C-QUAM standard — and output them as proper stereo audio.
When tuned to an AM station that is broadcasting C-QUAM stereo, the user would enable
the decoder (e.g. via a toggle in the RX Applet or VFO widget AM tab), and the audio
output would change from mono to stereo, with audible left/right channel separation
and a stereo indicator displayed in the UI.
Why
AM Stereo via C-QUAM is a real and still-active broadcast standard. A number of AM
stations worldwide (particularly in the US, Canada, Japan, and Australia) continue to
transmit C-QUAM stereo today. Conventional SDR clients receive AM as mono and discard
the stereo subcarrier entirely.
FlexRadio hardware is well-suited for AM Stereo reception — it has sufficient ADC
dynamic range and bandwidth, and delivers raw IQ-derived audio to the client. However,
SmartSDR for Windows has no C-QUAM decoder, so AetherSDR would have a genuine
capability advantage here. This is a feature that has long been requested by
broadcast-band listeners and vintage radio enthusiasts in the SDR community.
The problem being solved: AM Stereo audio is collapsed to mono by the current
AudioEnginepipeline. The stereo information encoded in the quadrature componentof the C-QUAM signal is simply discarded.
How Other Clients Do It
SDR# (SDRsharp) — Windows
SDR# supports AM Stereo via a community plugin that implements C-QUAM decoding
on the raw IQ baseband. It exposes a plugin panel with a stereo/mono lock indicator
and a pilot detection LED. When the decoder locks, audio switches to stereo
automatically.
GQRX — Linux/macOS
GQRX does not natively support C-QUAM as of writing. AM mode outputs mono only.
This is a known gap in the Linux SDR ecosystem — implementing this in AetherSDR
would be a meaningful differentiator.
Airspy HF+ Discovery / Spy Server
The Airspy ecosystem (via SDR#) supports C-QUAM natively when used with compatible
plugins. Documented in the Airspy community forums.
Vintage hardware reference
The Motorola MC13028A and MC13020P chips were the canonical C-QUAM decoder ICs.
Their datasheets describe the demodulation algorithm precisely and are freely
available — they are an excellent implementation reference for software decoding.
Suggested Behavior
Mode trigger
AMorSAM— it isirrelevant in USB/LSB/FM/CW/etc.
similar to how CW decode options appear in the CW tab).
Signal flow
The C-QUAM signal is received as stereo float32 audio (PCC
0x03E3) at 24 kHz.C-QUAM encodes stereo as:
The radio's
AMmode demodulates only the envelope (L+R). To recover the Qcomponent (L-R difference signal), the decoder would need access to the IQ
baseband before AM envelope detection — or operate on the raw audio delivered
in the VITA-49 stream if the radio provides the full complex baseband.
Decoding steps (software)
mono = sqrt(I² + Q²)→ L+R signalestablish the C-QUAM phase reference
L = (L+R + L-R) / 2,R = (L+R - L-R) / 2QAudioSinkpipelineUI indicators
the VFO widget or RX Applet when stereo lock is achieved
Settings persistence
New class:
CquamDecoderModeled after
CwDecoder— takesfeedAudio(float* left, float* right, int frames)and emits:
signals: void stereoLockChanged(bool locked); void audioReady(QVector<float> left, QVector<float> right);Wired into
AudioEngine::feedAudioData()when AM Stereo is enabled and mode is AM/SAM,replacing the mono envelope output with the decoded stereo pair.
Protocol Hints
Standard remote audio (current)
PCC
0x03E3delivers float32 stereo at 24 kHz — but in AM mode, the radio's ownDSP has already performed envelope detection, and both channels carry the same mono
audio. The Q component is lost at this point.
DAX IQ (needed — see issue #124)
PCC unknown — needs Wireshark capture. This would deliver raw complex baseband IQ
before the radio's own demodulation, allowing full client-side C-QUAM decode.
Mode forcing workaround (to investigate)
Setting the slice to a narrow DSB or raw IQ mode while tuning to an AM carrier
may expose both I and Q components via the existing audio stream. Needs testing
with firmware v1.4.0.0.
Overall protocol status: Partially known — DAX IQ stream format needs research
(see #124). Standard remote audio stream is insufficient for full C-QUAM decode.
Labels
feature·audio·dsp·help wantedRelated Issues