docs(product): scope ReaSampler 9000 UX overhaul (S10-S13) + record instrument name

Post-DAW-test: name the instrument ReaSampler 9000; spec the better-than-RS5K
overhaul — S10 keyboard-strip keymap editor, S11 waveform + draggable loop
points, S12 scroll/search/direct-entry/ADSR, S13 drop-to-load via the S8 relay.
VST3 class UID locked unchangeable; S-NAME-1 (binary filename) is Daniel's call.
This commit is contained in:
2026-07-26 19:03:26 -04:00
parent dc5d36ff43
commit 8c9cf38780
3 changed files with 328 additions and 5 deletions
+98
View File
@@ -1392,6 +1392,104 @@ without re-opening each editor. The missing trigger: a **bank-generation counter
This seam serves **both** S8 ingest and M10 recapture; the writer side is extension-only and
independent of S8, so it can land alongside either.
## ReaSampler 9000 — the UX overhaul (S10S13; DAW-tested S1S6, "the UX is awful")
**The bar is set: better than ReaSamplOMatic5000.** Daniel DAW-tested the S1S6
instrument and the verdict was that it *works* but the UX is unacceptable — "this is
supposed to be better than ReaSamplOMatic5000." The S1S6 editor was a spike-grade LICE
panel: a clickable sample list, zone rows each carrying **seven tiny ±1 nudge/delete
mini-buttons** (low-/low+/high-/high+/root-/root+/delete), text-only labels, **no keyboard
visualization, no waveform, no drag interaction of any kind, no scrolling** for long lists.
Setting a zone from C1 to C4 by clicking "+" thirty-six times is the catastrophe; the rest
(no way to *see* a sample, no loop editing by eye, unreachable rows past the panel bottom,
a fixed envelope) compound it. The overhaul is scoped as **S10S13**, sequenced so the
friction Daniel feels every test pass is removed first.
**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
strip — RS5K's own range UI is two number fields, so a *draggable* strip beats it); (3) a
**waveform** with draggable start/end/loop markers (our S11); (4) **ADSR** sliders (our
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.
**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
`mode_switch` / `editor_geometry` / `embed_strip`), the draw + drag-state machine in the
shell; RT discipline untouched (every edit commits **off** the audio thread via the
existing `commitMapAndReload` → off-thread `reloadFromBank` → atomic swap); the instrument
stays a **read-only bank consumer** (loop/root/ADSR edits are the instrument's *performance
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.
- **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
**snap to zero-crossings** (the S2 zero-crossing-aware requirement). A dragged loop is a
**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).
- **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
drop handler **relays a bank-ingest request to the extension** (S8's `option 1`), which
performs the capture/import + assign; refresh is hands-free via S9 (or a direct reload
without it). **Cross-artifact relay is the S8-flagged spike** — proven-and-shipped or
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
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
either way (S7 is engine/bus, S10 is editor/geometry — orthogonal). Honest counter: if the
stereo *sound* is the thing blocking real use, S7 first is defensible — but "it works, the
UX is awful" points at the editor as the live wound, so **S10 leads.**
## Product name — ReaSampler 9000 (Daniel, 2026-07-26)
The MIDI-playback instrument's product name is **ReaSampler 9000**. The extension stays
**ReaSampler** (capture + organization); the instrument is **ReaSampler 9000** (playback).
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.
- **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.
## REAPER / Steinberg API surface (verify all signatures)
- **VST3 SDK (a new vendored dependency — vendor it at the spike).** `FUnknown` and the