feat(capture): neutralize parent/master gain, pan, width, law in FX-scope capture

FxBypassGuard now snapshots/restores D_VOL, D_PAN, D_WIDTH, D_PANLAW, I_PANMODE
alongside I_FXEN for every bypassed track (forcing stereo-pan mode for an
unambiguous render), so Track/Item captures are uncolored by parent/folder/master
fader and routing. All restored on every path.
This commit is contained in:
2026-07-23 13:34:51 -04:00
parent df03b5e759
commit d4ffea6918
2 changed files with 102 additions and 30 deletions
+8 -6
View File
@@ -102,12 +102,14 @@ RangeSource inferRangeSource(bool hasRazorArea);
// concrete MediaTrack* by walking the ancestor chain via GetParentTrack and
// clears I_FXEN on each flagged track, snapshotting first (RAII restore).
//
// SCOPE BOUNDARY (documented, DAW-confirm): I_FXEN bypasses a track's FX plugins
// but NOT its volume/pan/routing. "No parent FX" is satisfied by bypassing parent
// FX only — parent/master GAIN still applies to a Track capture rendered via
// master (&128). Neutralizing parent gain would be a larger, surprising mutation
// (and is not what "FX scope" means); the least-surprising default is FX-only
// bypass. Flagged for Daniel's DAW confirmation.
// SCOPE BOUNDARY: I_FXEN bypasses a track's FX plugins but NOT its volume/pan.
// The guard (FxBypassGuard, main.cpp) therefore ALSO neutralizes the fader GAIN
// (D_VOL -> unity) of every track in this same bypass set, so a Track/Item
// capture rendered via master does NOT bake in the parent/folder/master fader
// level (Daniel: the capture is likely re-routed through that chain later). PAN
// is deliberately left untouched (D_PAN is coupled to D_WIDTH/D_PANLAW — a clean
// neutralize is non-trivial; flagged as a follow-up, not half-done). This plan
// selects the SET; the guard applies both the FX bypass and the gain neutralize.
struct FxBypassPlan {
bool bypassSelfFx = false; // the captured track's own FX
bool bypassAncestorFx = false; // every ancestor (parent/folder) track's FX