Skip to content

Channel Strip TX/RX: BYPASS suppresses RN2; RN2 captured in presets (#3054). Principle VI.#3066

Merged
ten9876 merged 1 commit into
mainfrom
aetherclaude/issue-3054
May 24, 2026
Merged

Channel Strip TX/RX: BYPASS suppresses RN2; RN2 captured in presets (#3054). Principle VI.#3066
ten9876 merged 1 commit into
mainfrom
aetherclaude/issue-3054

Conversation

@aethersdr-agent
Copy link
Copy Markdown
Contributor

Summary

Fixes #3054

What was changed

Channel Strip TX/RX: BYPASS suppresses RN2; RN2 captured in presets (#3054). Principle VI.

Files modified

  • src/core/AudioEngine.cpp
  • src/core/AudioEngine.h
  • src/core/ChannelStripPresets.cpp
  • src/gui/AetherialAudioStrip.cpp
  • src/gui/ClientChainApplet.cpp
  • src/gui/StripTubePanel.cpp
 src/core/ChannelStripPresets.cpp | 32 ++++++++++++++++++++++++++++++++
 src/gui/AetherialAudioStrip.cpp  |  8 ++++++--
 src/gui/ClientChainApplet.cpp    |  6 ++++--
 src/gui/StripTubePanel.cpp       |  4 +++-
 6 files changed, 74 insertions(+), 5 deletions(-)

Generated by AetherClaude (automated agent for AetherSDR)


🤖 aethersdr-agent · cost: $21.6045 · model: claude-opus-4-7

…3054). Principle VI.

Closes the four-part regression in the Aetherial Channel Strip where
RN2 TX (RNNoise mic pre-amp, #2813) functioned independently of the
chain BYPASS and the preset system that surround every other voice
stage:

  - setTxBypassed snapshots/restores m_rn2TxEnabled alongside the
    TxChainStage entries, so pressing BYPASS now produces a truly
    transparent TX path instead of "voice still passes, other audio
    is suppressed" (RN2 trained on speech).
  - setRxBypassed gets the symmetric fix for m_rn2Enabled.  RX RN2
    lives in the NR cluster, not RxChainStage, so the existing
    kAllStages loop missed it.
  - ChannelStripPresets::capturePresetJson writes a top-level "rn2"
    bool for TX and a sibling "rn2" inside the "rx" block for RX.
    applyPresetJson only acts when the key is present, so old preset
    files without it leave RN2 untouched — matching the precedent of
    the v0.9.8 "rx" block (#2425).
  - StripTubePanel, AetherialAudioStrip, ClientChainApplet tooltips
    now state the BYPASS scope (global, per-engine) and confirm RN2
    is suppressed alongside the chain.

BYPASS scope (global vs per-profile) is left as global per the open
question in the issue — that is a UX decision for the maintainer; the
tooltips make the current scope discoverable without prejudging it.

Principle VI: the visual CHAIN widget is the primary entry point for
the TX DSP path.  Before this change, RN2 was a stage that bypassed
the BYPASS gesture the CHAIN widget exposes, fragmenting the user's
mental model of the chain.  After this change, BYPASS suppresses
every voice-shaping stage that runs on the TX path, RN2 included,
restoring the CHAIN widget as the single point of control.

Blast radius: risk_score=0.256, 4 high-risk affected (top:
AppSettings::instance, AppSettings::setValue, AppSettings::save).
All four are downstream of the existing per-stage save* helpers the
bypass methods already call; the RN2 addition routes its persistence
through setRn2TxEnabled / setRn2Enabled, which use the existing
saveAetherialTubePreampTxSettings path.  No new AppSettings surface.
Upstream callers (AetherialAudioStrip::onBypassToggled,
ClientChainApplet::onBypassToggled) are unchanged.
Copy link
Copy Markdown
Contributor Author

@aethersdr-agent aethersdr-agent Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix — the BYPASS-leaks-RN2 behavior was a real footgun and the comments tying RN2's special-case to its out-of-enum location (#2813) make the intent very clear to a future reader. TX/RX mirror each other cleanly, the contains("rn2") guard in applyPresetJson preserves backward compatibility with old preset files, and the parallel-bool snapshot pattern is the right shape given RxChainStage/TxChainStage can't hold RN2.

A couple of observations rather than blockers:

1. BYPASS now writes RN2 state to AppSettings on every toggle (TX side).
setRn2TxEnabled() calls saveAetherialTubePreampTxSettings() unconditionally. So engaging BYPASS persists "RN2 TX = off", and releasing it persists "RN2 TX = on". This matches the precedent in setStageEnabled (which calls saveClient*Settings() per stage), so it's consistent — but worth being aware that a crash mid-BYPASS leaves AppSettings out of sync with the user's intended RN2 state. The RX side doesn't have this issue because setRn2Enabled doesn't persist (a pre-existing asymmetry, not introduced here).

2. Manual RN2 toggle during BYPASS is silently overwritten on un-bypass.
If a user clicks the RN2 button in StripTubePanel while BYPASS is engaged, the next un-bypass will restore the snapshotted value and clobber their change. This is identical to the existing stage-bypass behavior, so not a regression — just worth noting that the new tooltip language ("the button stays pressed across Channel Strip profile switches") might lead users to expect RN2 toggles to "stick" too. Probably fine to leave as-is.

3. Preset apply order interaction is safe today, but fragile.
setRn2Enabled(true) disables NR2/NR4/BNR/DFNR/MNR via mutual exclusion. The preset format doesn't currently capture those NR-cluster siblings, so there's no conflict — but if someone later adds nr2/bnr/etc. to the preset schema and applies them after rn2, the last-write-wins ordering will silently disable RN2. Worth a brief comment near the RX rn2 apply block flagging that any future NR-cluster keys must apply before rn2, or after considering the mutex.

None of these block merge — the PR delivers what #3054 asks for and the code is clear. Thanks for the careful comments and the consistent tooltip updates across AetherialAudioStrip, ClientChainApplet, and StripTubePanel.


🤖 aethersdr-agent · cost: $4.1706 · model: claude-opus-4-7

@ten9876 ten9876 merged commit a0232d5 into main May 24, 2026
5 checks passed
@ten9876 ten9876 deleted the aetherclaude/issue-3054 branch May 24, 2026 21:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Aetherial Channel Strip TX: RN2 ignores stage disable, BYPASS, and profile switching

1 participant