Title bar speaker button conflates radio line out mute with local PC audio mute
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
Research direction
Start with src/gui/TitleBar.cpp:317 and MainWindow.cpp:1822-1827, then compare the mute entry points in MainWindow_Controllers.cpp, MainWindow_Shortcuts.cpp, StripRxOutputPanel.cpp, and RadioSetupDialog.cpp. Confirm the intended title-bar semantics with the issue's Option A or B, then verify that the indicator, labels, persistence, and radio/local mute behavior are consistent across the named paths.
Written by the indexing model from the issue text.
Description
Summary
The title bar speaker button drives two independent things at once — the radio's physical line out and the local PC audio sink — and its indicator can only reflect one of them. Whichever one it reflects, it misrepresents the other.
This surfaced during review of #4628, which syncs the indicator to the local AudioEngine. That PR is a reasonable fix for the symptom it targets and is not the cause of this; it's the change that made the conflation visible enough to be worth writing down.
Current behaviour
One click on m_speakerBtn (src/gui/TitleBar.cpp:317) does three things via MainWindow.cpp:1822-1827:
m_audio->setMuted(muted)— mutes the local PC audio sinkmixer lineout mute N— mutes the radio's physical rear-panel line out- persists
PcAudioMutedtoAppSettings
Meanwhile:
- The button is labelled for only one of those:
setAccessibleName("Line out mute"), tooltip "Click to mute/unmute line out". - Every other mute entry point — RC-28 (
MainWindow_Controllers.cpp:428), MIDI (:1778,:2018), keyboard shortcut (MainWindow_Shortcuts.cpp:911), the strip SPEAK tile (StripRxOutputPanel.cpp:298) — callsAudioEngine::setMuted()only. None of them touch the radio, and none of them persist. RadioSetupDialoghas a second Line Out Mute button (RadioSetupDialog.cpp:2768) that callsRadioModel::setLineoutMute()and touches the radio only.
So the app has two controls both named "line out mute" that do different things, plus five entry points that do a third thing.
Why this is a Principle II problem
The radio is authoritative on live state, and it does report this one: FlexBackend.cpp:942 carries lineout_mute into RadioDelta::lineoutMute, surfacing as RadioModel::lineoutMute() and published via audioOutputChanged.
RadioSetupDialog.cpp:2840-2850 consumes that correctly — it reconciles its Mute button from m_model->lineoutMute() on every audioOutputChanged, under a QSignalBlocker. That's the pattern.
The title bar indicator has never been reconciled from radio status. Nothing calls TitleBar::setLineoutMuted() from audioOutputChanged. So a line out mute originating anywhere other than this button — the Radio Setup dialog, another Multi-Flex client, the radio itself — leaves the title bar showing the wrong thing indefinitely.
Concrete failure
- Radio Setup → Line Out → Mute. Radio line out mutes, that dialog reflects it, title bar still shows 🔊.
- Press the RC-28 mute key. Local audio mutes; with #4628 the title bar flips to 🔇, for an unrelated reason.
- User clicks the title bar speaker to restore audio →
mixer lineout mute 0→ the radio's line out, deliberately muted in step 1, is silently un-muted.
The operator has no way to see this coming, and nothing logs it.
Options
A — Title bar speaker means local PC audio (preferred).
Stop sending mixer lineout mute from the title bar click; relabel the accessible name and tooltip to "PC audio mute". Radio line out mute stays in Radio Setup, where it's already reconciled correctly. #4628's mutedChanged → setLineoutMuted connection then becomes exactly right, and every controller entry point agrees with it for free. The cost is a user-visible behaviour change for anyone using the title bar button to mute the rig, so it needs a CHANGELOG note.
B — Title bar speaker means radio line out.
Reconcile the indicator from RadioModel::lineoutMute() on audioOutputChanged, mirroring RadioSetupDialog. Principle-II-correct, but it does not solve the problem #4628 set out to solve — external controllers change local mute, not radio line out — so the local-mute indicator would need a separate home. The strip SPEAK tile already is one.
I lean A: it's the only option where all seven entry points and both indicators end up describing the same thing, and the label is already the odd one out rather than the behaviour.
Whichever way this goes, the accompanying cleanups are:
- Route the command through
RadioModel::setLineoutMute()(RadioModel.cpp:8712) rather than hand-writingmixer lineout mute %1atMainWindow.cpp:1824— the model setter is the command path. - Decide whether a mute set from a controller should persist. Today
PcAudioMutedis written only on title-bar clicks, so a mute set from the RC-28 doesn't survive a restart. m_audio->setMuted()is called directly from the GUI thread on an object moved tom_audioThread(MainWindow.cpp:1151), touchingm_audioSink->setVolume()off-thread. The neighbouring PC-audio handler usesQMetaObject::invokeMethodfor precisely this reason.
Related
Follow-up from the review of #4628 — that PR does not resolve this and should not be treated as closing it.
👨🏼💻 Co-authored by Claude Opus 5
- Dominant language
- C++
- Stars
- 221
- Forks
- 117
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 299
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from aethersdr/AetherSDR
-
audio documentation good first issue maintainer-review
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
bug CW maintainer-review safety
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
docs(agents): family PRs must stay in the family tree (shared applet/pan/model edits stall review) Opendocumentation enhancement maintainer-review
Difficulty 1/5 1-3 hours Newbie friendliness 90/100
-
bug good first issue GUI maintainer-review priority: low
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 86/100
All issues in aethersdr/AetherSDR
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
Sensor initialization takes very long when `--initial-sim-time` is set to current UNIX timestamp Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
gazebosim/gz-sensors#662 · 1 comment ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
LadybirdBrowser/ladybird#12123 ·