Repository navigation
macOS/PipeWire: the slice-mode sync overwrites the transmit dax flag mid-transmission (follow-up to #6593) #6595
Description
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?
Follow-up to #6593 (fix for #6538 / #5524 / #6579), which gives the radio's transmit dax flag a single owner on Windows. On macOS and PipeWire builds, one writer of that flag still works outside that owner: the slice-mode sync in MainWindow::onSliceAdded()'s updateDaxTxMode (src/gui/MainWindow_Wiring.cpp:1952-1966 on main cedd50f4e).
That sync runs on every slice's modeChanged and txSliceChanged (MainWindow_Wiring.cpp:1981-1982). Each time, it recomputes "is the TX slice in a digital mode" and writes the result unconditionally:
m_audio->setDaxTxMode(isDigital);
...
m_radioModel.transmitModel().setDax(isDigital);It doesn't know whether a producer currently needs the flag. So, inferred from the source and not yet reproduced:
- A TCI transmission on a voice-mode TX slice can be cut off mid-over. A TCI voice keyer (OpsLog, the case in TCI DVK leaves DAX enabled after TX #5524) or any TCI client keying a USB/LSB slice sets
dax=1for its over. If any slice's mode changes during that over, the sync sendstransmit set dax=0and turns off AetherSDR's local DAX TX mode, so the rest of the over goes out with no modulation. A mode change on another slice, a band-stack restore, or a TCImodulation:command from another client would all do it. - The same applies to the voice keyer, AX.25, WSPR and RX Playback, which all hold the flag during their own transmissions.
- The operator's DAX button doesn't survive a mode change. That is partly by design (DAX TX silent on Linux non-PipeWire after #2271 — radio gets dax=1 but no local stream #2273), but it means the flag on these platforms follows the last mode change, not what the operator chose.
Windows and non-PipeWire Linux builds don't compile this sync at all (#2670 / #2315), so they are unaffected.
What did you expect?
The mode sync should compose with the holders instead of overwriting them. The natural shape, after #6593:
- Make "the TX slice is in a digital mode" one more
RadioModel::DaxTxFlagHolder. Acquire it when the TX slice enters a digital mode, release it when it leaves. - The holder table then decides the wire value. A TCI over on a USB slice keeps
dax=1until its release. Leaving a digital mode hands back what the operator had before, instead of forcing0. AudioEngine::setDaxTxMode()needs the same treatment, or at least must not turn local DAX TX mode off while a producer is mid-over.
It needs care, because this is the path that works today on macOS and Linux:
- Digital TX through the hosted DAX bridge (WSJT-X over the PipeWire/CoreAudio devices) must keep
dax=1on DIGU/DIGL exactly as now. - RADE on these builds gets its
dax=1only from this sync (fix(dax): one owner for the radio's transmit dax flag, so TCI no longer latches it and RADE sets it on Windows. Principle XI. #6593 holds the flag for RADE only where the sync is compiled out). Folding the sync into the table should let RADE hold the flag uniformly on every platform. - The
profileLoadRadioStateWritesHeld()guard ([codex] Harden profile load recovery #3563) must still suppress the write during a profile load.
Steps to reproduce
Not yet reproduced; this is from reading the source. Suggested repro on a PipeWire Linux or macOS build with a FlexRadio, into a dummy load or at low power:
- Slice A in USB, TX slice. Slice B on any mode.
- Start a TCI transmission on slice A (
trx:0,true,tciwith audio, e.g. a TCI voice keyer). - While it's keyed, change slice B's mode.
- Expected bug: the wire log (
aether.connectiondebug) showstransmit set dax=0mid-over, and forward power drops for the rest of the over.
AetherSDR version
main cedd50f4e; still present with #6593 applied
Radio model & firmware
Any FlexRadio
Operating system
macOS, and Linux built with PipeWire
OS version and hardware
Any
73,
Ryan NF0T
👨🏼💻 Co-authored by Claude Opus 5.5
Activity
docs(rade): qualify the DAX restore by platform; ratchet TciServer's …
docs(rade): qualify the DAX restore by platform; ratchet TciServer's …