Skip to content

Fix macOS DAX RX audio corrupted after float32 migration#1242

Merged
ten9876 merged 1 commit into
aethersdr:mainfrom
pepefrog1234:fix/macos-dax-float32-mismatch
Apr 13, 2026
Merged

Fix macOS DAX RX audio corrupted after float32 migration#1242
ten9876 merged 1 commit into
aethersdr:mainfrom
pepefrog1234:fix/macos-dax-float32-mismatch

Conversation

@pepefrog1234

Copy link
Copy Markdown
Contributor

Summary

The float32 audio pipeline migration (502b934, b0c49d7) missed the macOS VirtualAudioBridge and the PCC_IF_NARROW DAX path in PanadapterStream, causing severe audio corruption on the macOS DAX virtual sound card. Digital mode software (VARA HF, WSJT-X) connected via the AetherSDR DAX device sees the audio spectrum displaced from the expected ~1500 Hz center frequency, making modems unable to decode signals.

Root Cause

After the float32 migration, PanadapterStream::daxAudioReady emits float32 stereo PCM. All downstream consumers were updated accordingly — TciServer::onDaxAudioReady, RADEEngine::feedRxAudio, and the Linux PipeWireAudioBridge (3400133) — but the macOS VirtualAudioBridge::feedDaxAudio() was not. It still reinterpret_cast's the incoming QByteArray as int16_t* and divides by 32768.0f:

// Before (broken): reads float32 bytes as int16
const auto* samples = reinterpret_cast<const int16_t*>(pcm.constData());
const float scale = chGain / 32768.0f;
block->ringBuffer[wp % RING_SIZE] = samples[i] * scale;

When float32 samples (4 bytes each) are reinterpreted as int16 (2 bytes each), every sample value is completely wrong — the ring buffer is filled with garbage, and the HAL plugin outputs corrupted audio to VARA/WSJT-X.

Additionally, PanadapterStream's PCC_IF_NARROW path (full-bandwidth stereo DAX) was still converting radio float32 → int16 via qBound(-1.0f, f, 1.0f) * 32767.0f before emission. This was missed by b0c49d7 which only fixed PCC_IF_NARROW_REDUCED. The lossy int16 conversion (clamping to ±1.0) combined with the format mismatch in VirtualAudioBridge compounded the corruption.

Fix

  • VirtualAudioBridge::feedDaxAudio(): Read payload as float*, compute sample count by dividing by sizeof(float), multiply by chGain directly (no /32768 normalization). Update RMS meter to operate on float samples natively.
  • PanadapterStream PCC_IF_NARROW path: Emit native float32 stereo (memcpy from big-endian-swapped uint32 to float) instead of converting to int16. Now consistent with PCC_IF_NARROW_REDUCED and all downstream consumers.
  • Info.plist.in: Add NSLocalNetworkUsageDescription — required by macOS for UDP broadcast discovery of FlexRadio devices on port 4992. Without this key, the radio does not appear in the device list.

Test plan

  • Build on macOS (ARM64, Qt 6.11)
  • Connect to FLEX-8600 (FW 1.4.0.0) in DIGU mode with DAX enabled
  • Verify VARA HF v4.9.0 receives audio spectrum correctly centered at ~1500 Hz via AetherSDR DAX virtual sound card
  • Verify radio appears in device list on macOS (NSLocalNetworkUsageDescription)

🤖 Generated with Claude Code

The float32 audio pipeline migration (502b934) and its follow-up fix
for PCC_IF_NARROW_REDUCED (b0c49d7) updated PanadapterStream to emit
float32 stereo from daxAudioReady, and updated all downstream consumers
(TciServer, RADEEngine, PipeWireAudioBridge) accordingly. However, two
paths on macOS were missed:

1. VirtualAudioBridge::feedDaxAudio() still reinterpret_cast'd the
   incoming QByteArray as int16_t* and divided by 32768.0f. After the
   migration, the payload is float32 — reading it as int16 produces
   completely wrong sample values, causing severe frequency shift and
   distortion in the DAX virtual audio device. Digital mode software
   (VARA HF, WSJT-X) connected via the AetherSDR DAX sound card would
   see the audio spectrum displaced from the expected 1500 Hz center
   frequency, making the modem unable to decode.

2. PanadapterStream's PCC_IF_NARROW (full-bandwidth stereo DAX) path
   was still converting float32 big-endian samples back to int16 via
   qBound/clamp before emitting. This path was missed by b0c49d7
   which only fixed PCC_IF_NARROW_REDUCED. The clamp to ±1.0 before
   int16 scaling introduced lossy truncation, and the format mismatch
   with VirtualAudioBridge compounded the corruption.

Fix:
- VirtualAudioBridge::feedDaxAudio(): read payload as float*, divide
  sample count by sizeof(float) instead of 2, multiply by chGain
  directly (no /32768 normalization needed for float input). Update
  RMS meter calculation to operate on float samples natively.
- PanadapterStream PCC_IF_NARROW: emit native float32 stereo (memcpy
  from big-endian-swapped uint32 to float) instead of converting to
  int16. This matches PCC_IF_NARROW_REDUCED and all downstream
  consumers.

Also adds NSLocalNetworkUsageDescription to the macOS Info.plist
template — required by macOS for UDP broadcast discovery of FlexRadio
devices on port 4992. Without this key, the radio does not appear in
the device list on macOS.

Tested on macOS 26.3 with FLEX-8600 (FW 1.4.0.0) + VARA HF v4.9.0:
DAX RX audio spectrum correctly centered at 1500 Hz after fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@pepefrog1234 pepefrog1234 requested a review from ten9876 as a code owner April 12, 2026 23:58
@ten9876 ten9876 merged commit 553fd53 into aethersdr:main Apr 13, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants