refactor(capture): expose offline tail as docked-panel toggle

Replace the ...-with-tail variant actions with a pure tail_control module +
a docked-panel footer toggle (Off/Auto/Manual) read by CAPTURE_ITEM/TRACK.
Default None (byte-identical); Manual fixed 2s, in-memory session lifetime.
Tail mechanism unchanged; retired the variant ids.
This commit is contained in:
2026-07-23 17:32:19 -04:00
parent 2d225258b4
commit 9a9339b90b
11 changed files with 363 additions and 90 deletions
+10 -13
View File
@@ -89,7 +89,7 @@ double autoTrimEndRatio();
// None — exact bounds, no tail. Byte-identical to the pre-tail capture. The
// default and the ONLY mode for null-test / verify captures.
// Auto — generous 8 s tail then trim trailing silence to -72 dB (surgical
// normalize). The user-facing "…with tail" default.
// normalize). The user-facing tail-on option (panel toggle).
// Manual — a fixed tail length (clamped to the 8 s cap), no trim.
enum class TailMode {
None,
@@ -213,13 +213,11 @@ RazorRange razorUnionBounds(const std::vector<RazorRange>& ranges);
// --- Capture-action taxonomy (the bindable set main.cpp registers) -----------
//
// One row per bindable SCOPE action. Two scopes (item / track), each in two tail
// variants: an exact-bounds row (TailMode::None) and a paired "…with tail" row
// (TailMode::Auto). The range each captures (razor-else-time) is inferred at fire
// time, not a mode. The tail variants are additive — the None rows keep their
// documented exact-bounds contract byte-for-byte; the Auto variants are a separate
// opt-in action rather than a silent default flip (Daniel's lean, spec §Open
// questions). Bounded, discoverable, NO dialogs (the tool's no-clutter ethos).
// One row per bindable SCOPE action: item and track. The range each captures
// (razor-else-time) is inferred at fire time, not a mode. TAIL is NOT a per-action
// variant — the tail MODE (None/Auto/Manual) is a panel SETTING the capture reads
// at fire time (see tail_control + bank_panel), so a single pair of actions covers
// every tail state. Bounded, discoverable, NO dialogs (the tool's no-clutter ethos).
//
// commandString is FOREVER-STABLE (user keybindings key off it) — never change a
// shipped value. baseName feeds the file stem (sanitized by capture_paths).
@@ -228,17 +226,16 @@ struct CaptureActionDef {
const char* description; // Actions-list label
const char* baseName; // file-stem base for this capture
CaptureScope scope; // FX scope (item / track)
TailMode tailMode; // None (exact bounds) or Auto ("…with tail")
};
// 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.
//
// Four rows: CAPTURE_ITEM / CAPTURE_TRACK (exact bounds, TailMode::None) plus the
// paired CAPTURE_ITEM_TAIL / CAPTURE_TRACK_TAIL variants (TailMode::Auto). 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.
// Two 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. The tail mode each
// capture applies is read from the docked-panel setting, not baked into the row.
const std::vector<CaptureActionDef>& captureActionTable();
} // namespace reasampler