docs(product): reframe S10 capture-first (browser + single-capture setup); reverse S4 auto-select; settle S-NAME-1 filename rename

This commit is contained in:
2026-07-26 19:49:03 -04:00
parent 5de2183ce3
commit 991c190bb8
3 changed files with 312 additions and 102 deletions
+96 -36
View File
@@ -1426,6 +1426,35 @@ Setting a zone from C1 to C4 by clicking "+" thirty-six times is the catastrophe
a fixed envelope) compound it. The overhaul is scoped as **S10S13**, sequenced so the
friction Daniel feels every test pass is removed first.
### Workflow hierarchy (REVISED 2026-07-26 — Daniel; supersedes the keymap-first S10)
The overhaul is reframed around the **actual workflow**, not a keymap. Daniel's directive,
distilled: *a giant list of "item" blocks is visually useless; optimize for working with
individual captures, not a huge list of everything.* The settled hierarchy:
1. **Primary flow = one capture, fast.** Most instances play a **single capture**. The
metric is **time-to-first-note**: open → pick a capture → see it (waveform/peaks) → play
it. The default editor face serves this, not a zone table.
2. **Fresh instance is SILENT — nothing auto-selected (policy reversal of S4).** On open
with no stored selection, the instrument plays **nothing** and shows a clear **empty
state** ("pick a capture") — it does **not** auto-play sample #1. This deliberately
reverses the S4 "first sample plays" convenience: the `selectSample` first-sample
fallback and the processor's Tier-0 fallback that resolved it are removed; an empty
stored id resolves to silence. (Recorded as a reversal, not a regression.)
3. **Capture browser, not an item list.** Scannable **cards/rows** with **peak thumbnails**
(the `Sample` peaks bank_model already carries — the same data the dock panel thumbnails
draw), name, and a **root/key badge** where present; **filterable by bank** (bank_book
named banks). A "giant list of item blocks" is the anti-pattern — the browser is designed
for scanning by eye.
4. **Graphic, descriptive controls with a guided fast path.** Once a capture is picked, a
prominent, self-explanatory single-capture setup surface (root note, play-mode basics,
level). The keyboard strip serves the **single-capture** case first (shows where the
capture sits / its root); drag matters most when zoning.
5. **Zones demoted to secondary (nice-to-have).** Multi-zone keymap editing becomes an
**opt-in "Zones" panel** (S10-Z), not the default face — "most of the time the zones
won't be used." The keyboard-strip drag machinery is still built, but in service of the
capture-first layout.
**What "better than RS5K" means, specifically (not vibes).** RS5K's genuine strengths —
match or beat each: (1) **drag a file straight onto it** loads the sample (our S13 relay);
(2) **note-start / note-end** range with a visual sense of the keyboard (our S10 keyboard
@@ -1434,10 +1463,12 @@ strip — RS5K's own range UI is two number fields, so a *draggable* strip beats
S12); (5) velocity layers / round-robin (Tier 2 — held, not in this overhaul). RS5K's real
**weaknesses are our opening:** its **one-sample-per-instance** model forces track sprawl
(one RS5K per drum) and it has **no multi-zone view in a single instance** — ReaSampler
9000 is multi-zone in one instrument by design (S5), so the keyboard-strip editor showing
*all* zones at once is a capability RS5K structurally lacks. "Better than RS5K" =
direct-manipulation where RS5K uses number fields, multi-zone where RS5K is one-shot, and
bank-integrated ingest where RS5K is file-at-a-time.
9000 is multi-zone in one instrument by design (S5), so the **opt-in Zones panel** showing
*all* zones at once is a capability RS5K structurally lacks. But per the reframe, the *default*
face is the single-capture fast path (browser + setup), and multi-zone is the demoted
nice-to-have. "Better than RS5K" = a fast single-capture browser where RS5K makes you drag a
file blind, direct-manipulation where RS5K uses number fields, multi-zone-when-you-want-it
where RS5K is one-shot, and bank-integrated ingest where RS5K is file-at-a-time.
**Constraints (unchanged — settled, do not re-open):** LICE/SWELL drawing only (no toolkit
change — D-A settled); **all layout/hit-test math in pure geometry modules** (mirror of
@@ -1448,17 +1479,28 @@ stays a **read-only bank consumer** (loop/root/ADSR edits are the instrument's *
map*, D-B — never written back to the bank); component-state persistence and
read-only-over-bank stay settled.
- **S10 — direct-manipulation keymap editor.** A **piano-keyboard strip** along the top;
each zone a bar over the keys it covers. **Drag an edge** → change low/high note; **drag
the bar body** → move the zone (span preserved); **click a key** → set/relocate the
zone's root. Retires the seven ±1 nudge buttons per row. New pure `keyboard_strip`
geometry module (key-span↔pixel reusing the `embed_strip` idiom; edge-grab vs. body-move
hit regions; `pixel→note`; drag-delta resolver). Shell extends the click-only `wndProc`
to a `WM_MOUSEMOVE`/`WM_LBUTTONUP` drag-state machine with live feedback, one coherent
edit on release. **Built with the current LICE drawing; adopts the Phase L kit (L1) when
it lands** (drawn through the shared component kit rather than flat `LICE_FillRect`/GDI once
available) — **not gated on Phase L**; the drag machine's `WM_MOUSEMOVE` tracking also lights
the kit's hover states at near-zero marginal cost once the kit is present.
- **S10 — capture-first editor: browser + guided single-capture setup (REVISED 2026-07-26).**
The default face is the **capture browser** (scannable cards with **peak thumbnails** from
the `Sample` peaks bank_model carries, name, root/key badge; **bank filter** over bank_book
banks) feeding a **guided single-capture setup** (root note, play-mode basics, level).
Fresh instance is **silent, nothing auto-selected** — the S4 first-sample fallback is
**removed** (empty stored id → silence + a "pick a capture" empty state). New pure modules:
`capture_browser` (card/grid layout + hit-test) and `keyboard_strip` (key-span↔pixel via
the `embed_strip` idiom; a **root marker** for the single loaded capture; `pixel→note`;
drag-delta resolver; per-zone bar rect + edge-grab hit regions for the opt-in Zones panel).
Shell extends the click-only `wndProc` to a `WM_MOUSEMOVE`/`WM_LBUTTONUP` drag-state
machine with live feedback, one coherent edit on release. **Multi-zone keymap editing is an
opt-in "Zones" panel (S10-Z), not the default** — the demoted nice-to-have; it reuses the
same strip geometry + drag machine (edge = resize, body = move, key = root) and retires the
seven ±1 nudge buttons per row. **Built with the current LICE drawing; adopts the Phase L
kit (L1) when it lands** (drawn through the shared component kit rather than flat
`LICE_FillRect`/GDI once available) — **not gated on Phase L**; the drag machine's
`WM_MOUSEMOVE` tracking also lights the kit's hover states at near-zero marginal cost once
the kit is present. **Boundary shifts (from the reframe):** the "sample list" S12 was to
scroll/search **is now this browser** — the card layout, peak thumbnails, and bank filter
are S10's; S12 keeps **scroll** + **type-to-filter search** *layered over* S10's browser
(bank filter picks the bank, search narrows within it). The waveform S11 makes loop-editable
is the same waveform S10 shows read-only for the picked single capture ("see it").
- **S11 — waveform view + draggable loop points.** Selecting a zone shows its sample's
**waveform** (peaks via the existing `peaks` module over the shell's already-decoded PCM
— no new decode/WAV path) with draggable **start/end/loop-start/loop-end** markers that
@@ -1466,13 +1508,17 @@ read-only-over-bank stay settled.
**per-zone loop override** (additive on `PerformanceZone`, same shape as `rootOverride`;
seeded from the S2 bank intrinsic, never written back). Marker/waveform geometry pure
(`frame↔pixel`, marker grab regions, clamp start≤end, zero-crossing snap helper).
- **S12 — scale + ergonomics.** The sample list **scrolls** (wheel + scrollbar) so a long
bank is fully reachable, and has a **type-to-filter search**. **Direct numeric entry**
for zone low/high/root (a click-to-type field over the strip, for precision the drag
can't hit). An **ADSR editor** — four draggable controls over the S3 `AdsrParams` (the
math already exists and is wired into the voice engine; today the envelope is a fixed
default). Scroll/search/slider/entry layout pure; ADSR + (implicitly) any exposed
parameters become per-instance component state (additive, version-bumped, back-compat).
- **S12 — scale + ergonomics.** **Scroll** (wheel + scrollbar) over **S10's capture
browser** so a bank longer than the panel is fully reachable, and a **type-to-filter
search** that narrows the cards by name, **composing with S10's bank filter** (bank filter
selects the bank; search narrows within it). *(Boundary shift from the 2026-07-26 reframe:
the browser card layout, peak thumbnails, and bank filter are now **S10's**; S12 = scroll
+ search layered over that browser.)* **Direct numeric entry** for zone low/high/root (a
click-to-type field over the strip, for precision the drag can't hit — Zones-panel-scoped).
An **ADSR editor** — four draggable controls over the S3 `AdsrParams` (the math already
exists and is wired into the voice engine; today the envelope is a fixed default).
Scroll/search/slider/entry layout pure; ADSR + (implicitly) any exposed parameters become
per-instance component state (additive, version-bumped, back-compat).
- **S13 — drop-to-load (the S8 relay, in the editor).** Dropping an OS file / media item
**onto the editor window** ingests into the bank + assigns to this instance — the RS5K
"drop a file straight on it" affordance. **The instrument does not ingest:** the editor's
@@ -1482,12 +1528,15 @@ read-only-over-bank stay settled.
degrade to the docked-`bank_panel` drop path with a clear affordance. Never inserts a
timeline item (capture/placement separation intact).
**Sequencing (recommendation, argued below in this section's tail).** S10 first — the
nudge-button zone editor is the friction Daniel hits on *every* test pass, so removing it
buys the most felt improvement per unit work and de-risks the drag-state machine S11/S12
reuse. S11 and S12 follow (both lean on S10's drag machine). S13 depends on S8's ingest
seam, so it sequences after S8. Against the queued engine work: **S10 should land before or
interleaved with S7 (stereo).** S7 is a real engine capability (stereo capture in true
**Sequencing (recommendation, argued below in this section's tail).** S10 first — under the
reframe it now carries the **whole felt win**: the empty-state / no-auto-select fix, the
capture browser (peak thumbnails, bank filter) that replaces the useless item list, and the
guided single-capture setup that retires the nudge buttons. This is the entire "the UX is
awful" wound, and time-to-first-note is the metric it moves. S11 (waveform + loop) and S12
(scroll/search over the browser, numeric entry, ADSR) follow — both lean on S10's browser +
drag machine, and S11's waveform is the same surface S10 shows for the picked capture. S13
depends on S8's ingest seam, so it sequences after S8. Against the queued engine work: **S10
should land before or interleaved with S7 (stereo).** S7 is a real engine capability (stereo capture in true
stereo) and touches the DSP Daniel smoke-tests — but the *reason* he'll keep smoke-testing
is the editor, and today every test pass is taxed by the nudge-button UX. Fixing what he
feels first (S10) makes every subsequent S7 test less painful; there is no hard dependency
@@ -1502,17 +1551,28 @@ The MIDI-playback instrument's product name is **ReaSampler 9000**. The extensio
Set by Daniel on DAW-testing the S1S6 instrument, alongside the UX-overhaul directive.
- **Propagate the display name** across user-visible surfaces: the VST3 class **display
name** string in the factory registration, the `IPlugView` editor **title band**
(currently "ReaSampler Instrument"), the **S6 embed-strip label**, and the Phase S docs.
name** string in the factory registration, the **factory vendor/name strings**, the
`IPlugView` editor **title band** (currently "ReaSampler Instrument"), the **S6 embed-strip
label**, and the Phase S docs.
- **Do NOT change the VST3 class UID.** Instances in already-saved projects key off the
class UID; changing it orphans every existing instance in every saved project. The UID is
a forever-stable contract (mirror of the command-id / ext-state-namespace forever-stable
strings). The name change is **display-string-only** on the code side.
- **Fork S-NAME-1 (Daniel's call): binary filename.** Renaming the built module (e.g.
`reasampler_9000.vst3`) carries compat weight — REAPER partly keys a saved project's
plugin reference by filename, so a rename can force users to re-select the plugin on
existing instances. **Lean: keep the filename, change only display strings** (zero compat
weight; the name shows everywhere the user reads it). Flagged for Daniel, not decided.
strings).
- **S-NAME-1 SETTLED (Daniel, 2026-07-26): rename the binary filename too.** The on-disk
module name is renamed to match the product (e.g. `reasampler_9000.vst3`), not just the
display strings. Full rename surface: **CMake `OUTPUT_NAME`** on the second VST3 target,
the **factory vendor/name strings**, the **editor title**, and the **embed label**. The
**class UID stays locked** as the compat anchor.
- **Compat verification (must-DAW-verify before shipping the rename).** The working
assumption is that REAPER **rebinds a saved instance by its VST3 class UID, not by the
module filename** — so a filename rename with an unchanged UID keeps saved projects working.
**This is a to-verify assumption, not a confirmed fact:** a web check surfaced a
JUCE/VST3-replace-VST2 case suggesting REAPER's binding can be more nuanced than "UID only"
(an FXID match is involved), so it is not safe to assert UID-only rebinding from source.
**DAW-verify:** save a project with an instance under the old filename, rename the module,
reopen, and confirm the instance rebinds and restores its state. If REAPER keys partly on
filename, fall back to keeping the current filename (display-strings-only) and record that
as the shipped choice.
## REAPER / Steinberg API surface (verify all signatures)