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:
+98
@@ -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
|
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.
|
independent of S8, so it can land alongside either.
|
||||||
|
|
||||||
|
## ReaSampler 9000 — the UX overhaul (S10–S13; DAW-tested S1–S6, "the UX is awful")
|
||||||
|
|
||||||
|
**The bar is set: better than ReaSamplOMatic5000.** Daniel DAW-tested the S1–S6
|
||||||
|
instrument and the verdict was that it *works* but the UX is unacceptable — "this is
|
||||||
|
supposed to be better than ReaSamplOMatic5000." The S1–S6 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 **S10–S13**, 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 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.
|
||||||
|
- **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)
|
## REAPER / Steinberg API surface (verify all signatures)
|
||||||
|
|
||||||
- **VST3 SDK (a new vendored dependency — vendor it at the spike).** `FUnknown` and the
|
- **VST3 SDK (a new vendored dependency — vendor it at the spike).** `FUnknown` and the
|
||||||
|
|||||||
@@ -383,6 +383,168 @@ alongside S8.
|
|||||||
stale value by design — it reloads on the *next* poll; confirm no torn-read hazard for the
|
stale value by design — it reloads on the *next* poll; confirm no torn-read hazard for the
|
||||||
single integer generation key).
|
single integer generation key).
|
||||||
|
|
||||||
|
## S10 — direct-manipulation keymap editor ("ReaSampler 9000" UX overhaul, part 1)
|
||||||
|
**Goal:** Replace the ±1 nudge-button zone editor with a **piano-keyboard-strip zone
|
||||||
|
editor** where the keymap is edited by direct manipulation: a horizontal keyboard span
|
||||||
|
along the top, each zone drawn as a bar over the keys it covers; **drag a zone's edge to
|
||||||
|
change its low/high note, drag the bar's body to move the whole zone, click a key (or the
|
||||||
|
zone's root marker) to set the root note.** No number is ever set by clicking a button 40
|
||||||
|
times. This is the friction Daniel feels every test pass — the current row of seven
|
||||||
|
mini-buttons per zone is the catastrophe. All layout/hit-test math is a **new pure
|
||||||
|
geometry module** (`keyboard_strip` — mirror of `mode_switch`/`editor_geometry`); the LICE
|
||||||
|
draw + drag-state machine is the editor shell. RT discipline untouched (edits still commit
|
||||||
|
off-thread via `commitMapAndReload`). CONTEXT.md §Phase S (ReaSampler 9000 UX — keymap
|
||||||
|
editor).
|
||||||
|
**Verify (in DAW):** a zone's range is set by **dragging its edges on the keyboard strip**
|
||||||
|
(not by nudge clicks); dragging a zone's body moves the whole range preserving its span;
|
||||||
|
clicking a key sets/relocates the zone's root (with the repitched result audible on the
|
||||||
|
next held note); overlapping zones render legibly and resolve first-match as before;
|
||||||
|
zone add/select/delete still work; the pure geometry module is CTest-green (edge-grab
|
||||||
|
regions, body-drag delta, key→note mapping, root hit-test) with no host types at its
|
||||||
|
boundary; the ±1 nudge-button row is gone.
|
||||||
|
**Depends on:** S5 (the `PerformanceMap`/zone model it edits), S1 (the LICE `IPlugView`
|
||||||
|
drag/event routing — extends the click-only `wndProc` to `WM_MOUSEMOVE`/`WM_LBUTTONUP`).
|
||||||
|
|
||||||
|
- [ ] Pure `keyboard_strip` geometry module: map a MIDI key span across a strip width
|
||||||
|
(128 keys → pixels, reusing the S6 `embed_strip` key-span idiom); per-zone bar rect from
|
||||||
|
`[lowNote,highNote]`; **edge-grab hit regions** (a few px inside each end = resize handles,
|
||||||
|
the middle = move handle); `pixel→note` and a `keyAtPoint` for click-to-set-root; a
|
||||||
|
drag-delta resolver `(grabbedField, startNote, dxPixels) → newNote`. No VST3/REAPER/LICE
|
||||||
|
types at the boundary; unit-tested outside the DAW (edge grabs, body-move delta, key
|
||||||
|
mapping, clamps low≤high, boundary rounding). Mirror of `mode_switch`/`editor_geometry`.
|
||||||
|
- [ ] Editor shell: draw the keyboard strip + zone bars in LICE (house palette), and drive
|
||||||
|
a **drag-state machine** — `WM_LBUTTONDOWN` grabs an edge/body/key, `WM_MOUSEMOVE`
|
||||||
|
updates the in-flight zone against the pure resolver, `WM_LBUTTONUP` commits via the
|
||||||
|
existing `commitMapAndReload` (off-thread reload; RT path untouched). Live visual feedback
|
||||||
|
while dragging; a single undo-coherent edit on release.
|
||||||
|
- [ ] Click-to-set-root + zone move/resize replace the seven per-row nudge/delete
|
||||||
|
mini-buttons; delete stays as one affordance (a small × on the zone bar or a keystroke).
|
||||||
|
The `zoneHitTest`/±1 nudge path in `editor_geometry` is retired for the new strip (kept
|
||||||
|
only if a numeric fallback is wanted for accessibility — build-time residual, not a fork).
|
||||||
|
|
||||||
|
## S11 — waveform view with draggable loop points (UX overhaul, part 2)
|
||||||
|
**Goal:** Give each sample/zone a **waveform display** with **draggable start/end/loop
|
||||||
|
markers** — the S2 loop-point intrinsics and the S5 performance map already carry the data;
|
||||||
|
today there is no way to *see* a sample or *set* its loop by eye. Selecting a zone (or a
|
||||||
|
bank sample) shows its waveform (peaks via the existing `peaks` module, fed the decoded
|
||||||
|
PCM the shell already loads); drag the **loop-start / loop-end** markers to set the sustain
|
||||||
|
loop, snapping to zero-crossings (the S2 spec's zero-crossing-aware requirement). Loop
|
||||||
|
points are a **performance-map override on the zone** where set, seeded from the bank
|
||||||
|
intrinsic (D-B split: the bank carries the file-fact default; the instrument's drag is the
|
||||||
|
performance choice). All marker/waveform layout + hit-test is pure geometry; peaks compute
|
||||||
|
reuses `peaks`; the draw + drag is the shell. CONTEXT.md §Phase S (ReaSampler 9000 UX —
|
||||||
|
waveform view).
|
||||||
|
**Verify (in DAW):** selecting a zone shows its sample's waveform; dragging the loop-start
|
||||||
|
and loop-end markers sets the sustain loop and a held note audibly loops that region;
|
||||||
|
markers snap to the nearest zero-crossing; a sample with no loop shows the "no loop" state
|
||||||
|
and a held note past the end goes silent (existing core behavior); the waveform peaks match
|
||||||
|
the audio (mirror of the `peaks` envelope assertion); the marker geometry module is
|
||||||
|
CTest-green (px↔frame mapping, marker grab regions, clamp start≤end).
|
||||||
|
**Depends on:** S2 (loop-point intrinsics), S3 (loop-aware sustain the markers drive), S5
|
||||||
|
(the zone the loop attaches to), S10 (shares the editor's drag-state machine + shell). The
|
||||||
|
zero-crossing snap is a small pure helper over the decoded PCM.
|
||||||
|
|
||||||
|
- [ ] Pure waveform/marker geometry: `frame↔pixel` mapping across the waveform rect, marker
|
||||||
|
x-position from a frame index, marker grab regions (start/end/loop-start/loop-end),
|
||||||
|
drag-delta `(grabbedMarker, dxPixels) → newFrame` with clamps (start≤end, in-bounds). A
|
||||||
|
**zero-crossing snap** helper: nearest sign-change frame to a target (pure, over the
|
||||||
|
decoded mono PCM). No host types; unit-tested.
|
||||||
|
- [ ] Waveform draw: compute peaks with the existing `peaks` module from the shell's already-
|
||||||
|
decoded PCM (no new decode path, no new WAV reader); draw the envelope in LICE in the
|
||||||
|
house style; draw the loop markers over it. Reuses the S10 drag-state machine.
|
||||||
|
- [ ] Loop-point edit → performance-map override: a dragged loop writes a per-zone loop
|
||||||
|
override (seeded from the S2 bank intrinsic, D-B), committed off-thread via
|
||||||
|
`commitMapAndReload`; the bank intrinsic is never written back (instrument is a read-only
|
||||||
|
bank consumer). Extends `PerformanceZone` with an optional loop override (additive, same
|
||||||
|
shape as `rootOverride`) + its component-state (de)serialize (version bump, back-compat
|
||||||
|
with S5's v2 map blob — a truncated/older blob defaults the override absent).
|
||||||
|
|
||||||
|
## S12 — editor scale + ergonomics (UX overhaul, part 3; scrollable/searchable list, direct entry)
|
||||||
|
**Goal:** Make the editor usable **at bank scale** and close the remaining RS5K-parity
|
||||||
|
gaps: the sample list **scrolls** (today a long bank's rows run off the panel with no way
|
||||||
|
to reach them) and has a **type-to-filter search**; add **direct numeric entry** for a
|
||||||
|
zone's low/high/root (a click-to-type field over the strip, for precision the drag can't
|
||||||
|
hit) and an **ADSR control** for the amp envelope (S3 already has the ADSR math; today it
|
||||||
|
is fixed — expose attack/decay/sustain/release as draggable sliders, per-instance state).
|
||||||
|
This is the "sensible list handling + direct manipulation of the parameters that exist"
|
||||||
|
tier. All slider/scroll/search-box layout + hit-test is pure geometry; the shell draws +
|
||||||
|
routes; ADSR/scroll/filter state is instrument-owned (component state / transient UI
|
||||||
|
state). CONTEXT.md §Phase S (ReaSampler 9000 UX — scale + ergonomics).
|
||||||
|
**Verify (in DAW):** a bank with more samples than fit **scrolls** (wheel + drag) and every
|
||||||
|
sample is reachable; typing filters the list to matching names; a zone's low/high/root can
|
||||||
|
be **typed** (not only dragged) via a click-to-edit field; the amp envelope's ADSR is
|
||||||
|
**adjustable** (four draggable controls) and the change is audible + persists across project
|
||||||
|
save/reopen (component state); the scroll/search/slider geometry is CTest-green.
|
||||||
|
**Depends on:** S10 (the editor shell + drag-state machine), S3 (the `AdsrParams` the ADSR
|
||||||
|
sliders drive — already wired into the voice engine; today they are fixed defaults), S5
|
||||||
|
(the map the numeric fields edit).
|
||||||
|
|
||||||
|
- [ ] Scrollable, searchable sample list: a scroll offset (wheel + scrollbar drag) so long
|
||||||
|
banks are fully reachable; a type-to-filter search that narrows the drawn rows to matching
|
||||||
|
display names. Scroll/filter layout + hit-test is pure geometry (visible-row window,
|
||||||
|
scrollbar thumb rect, search-box rect); filter/scroll state is transient UI state.
|
||||||
|
- [ ] Direct numeric entry for zone low/high/root: a click-to-edit field over the strip
|
||||||
|
(LICE text-entry idiom or a SWELL edit control on the child HWND) so a precise note can be
|
||||||
|
typed, not only dragged. Commits via `commitMapAndReload` like every other edit.
|
||||||
|
- [ ] ADSR editor: four draggable controls (attack/decay/sustain/release) over the S3
|
||||||
|
`AdsrParams`; per-instance component state (additive to the map/selection blob, version-
|
||||||
|
bumped, back-compat defaults to the current fixed envelope). Slider layout/hit-test pure;
|
||||||
|
the audible envelope change goes through the same off-thread reload.
|
||||||
|
|
||||||
|
## S13 — drop-to-load: the S8 ingest story, folded into the editor UX (UX overhaul, part 4)
|
||||||
|
**Goal:** Make "load a sample into the sampler" **one gesture from the editor**: dropping
|
||||||
|
an OS file (or REAPER media item) **onto the editor window** ingests it into the bank and
|
||||||
|
assigns it to this instance — the RS5K "drag a file straight onto it" affordance, which is
|
||||||
|
the single biggest first-impression win RS5K has and we currently lack. This is the
|
||||||
|
**editor-window end of S8's `option 1` ingest** — the instrument does **not** ingest itself
|
||||||
|
(it stays a read-only bank consumer); the editor's drop handler **relays a bank-ingest
|
||||||
|
request to the extension** over the agreed cross-artifact seam, and the extension performs
|
||||||
|
the capture/import-into-bank + assign. S8 already flags drop-onto-editor as an unproven
|
||||||
|
cross-artifact **spike** — this point is where that spike is either proven and shipped or
|
||||||
|
falls back to the docked-panel drop path. CONTEXT.md §Phase S (ReaSampler 9000 UX — drop to
|
||||||
|
load / S8 relay). **Cross-artifact relay is a spike, not a promise — sequence after S8.**
|
||||||
|
**Verify (in DAW):** an OS file dropped onto the ReaSampler 9000 editor window ingests into
|
||||||
|
the active bank and this instance plays it (via the S8 capture/import add-path + S9 refresh,
|
||||||
|
or a direct reload if S9 absent) — **never** inserting a timeline item (capture/placement
|
||||||
|
separation intact); the instrument itself performs no capture/import/write (the editor only
|
||||||
|
*relays* the request to the extension); if the cross-artifact relay proves unworkable, the
|
||||||
|
drop-onto-docked-`bank_panel` path (S8) is the shipped ingest and this degrades cleanly with
|
||||||
|
a clear affordance pointing there.
|
||||||
|
**Depends on:** S8 (owns the extension-side capture/import + assign, and the relay seam), S1
|
||||||
|
(the editor HWND that accepts the drop), S9 (hands-free refresh after assign; functional
|
||||||
|
without it via a direct reload). **Spike — do not promise the drop-onto-editor path until
|
||||||
|
the relay is proven.**
|
||||||
|
|
||||||
|
- [ ] Editor-window drop target: accept `WM_DROPFILES`/`IDropTarget` on the editor child
|
||||||
|
HWND (the same SWELL/Win32 surface `bank_panel` owns), extracting the dropped file
|
||||||
|
path(s). Windows-only (D5). This is the *acceptance* half; the ingest is the extension's.
|
||||||
|
- [ ] Cross-artifact ingest relay (the S8-flagged spike): the editor hands the dropped
|
||||||
|
path + this instance's identity to the extension as a **bank-ingest request** over the
|
||||||
|
agreed seam (the instrument never writes the bank). **Prove the relay mechanism before
|
||||||
|
promising it**; if gnarly, fall back to the S8 docked-panel drop path and mark
|
||||||
|
drop-onto-editor deferred.
|
||||||
|
- [ ] UX degrade path: when the relay is unavailable/unproven, the editor shows a clear
|
||||||
|
"drop files on the ReaSampler panel to add" affordance rather than silently swallowing the
|
||||||
|
drop — the shipped ingest gesture stays discoverable either way.
|
||||||
|
|
||||||
|
## Phase S — product name (ReaSampler 9000)
|
||||||
|
The MIDI-playback instrument's product name is **ReaSampler 9000** (Daniel, 2026-07-26,
|
||||||
|
on DAW-testing the S1–S6 instrument). The extension remains **ReaSampler**; the instrument
|
||||||
|
is **ReaSampler 9000**. Framing + propagation surfaces:
|
||||||
|
`docs/product/midi-playback.md` §Product name.
|
||||||
|
|
||||||
|
- [ ] Propagate the display name **ReaSampler 9000** 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 it; a
|
||||||
|
UID change orphans every existing instance (fork below).
|
||||||
|
- [ ] **Fork S-NAME-1 (Daniel's call): the binary filename.** Renaming the built VST3
|
||||||
|
module (e.g. `reasampler_9000.vst3`) is a compat break — REAPER keys a saved project's
|
||||||
|
plugin reference partly by filename, so a rename can require users to re-select the plugin
|
||||||
|
on existing instances. Lean: **keep the current filename, change only display strings**
|
||||||
|
(zero compat weight, the name shows everywhere the user reads), unless Daniel wants the
|
||||||
|
on-disk name to match. Flag, do not decide.
|
||||||
|
|
||||||
## S17 — drop-and-load: drag a capture onto a track's FX button → instantiate ReaSampler 9000 with the capture loaded
|
## S17 — drop-and-load: drag a capture onto a track's FX button → instantiate ReaSampler 9000 with the capture loaded
|
||||||
**Goal:** Turn a bank capture into a playable instrument in one gesture. Today a drag
|
**Goal:** Turn a bank capture into a playable instrument in one gesture. Today a drag
|
||||||
out of the `bank_panel` becomes an OS file drag once it leaves the panel (M11 —
|
out of the `bank_panel` becomes an OS file drag once it leaves the panel (M11 —
|
||||||
|
|||||||
@@ -7,7 +7,10 @@ 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
|
*why* (the plugin-format reasoning, the bare-VST3-vs-JUCE assessment, the settled
|
||||||
decision record).
|
decision record).
|
||||||
|
|
||||||
Status: framed by product-designer (2026-07-26), **revised 2026-07-26 (r4)**. The
|
Status: framed by product-designer (2026-07-26), **revised 2026-07-26 (r5)**. r5 records
|
||||||
|
the post-DAW-test directives on the S1–S6 instrument: the product name **ReaSampler 9000**
|
||||||
|
and the **"better than RS5K" UX overhaul** (Phase S points S10–S13) — see the Addendum in
|
||||||
|
§4. r4 (below) settled the four residual forks D-A..D-D. The
|
||||||
"no PLAN.md footprint" era is **over** — with D-A through D-D settled (below), the
|
"no PLAN.md footprint" era is **over** — with D-A through D-D settled (below), the
|
||||||
instrument was scoped into **Phase S** (codename Daniel's: "S" for Sampler, because "D"
|
instrument was scoped into **Phase S** (codename Daniel's: "S" for Sampler, because "D"
|
||||||
collides with the existing Design View phase). **PLAN.md §Phase S is now the
|
collides with the existing Design View phase). **PLAN.md §Phase S is now the
|
||||||
@@ -658,6 +661,56 @@ with the honest SDK reality verified against the vendored headers:
|
|||||||
ME merely-selected-file read (b), and the drop-onto-editor cross-artifact relay (c). Both
|
ME merely-selected-file read (b), and the drop-onto-editor cross-artifact relay (c). Both
|
||||||
are honestly-flagged as spikes in PLAN.md S8, not promised.
|
are honestly-flagged as spikes in PLAN.md S8, not promised.
|
||||||
|
|
||||||
|
### Addendum — product name + UX overhaul (Daniel, 2026-07-26, post-S1–S6 DAW test)
|
||||||
|
|
||||||
|
Daniel DAW-tested the S1–S6 instrument and set two directives. These are **settled
|
||||||
|
directions**, specced as new Phase S points (S10–S13) and a product-name convention — not
|
||||||
|
open forks (the two flagged forks below are the only calls left to Daniel).
|
||||||
|
|
||||||
|
**The instrument's product name is `ReaSampler 9000`.** The extension stays **ReaSampler**
|
||||||
|
(capture + organization); the instrument is **ReaSampler 9000** (playback). Propagation is
|
||||||
|
a checklist item (PLAN.md §Phase S — product name; CONTEXT.md §Product name): the VST3
|
||||||
|
class **display name** string, the `IPlugView` editor title band (today "ReaSampler
|
||||||
|
Instrument"), the S6 embed-strip label, and the docs. **Compat guard (load-bearing):** the
|
||||||
|
**VST3 class UID must NOT change** — instances in saved projects key off it; a UID change
|
||||||
|
orphans every existing instance. The name change is **display-string-only** on the code
|
||||||
|
side. *Fork S-NAME-1 (Daniel's call):* the on-disk **binary filename** — renaming it
|
||||||
|
(`reasampler_9000.vst3`) carries compat weight (REAPER keys a saved project's plugin
|
||||||
|
reference partly by filename), so the lean is **keep the filename, change only display
|
||||||
|
strings**; flagged, not decided.
|
||||||
|
|
||||||
|
**The UX bar is "better than ReaSamplOMatic5000."** Verdict verbatim: "okay it works, but
|
||||||
|
the UX is awful." The S1–S6 editor was spike-grade — a clickable list, zone rows with
|
||||||
|
**seven ±1 nudge/delete mini-buttons** each, text labels, **no keyboard, no waveform, no
|
||||||
|
drag, no scroll.** Setting a zone range by ±1 clicks is the catastrophe. The overhaul
|
||||||
|
(S10–S13) makes "better than RS5K" *specific*:
|
||||||
|
|
||||||
|
- **RS5K's strengths, matched or beaten.** Drag-a-file-onto-it load (→ S13 relay);
|
||||||
|
note-range + a visual keyboard (→ S10 — RS5K uses two *number fields*, so a **draggable
|
||||||
|
keyboard strip** beats it); waveform with draggable start/end/loop markers (→ S11); ADSR
|
||||||
|
sliders (→ S12). Velocity layers / round-robin stay Tier 2 (held).
|
||||||
|
- **RS5K's weaknesses, our opening.** RS5K is **one-sample-per-instance** (forcing track
|
||||||
|
sprawl — one instance per drum) with **no multi-zone view in a single instance**.
|
||||||
|
ReaSampler 9000 is **multi-zone in one instrument** (S5), so the keyboard-strip editor
|
||||||
|
showing *every* zone at once is a capability RS5K structurally lacks. That is the
|
||||||
|
sharpest "better than RS5K" claim, and it's free — it falls out of the existing model.
|
||||||
|
|
||||||
|
The overhaul honors every settled constraint: **LICE/SWELL only** (D-A), **pure geometry
|
||||||
|
modules** for all layout/hit-test (mirror of `mode_switch`/`editor_geometry`/`embed_strip`),
|
||||||
|
**RT discipline untouched** (edits commit off-thread), the instrument stays a **read-only
|
||||||
|
bank consumer** (loop/root/ADSR edits are the instrument's performance map, D-B — never
|
||||||
|
written to the bank). Component-state persistence and read-only-over-bank stay settled.
|
||||||
|
|
||||||
|
*Sequencing (product recommendation).* **S10 leads** — the nudge-button zone editor is the
|
||||||
|
friction Daniel hits on every test pass, so removing it buys the most felt improvement per
|
||||||
|
unit of work and de-risks the drag-state machine S11/S12 reuse. Against the queued **S7
|
||||||
|
(stereo)**: S10 should land **before or interleaved with** S7 — S7 is real engine work but
|
||||||
|
the *reason* Daniel keeps smoke-testing is the editor, and every test pass is currently
|
||||||
|
taxed by the UX; the two are orthogonal (S7 = engine/bus, S10 = editor/geometry), so there
|
||||||
|
is no hard ordering, but the live wound is the editor. Honest counter: if the stereo
|
||||||
|
*sound* is what blocks real use, S7-first is defensible — but "it works, the UX is awful"
|
||||||
|
names the editor as the wound.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Where this landed
|
## Where this landed
|
||||||
@@ -683,12 +736,22 @@ Two further directions set post-scoping (2026-07-26; see the Addendum in §4):
|
|||||||
hands-free refresh** (**S9**) — one-gesture capture/import + assign; the instrument stays
|
hands-free refresh** (**S9**) — one-gesture capture/import + assign; the instrument stays
|
||||||
a read-only consumer.
|
a read-only consumer.
|
||||||
|
|
||||||
|
Post-DAW-test directives (2026-07-26; see the "product name + UX overhaul" Addendum in §4):
|
||||||
|
|
||||||
|
7. **Product name → `ReaSampler 9000`** (display-string-only; VST3 class UID unchanged;
|
||||||
|
binary filename = fork S-NAME-1, Daniel's call).
|
||||||
|
8. **UX overhaul → "better than RS5K"** (**S10–S13**): direct-manipulation keyboard-strip
|
||||||
|
keymap editor (S10), waveform + draggable loop points (S11), scale/ergonomics — scroll,
|
||||||
|
search, direct numeric entry, ADSR (S12), and drop-to-load folding in the S8 relay (S13).
|
||||||
|
|
||||||
**Authoritative from here:** **PLAN.md §Phase S** is the roadmap (S1–S6 the original
|
**Authoritative from here:** **PLAN.md §Phase S** is the roadmap (S1–S6 the original
|
||||||
dependency chain: spike → `Sample` fields → pure sampler core → Tier 0 → Tier 1 → embedded
|
dependency chain: spike → `Sample` fields → pure sampler core → Tier 0 → Tier 1 → embedded
|
||||||
UI; then **S7** stereo, **S8** ingest, **S9** change-detection); **CONTEXT.md §Phase S** is
|
UI; then **S7** stereo, **S8** ingest, **S9** change-detection, **S10–S13** the ReaSampler
|
||||||
the spec (seam-field semantics, scope contracts, the channel-mode / ingest / bank-generation
|
9000 UX overhaul); **CONTEXT.md §Phase S** is the spec (seam-field semantics, scope
|
||||||
contracts, the pure/shell split, the must-verify SDK/bridge surfaces). This doc is the
|
contracts, the channel-mode / ingest / bank-generation contracts, the UX-overhaul spec, the
|
||||||
framing/decision record they point back to. The "no PLAN.md footprint" era is over.
|
product-name convention, the pure/shell split, the must-verify SDK/bridge surfaces). This
|
||||||
|
doc is the framing/decision record they point back to. The "no PLAN.md footprint" era is
|
||||||
|
over.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user