docs(phase-s): settle S-VIEW velocity persistence + draggable nodes, single-pass on L3

F1 -> preview velocity persists via VST3 component state (v5->v6). F2 -> envelope nodes draggable via new pure envelope_edit module. Drop the two-pass L3 restyle framing; build on the merged L3 LnF. F3 remains open.
This commit is contained in:
2026-07-27 12:57:08 -04:00
parent 5ec84ab0eb
commit 3b9b78b82c
3 changed files with 170 additions and 55 deletions
+38 -16
View File
@@ -7,8 +7,15 @@ the **product framing behind a scoped phase**. Its build roadmap lives in **PLAN
*why* (the plugin-format reasoning, the bare-VST3-vs-JUCE assessment, the settled
decision record).
Status: framed by product-designer (2026-07-26), **revised 2026-07-26 (r8)**. r8 records
Daniel's **duration-preserving correction** (2026-07-26, verbatim: *"isn't that ratio stuff
Status: framed by product-designer (2026-07-26), **revised 2026-07-27 (r9)**. r9 records the
**three-view editor redesign** (Sample / Browse / Zone) and its follow-up settlements: the
S-VIEW-F1 and S-VIEW-F2 forks are now **SETTLED** (2026-07-27) — **preview velocity persists** via
the instrument's own VST3 component state (envelope bump to v6, *not* the extension's project
ext-state), and the **envelope overlay's nodes are draggable** via a new pure `envelope_edit`
module — and S-VIEW builds **directly on the finished, merged Phase L L3 look-and-feel** in a
**single implementation pass** (no two-pass restyle-after; L3 landed 2026-07-27, commit `c53683e`).
Only S-VIEW-F3 (Browse modal presentation) remains open. Full r9 record in the Addendum below. r8
records Daniel's **duration-preserving correction** (2026-07-26, verbatim: *"isn't that ratio stuff
going to change the playback rate? I want duration-preserving repitching"*): the ratio path is
**varispeed** (pitch/duration coupled), so S16 is reshaped from "pitch envelope only" into a
**pitch-engine mode — Varispeed vs Preserve — plus the pitch envelope** riding either engine.
@@ -1043,20 +1050,33 @@ grammar, and it is the grammar the redesign adopts:
higher:* the useful musical range is 0200%; past 200% it is noise, and a bounded slider reads
cleaner than an open one.
- **Preview velocity (Sample view).** The velocity level the preview-trigger button fires at,
set by an adjacent knob. Not persisted as a musical parameter of the sample — it is a
*utility* setting for the audition button (like a metronome level), so it can live as
transient editor state or a small persisted convenience; the spec leans transient (see
§S-VIEW). This is what makes the preview button *fun*: tap it hard or soft without reaching for
a controller.
set by an adjacent knob. It is a *utility* setting for the audition button (like a metronome
level), not a musical parameter of the sample — but **it PERSISTS across reloads** (S-VIEW-F1
SETTLED, Daniel 2026-07-27). The seam matters and was verified against the existing VST source,
not recalled: it lives in the **instrument's own VST3 component state** (the envelope-versioned
`ComponentState` blob the processor round-trips through `getState`/`setState`, bumped to v6 for a
new top-level `previewVelocity` field), **not** the extension's `persist` project ext-state —
that module is REAPER-project-scoped and extension-owned, so it would make the level
project-global instead of per-instance and route an instrument concern through a bank-read-only
seam. See CONTEXT.md §S-VIEW for the round-trip and back-compat lift. This is what makes the
preview button *fun*: tap it hard or soft without reaching for a controller — and it remembers.
**Two visual components the redesign commits to:**
- **The envelope overlay** on the Sample view's hero waveform: the amp envelope (AHDSR for Gate,
the fade/%-length shape for Trigger) drawn as a curve *at accurate wall-clock time* across the
waveform, the way Simpler draws its amp envelope over the sample and Phase Plant traces it in
bright blue. This is the single biggest "reads like a real sampler, not a spreadsheet" move —
the envelope stops being four abstract sliders and becomes a *shape you see over the sound*.
The sliders stay (precise entry), but the picture leads.
- **The envelope overlay — with DRAGGABLE nodes** — on the Sample view's hero waveform: the amp
envelope (AHDSR for Gate, the fade/%-length shape for Trigger) drawn as a curve *at accurate
wall-clock time* across the waveform, the way Simpler draws its amp envelope over the sample and
Phase Plant traces it in bright blue. This is the single biggest "reads like a real sampler, not
a spreadsheet" move — the envelope stops being four abstract sliders and becomes a *shape you see
over the sound*. And it is **directly editable** (S-VIEW-F2 SETTLED, Daniel 2026-07-27 — in
scope, not deferred): the breakpoints are **draggable handles** (X → segment time, Y → level on
the sustain node; monotonic-in-time, range-clamped), the exact ADSR-editor grammar Simpler /
Phase Plant / Serum all use. The sliders stay as the precise numeric-entry surface, and **both
surfaces read/write the same envelope params** — one source of truth, so a drag moves the sliders
and a slider edit re-lays the nodes with no divergence. The geometry/hit-test math lives in a new
pure `envelope_edit` module (mirror of `card_drag`, unit-tested at the clamp/monotonic
boundaries); the shell only draws the handles and routes the mouse. This is the affordance that
makes envelope-shaping *feel* like a sampler instead of a form.
- **The real piano-keyboard pattern** on the Zone view's keyboard strip. Today's spectral strip
is pretty but does not *read as a keyboard* — Daniel's note. The redesign keeps the pastel
spectral hue but overlays the **actual alternating white/black key pattern** (bright/dark per
@@ -1069,9 +1089,11 @@ consumer** — every new control (key-tracking, preview velocity, the loop/start
inherits) is *performance map*, never written to `Sample` or the bank (D-B). LICE/SWELL drawing
only, all layout/hit-test in pure geometry modules (D-A). RT discipline untouched — the
preview-trigger fires a note through the same voice engine off the audio-thread commit path, no
new audio-thread work. The VST3 class UID is unchanged — a view reorganization is not a compat
event. And this is an *editor* redesign: the S3 voice engine, the keymap resolution, the
component-state format (extended additively for key-tracking) are the same load-bearing core.
new audio-thread work. The VST3 class UID is unchanged — a view reorganization plus additive
persisted fields is not a compat event; saved instances rebind and restore. And this is an
*editor* redesign: the S3 voice engine, the keymap resolution, and the component-state format
(extended additively — `keyTrack` per-zone, `previewVelocity` per-instance via an envelope bump to
v6, both with back-compat defaults on read) are the same load-bearing core.
**Where the spec lives:** CONTEXT.md §Phase S — editor view-model redesign (S-VIEW); PLAN.md
§Phase S — editor view-model redesign. This Addendum is the *why*; those are the *what/how*.