Skip to content

DAX/TX PipeWire nodes all show node.description "AetherSDR" — spaced device.description is truncated on the legacy pipe path #3437

Description

@Ozy311

Summary

On builds without libpipewire-0.3 dev headers (HAVE_PIPEWIRE_NATIVE off), DAX audio
nodes are created via the legacy pactl module-pipe-source / module-pipe-sink path. Every
DAX RX node and the TX node ends up with node.description = "AetherSDR" — generic and
identical for all of them — so qpwgraph, JACK-via-PipeWire patchbays, WSJT-X and FLDIGI show
no way to tell DAX 1 from DAX 4 from TX. Operators have to pick the generic pipewire device
and hand-route by guesswork.

The TX sink is created via this legacy path even on native builds, so the TX half is
affected on every build.

Environment

  • Linux, pipewire-pulse (PipeWire's PulseAudio server — the modern default on
    Fedora/Nobara/Ubuntu/Arch). Observed on Nobara 43, PipeWire 1.x.
  • Build with native PipeWire off (PIPEWIRE_NATIVE_INCLUDEDIR empty in CMakeCache.txt).

Evidence (pw-cli ls Node)

node.name = "aethersdr-dax-1"   node.description = "AetherSDR"
node.name = "aethersdr-tx"      node.description = "AetherSDR"

Expected: AetherSDR DAX 1AetherSDR DAX 4, AetherSDR TX.

Root cause

loadPipeSource() passes:

source_properties=device.description="AetherSDR DAX 1" node.latency=256/48000

But pipewire-pulse's pulse-module argument parser splits the property value on
unescaped whitespace and does not honor the embedded double-quotes for grouping. So the
value is taken only up to the first space → device.description="AetherSDR", and everything
after the space (DAX 1" node.latency=256/48000) is dropped. node.description is derived
from device.description
, so it inherits the truncated "AetherSDR".

A reproducible A/B with pactl (the exact argv the code emits), reading back via pw-cli:

source_properties value (as emitted) node.description node.latency
device.description="AetherSDR DAX 1" node.latency=256/48000 (current) AetherSDR dropped
device.description=AetherSDR\ DAX\ 1 (backslash-escaped) AetherSDR n/a
'device.description="AetherSDR DAX 1" node.latency=256/48000' (quoted) AetherSDR DAX 1 256/48000

Two consequences of the same truncation:

  1. Naming — all DAX/TX nodes collapse to "AetherSDR".
  2. Latency — the node.latency=256/48000 hint (the quantum hint from Current DAX Implementation higher latency than SSDR DAX Latency #1008) is orphaned
    and never applied on these nodes.

The native RX path (PipeWireNativeRxSource.cpp) sets PW_KEY_NODE_DESCRIPTION directly
via the raw API and is unaffected — so on native builds the RX nodes are already named
correctly; this is purely a legacy-fallback (and TX) problem.

Fix direction

Quote the source_properties / sink_properties value so the spaced device.description
(and the trailing node.latency) survive the module-arg split. PR to follow.

Note

DaxIqModel.cpp builds its pactl command the same way (with backslash-escaped spaces, run
via bash -c), so DAX-IQ node descriptions are very likely truncated the same way — separate
follow-up.

Metadata

Metadata

Assignees

No one assigned

    Labels

    audioAudio engine and streamingbugSomething isn't workingmaintainer-reviewRequires maintainer review before any action is taken

    Type

    No type

    Fields

    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