refactor(capture): drop master scope; realtime taps selected track

Capture is now item + track only (master removed as a scope; still bypassed
as out-of-scope chain). Realtime records the selected track's own output via
per-track post-fader sends into a hidden temp track, fixing the silent file.
This commit is contained in:
2026-07-23 16:34:02 -04:00
parent 3791e6c119
commit 4ef41cf705
6 changed files with 215 additions and 192 deletions
+11 -10
View File
@@ -66,18 +66,20 @@ RenderSettingsChoice renderSettingsFor(SourceMode mode, double wetDry);
// --- Capture scope: the FX-scope invariant (Daniel, critical) ----------------
//
// Three FX scopes. The render RANGE (razor-else-time) is orthogonal to the scope.
// Two FX scopes. The render RANGE (razor-else-time) is orthogonal to the scope.
// Item -> item/take FX ONLY (no track, no parent/folder, no master FX).
// Track -> item FX + the selected track's OWN track FX (no parent/folder/master).
// Master -> the whole chain (nothing bypassed).
// There is NO master scope: to capture the master you render a track instead. The
// master track's FX/gain/pan are still NEUTRALIZED as part of the out-of-scope
// chain for both item and track captures (bypassMaster below) — master is a
// bypass target, not a capture scope.
enum class CaptureScope {
Item,
Track,
Master,
};
// The render source mode each scope drives. Item captures selected items, Track
// captures selected tracks (via master), Master captures the master mix.
// captures selected tracks (via master).
SourceMode sourceModeForScope(CaptureScope scope);
// --- Range inference: razor-else-time (orthogonal to scope) -------------------
@@ -142,7 +144,7 @@ RazorRange razorUnionBounds(const std::vector<RazorRange>& ranges);
// --- Capture-action taxonomy (the bindable set main.cpp registers) -----------
//
// One row per bindable SCOPE action. Three scopes (item / track / master); the
// One row per bindable SCOPE action. Two scopes (item / track); the
// range each captures (razor-else-time) is inferred at fire time, not a mode.
// Tail is OFF for every row (exact bounds); a tail-on variant is a later opt-in,
// YAGNI now. Bounded, discoverable, NO dialogs (the tool's no-clutter ethos).
@@ -153,17 +155,16 @@ struct CaptureActionDef {
const char* commandString; // CEREBELLUM_REASAMPLER_… FOREVER-STABLE id string
const char* description; // Actions-list label
const char* baseName; // file-stem base for this capture
CaptureScope scope; // FX scope (item / track / master)
CaptureScope scope; // FX scope (item / track)
};
// The capture-action table. Iterated by main.cpp to register the family and route
// each fired command back to its definition. Kept here (pure) so the taxonomy is
// one testable list, not scattered registration code.
//
// Three scope rows: CAPTURE_ITEM, CAPTURE_TRACK, CAPTURE_MASTER. This replaces the
// M7 four-mode table (master / tracks / items / razor) — razor is now an inferred
// range, not a mode, and each scope enforces its FX-scope invariant via
// fxBypassPlanFor.
// Two scope rows: CAPTURE_ITEM, CAPTURE_TRACK. There is no master capture — to
// capture the master you render a track. Razor is an inferred range, not a mode,
// and each scope enforces its FX-scope invariant via fxBypassPlanFor.
const std::vector<CaptureActionDef>& captureActionTable();
} // namespace reasampler