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:
+96
-36
@@ -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 **S10–S13**, 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 S1–S6 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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user