aethersdr / aethersdr/AetherSDR

DAX: size the published/opened RX device set to radio capacity after connect

Open
#4,935 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

audio enhancement maintainer-review
Dominant language
C++
Stars
221
Forks
117
Avg merge
2d 7h
Merged PRs (30d)
299

Description

Corrected — the original body described the post-#4854 branch, not main. Restated against main @ 0bd3c493; thanks to @aethersdr-agent for the catch and the implementation sketch below.

Problem (on main today). The DAX RX wire path publishes/opens a fixed NUM_CHANNELS = 4 devices regardless of the connected radio, while RadioModel::maxSlicesForModel() (src/models/RadioModel.cpp:2197) already knows the per-model slice count (2 for a 6300/6400). So a FLEX-6400 currently gets four AetherSDR DAX N entries in the system audio list, two of which can never carry audio.

Sites on main:

  • src/core/PipeWireAudioBridge.h:28NUM_CHANNELS = 4
  • src/core/VirtualAudioBridge.h:37NUM_CHANNELS = 4
  • open loops: src/core/PipeWireAudioBridge.cpp:126, src/core/VirtualAudioBridge.cpp:94
  • CoreAudio publish loop: hal-plugin/AetherSDRDAX.cpp:234 (for (int ch = 1; ch <= 4; ++ch))

Relationship to #4854. #4854 raises the wire path to 8 (taking the 6400 case to eight-and-six). This capacity-gating is orthogonal — it can land against main at the current 4→capacity and reduces #4854 stated cost. Either order works.

Proposed approach (design credit: @aethersdr-agent triage on this issue):

Linux/shm bridges run in-process with RadioModel, so they can gate on maxSlices() directly. NUM_CHANNELS sizes std::array/C-array members (PipeWireAudioBridge.h:68/93/101/114), so keep it as the compile-time upper bound and add a runtime m_activeChannels that bounds only the open loops (PipeWireAudioBridge.cpp:126, VirtualAudioBridge.cpp:94). Teardown loops can keep iterating the full bound — closing a never-opened slot is a no-op.

Resize-after-connect hazard: close+reopen yanks a source out from under an app already holding it (a WSJT-X on aethersdr-dax-2 sees its device vanish and return). Prefer grow-freely, shrink-only-when-idle over an unconditional republish on every infoChanged.

CoreAudio HAL plugin (coreaudiod loads it before any radio is known, so it cannot read maxSlices() at load): it already maps the same DaxShmBlock and has a retry timer (AetherSDRDAX.cpp:199). DaxShmBlock.reserved[3] (VirtualAudioBridge.h:23) is unused — writing maxChannels into reserved[0] is ABI-compatible: it zero-inits, an old plugin ignores it, and a new plugin reading 0 means "app too old / not connected -> publish the full set." That sidesteps the plugin/app version-skew hazard. For the device list, prefer hiding already-created devices (kAudioDevicePropertyIsHidden, if libASPL exposes it) over AddDevice/RemoveDevice churn on a device an app may have open; fall back to add/remove (safe post-OnInitialize per AetherSDRDAX.cpp:230-231) if not.

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.

Research direction

Read RadioModel::maxSlicesForModel() in src/models/RadioModel.cpp and the open loops in src/core/PipeWireAudioBridge.cpp and src/core/VirtualAudioBridge.cpp, then inspect the shared-memory and retry logic in hal-plugin/AetherSDRDAX.cpp. Done means published devices follow radio capacity without disrupting active users, while the CoreAudio path handles unknown or older shared-memory data safely.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
audio-video-rtc, desktop
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
39/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.