From 54d3ce39582de6200a0331203bd08a5747505360 Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Thu, 23 Jul 2026 19:23:44 -0400 Subject: [PATCH] docs: archive tail follow-ons; add tail_setting key to persist doc Record the Manual scroll fine-adjust + per-project tail persistence in COMPLETED.md; name all three reasampler ext-state keys in CLAUDE.md. --- CLAUDE.md | 2 +- COMPLETED.md | 44 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 6ca3b74..e99808a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -61,7 +61,7 @@ There is no hot-reload. Copy the built binary into REAPER's `UserPlugins/` folde - `capture` — `ICaptureBackend` interface; `OfflineRenderBackend` (deterministic default) and `RealtimeRecordBackend`. Input: `CaptureRequest`. Output: finished file + populated `Sample` handed to `bank_model`. - `insert` — placement via `InsertMedia`; conform-to-project-tempo is an explicit opt-in flag, never silent stretching. - `bank_panel` — docked LICE-drawn grid: thumbnails, audition, multi-select, keyboard navigation. -- `persist` — project ext state (`SetProjExtState` / `GetProjExtState`, namespace `"reasampler"`) ↔ `bank_model` JSON + `ViewModeModel` JSON (`"view_state"` key); project-relative path resolution. +- `persist` — project ext state (`SetProjExtState` / `GetProjExtState`, namespace `"reasampler"`) ↔ `bank_model` JSON (`"bank_index"` key) + `ViewModeModel` JSON (`"view_state"` key) + `TailSetting` JSON (`"tail_setting"` key); project-relative path resolution. - `view` — Design View shell: reads the folder tree via `view_tree`, snapshots flag values before parking, drives hide + CPU-park on inactive-mode leaves (`B_SHOWINTCP`/`B_SHOWINMIXER`/`B_MAINSEND`/`I_FXEN` + per-FX offline) and derived visibility on parents; restores from snapshot. Never touches master or `B_MUTE`/`I_SOLO`. - `track_guid` — shared `MediaTrack*` → canonical GUID-string formatter; single source of truth for membership keys used by both the view shell and the actions layer. - `actions` — registers the capture/placement/slot action family and the Design View action family (toggle active mode, activate Arrange/Design, tag/untag selected tracks, show-both); routes each to the modules above via the `command_id`/`gaccel`/`hookcommand` contract. diff --git a/COMPLETED.md b/COMPLETED.md index f2d3391..f8041e7 100644 --- a/COMPLETED.md +++ b/COMPLETED.md @@ -473,11 +473,10 @@ path. - **`kNormalizeDisableAll = (4 << 16) = 262144`.** Used for None and Manual — the same disable-all value the pre-tail exact-bounds capture used. - **`tail_control` pure module** (`src/tail_control.{h,cpp}`): REAPER-free logic for - the panel toggle. `kDefaultManualTailMs = 2000.0` (2 s). Fine-adjust UI (± - click zones / scroll) is a noted follow-on; this pass ships a fixed default. -- **Follow-ons noted, not done:** Manual fine-adjust UI; per-project persistence of - the toggle (currently extension-session lifetime, resets to None on unload); T2 - realtime tail. + the panel toggle. `kDefaultManualTailMs = 2000.0` (2 s). Fine-adjust UI (scroll-wheel + in 250 ms steps) and per-project persistence landed as T1-followons (see below). +- **Follow-ons resolved:** Manual fine-adjust UI and per-project persistence of the + toggle landed as T1-followons. T2 realtime tail landed separately. --- @@ -513,3 +512,38 @@ then trims at the -72 dB decay point (± inherent realtime tolerance); realtime exact-bounds capture. - **Realtime tail is non-deterministic by design** (inherent to the realtime backend). Bit-identical repeats are not asserted for the realtime path; this is documented, not a defect. + +--- + +## T1-followons — Manual fine-adjust UI + per-project tail persistence +**Goal:** Close the two follow-ons deferred at T1 landing: (1) scroll-wheel fine-adjust +of the Manual tail length in the panel footer; (2) the tail setting (mode + Manual length) +persists per-project inside the `.rpp` rather than resetting on extension unload. +**Verify (in DAW):** Scroll-wheel over the footer adjusts Manual length in 250 ms steps, +clamped 0–8 s; the label reads "Tail: Manual X.Xs" (one decimal) in Manual mode; footer +click still cycles Off → Auto → Manual. The tail setting survives Save / close+reopen; +projects with no stored key fall back to Off / 2 s. +**Depends on:** T1. + +- [x] `adjustManualMs(current, notches, stepMs)` pure helper in `tail_control` (per-notch + ±`kManualStepMs` = 250 ms, clamped [0, `kMaxTailMs`]); unit-tested. +- [x] `tailToggleLabel` updated: Manual mode appends the clamped length in seconds to one + decimal, e.g. `"Tail: Manual 2.0s"`; unit-tested at boundary lengths. +- [x] Panel footer scroll-wheel handler calls `adjustManualMs` and repaints; click handler + unchanged (still cycles mode via `cycleTailMode`). +- [x] `serializeTailSetting` / `deserializeTailSetting` pure round-trip (mode + manualMs) + added to `tail_control`; unit-tested including `std::nullopt` on malformed input. +- [x] `TailSetting tail_` promoted into `ReaSamplerSession` (peer to `bank_` and `view_`); + `persist` serializes it under the forever-stable key `"tail_setting"` (namespace + `"reasampler"`) on save and reloads it on project open. Absent key → default Off / 2 s + (graceful for older/unsaved projects). +- [x] Changing the toggle marks the project dirty and commits the value to ext state; + `bankPanelTailSetting()` reads through the session (not a panel-local copy). + +**Notes/decisions:** +- `kManualStepMs = 250.0` — Daniel-set coarse-but-precise step; one wheel notch = ± 250 ms. +- Label format: `"Tail: Manual 2.0s"` (one decimal, `s` suffix) — format pinned by unit tests. +- Default fallback on absent/malformed key: `TailSetting { TailMode::None, kDefaultManualTailMs }` + (Off mode, 2 s stored length) — graceful for projects saved before this feature shipped. +- `kProjExtTailKey = "tail_setting"` is forever-stable (changing it would orphan saved choices, + falling back to the default — graceful but lossy).