f3be4d8cce
capture.h realtime seam split to capture_realtime_shell.h; GetProjExtState grow-loop rehomed to core/wire/ext_state_read; stale persist.cpp/bank_panel.cpp comment refs fixed; CLAUDE.md persist/bank_book/actions bullets updated. Command-id suffixes, display phrases, and undo labels byte-identical.
71 lines
3.8 KiB
C++
71 lines
3.8 KiB
C++
#pragma once
|
|
// tail_control — the REAPER-free logic behind the docked bank_panel's tail-mode
|
|
// toggle. The panel shell (shell/panel/) owns the SWELL window, LICE drawing, and
|
|
// click hit-testing; what is NOT DAW-bound — the cycle order, the manual-length
|
|
// clamp, and the toggle's label text — lives here so it is unit-tested outside the
|
|
// DAW (CLAUDE.md §load-bearing split). Mirror of bank_grid / mode_switch.
|
|
//
|
|
// PURE MODULE: NO REAPER types, NO SWELL, NO vendor/ includes. Standard library
|
|
// only (plus render_settings for the pure TailMode enum). Builds and unit-tests
|
|
// without REAPER.
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
|
|
#include "core/capture/render_settings.h" // TailMode (pure enum) — the three-state tail contract
|
|
|
|
namespace reasampler::capture {
|
|
|
|
// The Manual-mode starting length. 2 s is a musically useful default tail (a bar of
|
|
// reverb throw at a moderate tempo) that is well under the 8 s cap. Also the value a
|
|
// project with no stored tail setting (older / never-adjusted) falls back to on load.
|
|
inline constexpr double kDefaultManualTailMs = 2000.0;
|
|
|
|
// The fine-adjust step per scroll-wheel notch in Manual mode. 250 ms is coarse enough
|
|
// that a few notches cover the useful range, fine enough to dial a length precisely.
|
|
// Daniel-set. The panel maps one wheel notch to +/- this many ms via adjustManualMs.
|
|
inline constexpr double kManualStepMs = 250.0;
|
|
|
|
// The panel's current tail setting: the mode plus the length used ONLY when the
|
|
// mode is Manual. Held as in-memory panel/session state (shell/panel), default
|
|
// None so a capture with no explicit choice stays exact-bounds / byte-identical to
|
|
// today. `manualMs` is a stored default a future fine-adjust UI can tune; it is
|
|
// clamped to the 8 s cap (kMaxTailMs) before it ever reaches a CaptureRequest.
|
|
struct TailSetting {
|
|
TailMode mode = TailMode::None;
|
|
double manualMs = kDefaultManualTailMs;
|
|
};
|
|
|
|
// Cycles the tail mode: None -> Auto -> Manual -> None. Pure so the wrap order is
|
|
// pinned by a test and the panel's click handler owns no enum arithmetic of its own.
|
|
// An out-of-range value (unreachable for a valid enum) cycles back to None.
|
|
TailMode cycleTailMode(TailMode current);
|
|
|
|
// The effective manual length a Manual capture uses: `manualMs` clamped to
|
|
// [0, kMaxTailMs] (the runaway guard the pure tailRenderSettingsFor also applies).
|
|
// Exposed so the panel can show the clamped value and main.cpp hands a pre-clamped
|
|
// tailMs into the CaptureRequest. Meaningful only for TailMode::Manual.
|
|
double clampManualMs(double manualMs);
|
|
|
|
// Applies `notches` scroll-wheel steps of `stepMs` each to `current`, clamped to
|
|
// [0, kMaxTailMs]. Positive notches lengthen, negative shorten. Pure so the fine-adjust
|
|
// arithmetic (and its clamp at both bounds) is unit-tested; the panel wheel handler
|
|
// owns no arithmetic of its own. Meaningful only for TailMode::Manual.
|
|
double adjustManualMs(double current, int notches, double stepMs);
|
|
|
|
// The toggle's label for a setting, e.g. "Tail: Off", "Tail: Auto". In Manual mode the
|
|
// clamped length is appended in seconds to one decimal, e.g. "Tail: Manual 2.0s" —
|
|
// Off/Auto carry no length. Pure so the exact strings (and the Manual format) are
|
|
// test-pinned, including the boundary lengths (0.0s, 8.0s).
|
|
std::string tailToggleLabel(const TailSetting& setting);
|
|
|
|
// JSON round-trip of a TailSetting (mode + manualMs), for persist to store the tail
|
|
// setting per-project alongside the bank and view model. Kept pure/testable here —
|
|
// the natural home, mirroring bank_model's serialize/deserialize. serialize emits a
|
|
// compact object; deserialize returns std::nullopt on malformed input so the caller
|
|
// (persist) falls back to a default setting, exactly as an absent key does.
|
|
std::string serializeTailSetting(const TailSetting& setting);
|
|
std::optional<TailSetting> deserializeTailSetting(const std::string& json);
|
|
|
|
} // namespace reasampler::capture
|