Fix macOS DAX RX audio corrupted after float32 migration#1242
Merged
ten9876 merged 1 commit intoApr 13, 2026
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The float32 audio pipeline migration (502b934, b0c49d7) missed the macOS
VirtualAudioBridgeand thePCC_IF_NARROWDAX path inPanadapterStream, 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::daxAudioReadyemits float32 stereo PCM. All downstream consumers were updated accordingly —TciServer::onDaxAudioReady,RADEEngine::feedRxAudio, and the LinuxPipeWireAudioBridge(3400133) — but the macOSVirtualAudioBridge::feedDaxAudio()was not. It stillreinterpret_cast's the incomingQByteArrayasint16_t*and divides by 32768.0f: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'sPCC_IF_NARROWpath (full-bandwidth stereo DAX) was still converting radio float32 → int16 viaqBound(-1.0f, f, 1.0f) * 32767.0fbefore emission. This was missed by b0c49d7 which only fixedPCC_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 asfloat*, compute sample count by dividing bysizeof(float), multiply bychGaindirectly (no/32768normalization). Update RMS meter to operate on float samples natively.PanadapterStreamPCC_IF_NARROW path: Emit native float32 stereo (memcpyfrom big-endian-swappeduint32tofloat) instead of converting to int16. Now consistent withPCC_IF_NARROW_REDUCEDand all downstream consumers.Info.plist.in: AddNSLocalNetworkUsageDescription— 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
🤖 Generated with Claude Code