diff --git a/CONTEXT.md b/CONTEXT.md index 69dae11..9e85295 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -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 (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) - **VST3 SDK (a new vendored dependency — vendor it at the spike).** `FUnknown` and the diff --git a/PLAN.md b/PLAN.md index 0d618d8..5db07fc 100644 --- a/PLAN.md +++ b/PLAN.md @@ -383,6 +383,168 @@ alongside S8. stale value by design — it reloads on the *next* poll; confirm no torn-read hazard for the 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 **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 — diff --git a/docs/product/midi-playback.md b/docs/product/midi-playback.md index 0632ff2..ba9ed41 100644 --- a/docs/product/midi-playback.md +++ b/docs/product/midi-playback.md @@ -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 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 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 @@ -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 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 @@ -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 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 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 -the spec (seam-field semantics, scope contracts, the channel-mode / ingest / bank-generation -contracts, 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. +UI; then **S7** stereo, **S8** ingest, **S9** change-detection, **S10–S13** the ReaSampler +9000 UX overhaul); **CONTEXT.md §Phase S** is the spec (seam-field semantics, scope +contracts, the channel-mode / ingest / bank-generation contracts, the UX-overhaul spec, the +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. ---