Skip to content

Client Side recording produces a silent file — TX audio is never captured (QsoRecorder::feedTxAudio has no signal connected) #3556

@TnxQSO-Admin

Description

@TnxQSO-Admin

Report preparation

  • I used the AI-assisted bug report tool (Help → Support → File an Issue)
  • I have attached a support bundle or log file

What happened?

What happened

With record mode set to Client Side (recording stored on the PC), the resulting WAV file contains only a 44-byte header and zero audio samples. It is silent both in AetherSDR playback and in an external player (tested with Haruna).

With record mode set to Radio Side, the exact same recording works correctly and contains audio (both RX and TX).

This was observed during normal SSB/phone operation over a remote connection, where RX audio is heard normally through the client output device (Focusrite Scarlett 4i4). So decoded RX audio is definitely flowing through the client; the recording still ends up empty.

Environment

  • OS: Linux (Arch / CachyOS, KDE)
  • Connection: remote
  • AetherSDR version: 26.5.2 (please confirm — this is the value in CLAUDE.md on main; replace with your actual build)
  • Output device: Focusrite Scarlett 4i4 (RX monitor heard normally during the test)
  • Note: the root cause appears to be a missing client-side signal connection and is expected to be independent of radio model, firmware, and OS.

Suggested fix

A read-only static investigation of the recording subsystem points to a single root cause: no audio source is ever connected to QsoRecorder::feedTxAudio, and during transmit there is no RX audio to fall back on.

Findings (file:line references from a read-only code read):

  • QsoRecorder::feedTxAudio is declared (XXXQsoRecorder.hXXX) and implemented (XXXQsoRecorder.cppXXX) and is correctly designed: it calls float32ToInt16() on float32 input and writes to the WAV file.
  • There is no connect() anywhere in the codebase that wires any signal to QsoRecorder::feedTxAudio. The slot is never called.
  • The only signal wired to the recorder is RX audio:
connect(m_radioModel.panStream(), &PanadapterStream::audioDataReady,
        m_qsoRecorder, &QsoRecorder::feedRxAudio);

(in the MainWindow constructor). feedRxAudio only checks m_recording and m_file — no filtering.

  • During transmit, the radio stops sending RX audio over the network, so audioDataReady carries silence. feedRxAudio writes nothing, feedTxAudio is never called, m_dataBytes stays 0, and patchWavHeader() writes a data size of 0 → valid 44-byte header, no samples.
  • The only signal-based TX PCM tap, AudioEngine::txRawPcmReady, is emitted only when RADE digital mode is active (inside the m_radeMode block in XXXAudioEngine.cppXXX). For normal SSB/phone TX it never fires, so simply wiring txRawPcmReady → feedTxAudio would only fix TX recording in RADE mode, not SSB.
  • The TX capture path that already works (the "Aetherial Audio" strip record button) does not use signals at all — it uses ClientPuduMonitor / m_finalMonitor via a direct atomic callback on the audio thread (the post-final-limiter monitor tap). This is the source that actually carries normal SSB TX/monitor audio in the client.
  • Minor: the comment near the recorder connection in XXXMainWindow.cppXXX states that txRawPcmReady is int16 and would need separate handling. That comment is inaccurate — the signal carries float32, and feedTxAudio already converts float32 → int16. Worth correcting alongside the fix.

Fix direction (needs maintainer review per the architecture boundary in CLAUDE.md — this touches signal routing):

Route a TX PCM source into QsoRecorder so that Client Side recording captures TX. Because txRawPcmReady is RADE-only, the source that covers normal SSB is the same post-limiter monitor tap that the Aetherial Audio strip already uses successfully (ClientPuduMonitor / m_finalMonitor).

There is also a design decision for the maintainer: whether Client Side should write a single interleaved-in-time RX/TX file (matching Radio Side behavior, switching source on transmit state) or keep RX and TX handling explicit. I am not prescribing the exact wiring — flagging the root cause and the viable source.

Related

Suggested labels: bug, audio

What did you expect?

What I expected

The storage location must not change what gets recorded. Radio Side records both RX and TX into the file. Client Side should produce an equivalent recording — RX while receiving, my own TX (monitor) audio while transmitting — just written to local disk instead of the radio.

Steps to reproduce

Steps to reproduce

  1. Connect to the radio remotely. Confirm RX audio is heard through the client output device.
  2. Set record mode to Client Side (RadioSetupDialog → "Client Side").
  3. Press the record button on the VfoWidget / panadapter.
  4. Receive for a few seconds, then transmit (SSB) for a few seconds, then receive again.
  5. Stop recording. Open the resulting WAV in AetherSDR or an external player.

Result: the file is 44 bytes (header only), no audio.

Repeat steps 2 to 5 with Radio Side selected. Result: the file contains audio (RX + TX).

AetherSDR version

v26.6.2

Radio model & firmware

AU-520 4.2.20.41343

Operating system

Linux

OS version and hardware

CachyOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    audioAudio engine and streamingawaiting-responseWaiting for reporter to provide additional informationbugSomething isn't workingmaintainer-reviewRequires maintainer review before any action is takenpriority: mediumMedium priority

    Type

    No type
    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