Skip to content

CW decoder not working #474

Description

@KnikmanAV

Here is your complete bug report, ready to paste into GitHub:

Title: CW decoder shows no text output despite visible signal and working audio
What happened?
The CW decode panel appears as expected when switching to CW mode (both CWU and CWL), but it produces no decoded text output whatsoever. A CW signal is clearly visible on the waterfall and FFT spectrum, and RX audio is working correctly — the CW tones are audible through the speaker. Despite this, the ggmorse-based decoder emits nothing: the text area remains blank regardless of signal strength, speed, or pitch. The issue reproduces in both CWU and CWL modes.
What did you expect?
When a CW signal is visible on the waterfall and audible in the RX audio, the CW decoder panel should display decoded text in real time, color-coded by confidence level (green → yellow → orange → red). The decoder is expected to auto-detect pitch and keying speed and begin producing output within a few seconds of receiving a clean signal.
Steps to reproduce

Launch AetherSDR 0.7.16 on macOS and connect to a FLEX-8400 (fw 4.1.5.39794).
Tune to a frequency with an active CW signal (confirm signal is visible on waterfall and audible).
Set slice mode to CWU (or CWL).
Observe that the CW decoder panel appears automatically.
Wait for decoded text output — none appears. The decoder panel remains blank.
Repeat in CWL mode — same result.

Radio model & firmware

Radio: FLEX-8400
Firmware: 4.1.5.39794

OS & version

OS: macOS
AetherSDR: 0.7.16
Qt: 6.7.3

Developer Notes
Likely source files and functions:

src/core/CwDecoder.cpp / CwDecoder.h — primary suspect. The decoder receives audio via CwDecoder::feedAudio(), which is called from AudioEngine after the NR2/RN2 pipeline. Check that feedAudio() is actually being called (add a counter/log) and that ggmorse gm_get_rx_data() is returning results.
src/core/AudioEngine.cpp — the CW decode path branches off after NR2/RN2 processing. Verify the slice mode check that gates CwDecoder::feedAudio() is correctly recognising both CWU and CWL modes on fw 4.1.5.39794. The CLAUDE.md notes a CW passband fix ("filter centered on carrier, radio BFO handles pitch offset") — it is possible the audio being fed to the decoder is at an unexpected pitch for ggmorse's auto-detection range.
src/core/Resampler.cpp — audio from VITA-49 PCC 0x03E3 arrives as 24 kHz float32 stereo. ggmorse expects a specific sample rate; confirm the r8brain polyphase resampler is converting to the rate ggmorse was initialised with. A mismatch here would produce silence or gibberish at the decoder without any crash.
src/gui/MainWindow.cpp — the CW decode overlay toggle (Radio Setup → Phone/CW) and the auto-show logic in CW mode. Confirm the decoder is enabled (CwDecodeEnabled in AppSettings) and that the panel's feedAudio signal connection survives a mode switch.
src/models/SliceModel.cpp — check that the mode string reported by fw 4.1.5.39794 for CW matches what AudioEngine and CwDecoder compare against. Firmware differences may use a slightly different token (e.g. CW vs CWU).

Logging to enable (Help → Support):
Enable the following diagnostic categories before reproducing:

Audio — confirms feedAudioData() is receiving VITA-49 float32 frames on PCC 0x03E3
DSP / NR — confirms the NR2/RN2 pipeline is passing audio through to the CW branch
CW Decoder — should show ggmorse input frame counts, pitch estimates, and any decode results
Protocol / Slice — confirms the slice mode is being set to CWU/CWL correctly and that the mode string matches what the decoder gate expects

Potential root causes, in order of likelihood:

Sample rate mismatch between Resampler output and ggmorse initialisation rate — ggmorse receives audio at the wrong rate on macOS due to a 48 kHz fallback path (noted in CLAUDE.md: "48kHz audio fallback for devices that don't support 24kHz"), causing the decoder to see signals at the wrong pitch and produce no output.
Mode-string mismatch gating feedAudio() — fw 4.1.5.39794 (FLEX-8400) may emit a different mode token than the FLEX-8600 fw 1.4.0.0 the code was developed against, causing the if (mode == CWU || mode == CWL) guard in AudioEngine to never fire.
CW decode overlay disabled in AppSettings — CwDecodeEnabled may default to "False" on a fresh install; the panel appearing does not necessarily mean decoding is active.
ggmorse pitch auto-detection out of range — the CW passband fix (BFO-offset audio) may place the CW tone outside the pitch range ggmorse scans by default, preventing lock-on even with a strong signal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions