Waterfall blanks/flickers during TX only when AetherSDR is the active window

Open
#2,126 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
cpp, macos

Research direction

Start by tracing PanadapterStream::processPacket() for PCC 0x8004, SpectrumWidget::updateWaterfallRow(), and SpectrumWidget::paintEvent(), comparing packet and frame behavior during focused and unfocused TX. Then inspect AudioEngine and QAudioSource lifecycle alongside the waterfall render timer. Done means the waterfall remains continuous during WSJT-X TX, with no dropped frames and no unnecessary QAudioSource activity in DIGI/DAX mode.

Written by the indexing model from the issue text.

Description

enhancement GUI macOS maintainer-review priority: medium spectrum
Request preparation
  • I used an AI assistant to help structure this request
  • I checked for existing issues covering the same feature
What would you like?

https://github.com/user-attachments/assets/aba34e71-d7d9-44ad-8909-244d14a60516

Waterfall blanks/flickers during TX only when AetherSDR is the active window

Labels: bug, spectrum, audio


What happened

During a WSJT-X transmission sequence (FT8/FT4), the waterfall in
SpectrumWidget flickers on and off — alternating between scrolling
normally and going fully blank — but only while the AetherSDR window
is in the foreground
. When WSJT-X is the active window during the
same TX phase, the AetherSDR waterfall continues scrolling without
interruption. After TX ends and the radio returns to RX, the waterfall
recovers immediately regardless of which window is active.

Videos attached by reporter demonstrating both cases.

What I expected

The waterfall should scroll continuously throughout the full TX/RX
cycle regardless of which application window has focus. SmartSDR on
Windows scrolls the waterfall uninterrupted during TX.

Steps to reproduce

  1. Set up WSJT-X with DAX or VOX PTT targeting the FlexRadio.
  2. Connect AetherSDR to the same radio. Confirm waterfall is scrolling
    normally in RX.
  3. Click the AetherSDR window so it is the active foreground window.
  4. Wait for WSJT-X to begin a TX sequence (or trigger MOX manually).
  5. Observe: waterfall alternates between scrolling and blanking
    during the TX phase.
  6. Click the WSJT-X window so AetherSDR loses focus.
  7. Trigger another TX sequence.
  8. Observe: AetherSDR waterfall scrolls normally — bug does not
    occur while AetherSDR is in the background.

Environment

  • OS: MacOS 26.3.1 (a) (25D771280a)
  • Radio: FlexRadio 6400
  • Firmware: v1.4.5.39794
  • AetherSDR: v0.9.1
  • External software: WSJT-X 3.1.0 improved plus, using DAX or VOX PTT

Root cause analysis

The window-focus correlation is the critical clue. When AetherSDR is
the active window, Qt delivers keyboard events, mouse events, and
possibly repaint requests
to it. Three plausible mechanisms:

Hypothesis A — QAudioSource mic capture activated by window focus (most likely)

When AetherSDR becomes the foreground window, Qt may activate or
prioritize the QAudioSource microphone capture pipeline
(AudioEngine::onTxAudioReady()). If QAudioSource is running in the
same thread as the VITA-49 UDP socket (PanadapterStream), or if its
callback fires at a rate that saturates the event loop, waterfall tile
processing (updateWaterfallRow()) can be delayed or dropped entirely.

Check: Is QAudioSource started unconditionally on connect, or only
when TX is active? If it is always running and polling, switching window
focus may push it into an active-read state.

Hypothesis B — Main thread event loop saturated by focus/repaint events

QEvent::WindowActivate and QEvent::ApplicationActivated cause Qt to
re-render the entire widget hierarchy. If SpectrumWidget::paintEvent()
is slow (large waterfall pixmap blit), and focus changes re-trigger
paints at high rate during TX, the UDP receive callbacks in
PanadapterStream may be starved while the main thread is busy painting.

Check: Profile paintEvent() duration. Add a frame-drop counter to
updateWaterfallRow() — if drops spike when AetherSDR is focused during
TX, this is the mechanism.

Hypothesis C — TX audio thread competing with waterfall render timer

WSJT-X drives PTT via CAT/rigctld or VOX. When AetherSDR is focused,
user input (keyboard, mouse) may trigger QAudioSource to start reading
mic audio for TX even in DIGI/DAX mode. The TX audio thread and the
waterfall render timer (QTimer firing update() on SpectrumWidget)
may be competing for the Qt event loop.

Suggested fix

Step 1 — Confirm packet arrival rate:
Add a temporary qDebug() counter to
PanadapterStream::processPacket() for PCC 0x8004. Log packets/second
before and during TX, with and without AetherSDR focused. If the rate
drops during TX+focus, the issue is upstream of SpectrumWidget.

Step 2 — Check QAudioSource lifecycle:
In AudioEngine, verify that QAudioSource is only started when TX is
actually active (xmit 1 received), not on window focus or connection.
If it is always open, consider stopping it when TransmitModel reports
TX inactive.

Step 3 — Move waterfall rendering off the main thread:
If updateWaterfallRow() is called directly from the VITA-49 receive
thread via a direct signal connection, ensure the connection type is
Qt::QueuedConnection so waterfall updates are queued to the main
thread without blocking the UDP reader.

Step 4 — Suppress QAudioSource during DIGI/DAX mode:
When the active slice mode is DIGU/DIGL and DAX TX is in use, the
QAudioSource mic path should be fully idle. Confirm
AudioEngine does not open the mic device in this case.

Acceptance criteria

  • Waterfall scrolls continuously throughout a WSJT-X TX phase with
    AetherSDR as the foreground window
  • No dropped waterfall frames (PCC 0x8004) observable in debug
    logging when AetherSDR is focused during TX
  • QAudioSource is confirmed not active during DIGI/DAX TX when
    mic input is not needed
  • Behavior is identical whether AetherSDR or WSJT-X is the active
    window
  • No regression in SSB/CW TX waterfall behavior
Dominant language
C++
Stars
221
Forks
117
Avg merge
2d 7h
Merged PRs (30d)
299

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from aethersdr/AetherSDR

All issues in aethersdr/AetherSDR

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.