From e4f4691a0d3575407a5c147a2ea0bd2fed5f7bbd Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Mon, 27 Jul 2026 21:07:19 -0400 Subject: [PATCH] docs: rewrite README to current state, retire TODO.md, fix stale mpe_model ref README was frozen at Milestone 0. TODO.md was entirely M0-M2 tasks, all landed. CONTEXT.md intro cited a file deleted in M0. --- CONTEXT.md | 12 +++--- README.md | 107 +++++++++++++++++++++++++++++------------------------ TODO.md | 63 ------------------------------- 3 files changed, 64 insertions(+), 118 deletions(-) delete mode 100644 TODO.md diff --git a/CONTEXT.md b/CONTEXT.md index e1fda7d..74048c3 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -6,12 +6,12 @@ arrange view, with keyboard/MIDI-bindable capture and placement. Built as a precision tool: deterministic, non-destructive, no clutter. This document is the spec. Read the existing scaffold first (`src/main.cpp` is -the REAPER<->extension contract; the pure/testable-core split in `src/mpe_model.*` -is the pattern to preserve — the MPE model is being replaced, the *discipline* -is not). Verify every REAPER API name and signature against -`vendor/reaper-sdk/sdk/reaper_plugin_functions.h` before use — the API names in -this brief are correct-by-intent but treat them as hints, not gospel, and check -argument order/types. +the REAPER<->extension contract; the pure/testable-core split in `src/bank_model.*` +is the pattern to preserve — the *discipline* of a pure testable core split from +REAPER-facing shells runs throughout the codebase). Verify every REAPER API name +and signature against `vendor/reaper-sdk/sdk/reaper_plugin_functions.h` before use +— the API names in this brief are correct-by-intent but treat them as hints, not +gospel, and check argument order/types. ## The load-bearing principle diff --git a/README.md b/README.md index 5d0d1f6..b0c94c4 100644 --- a/README.md +++ b/README.md @@ -5,79 +5,88 @@ per-project **sample bank** (cached files + a docked grid), decoupled from the arrange view, with keyboard/MIDI-bindable capture and placement. Built as a precision tool: deterministic, non-destructive, no clutter. -This is a **skeleton**: the loading contract, build system, and the testable -pure-core library are wired up. The bank panel, capture backend, and remaining -module set are stubbed with clearly marked seams. +## The two artifacts -## Layout +**`reaper_reasampler`** — the REAPER extension. Captures audio into a named, +per-project sample bank, displays it in a docked panel, and provides bindable +actions for capture and placement. - src/main.cpp The REAPER<->extension contract: the single file that - #defines REAPERAPI_IMPLEMENT, resolves API pointers, - and holds the action-registration seam (commented, - ready to reinstate under the CEREBELLUM_REASAMPLER_ - prefix). Logs "ReaSampler loaded." on startup. - src/bank_model.{h,cpp} Pure, REAPER-free core: the Sample metadata struct and - BankIndex (add / remove / query / tier moves / - dedup-by-hash + JSON round-trip). This is the heart; - everything else hangs off it. Currently an M0 - placeholder — the full implementation is Milestone 1. - tests/test_bank_model.cpp Standalone tests for bank_model — no REAPER needed. - vendor/ git submodules go here (see below). +**ReaSampler 9000** (`reasampler_9000.vst3`) — a Windows-only VST3 sampler +instrument that plays bank captures back across a MIDI keyboard. The VST3 target +(`reasampler_vst`) is gated on the vendored `vendor/vst3sdk` slice; configure +quietly omits it if the slice is absent. -Target module set (milestones ahead — see PLAN.md): +A **beta channel** build is available via `-DREASAMPLER_CHANNEL=beta` at configure +time, producing `reaper_reasampler_beta` and `reasampler_9000_beta.vst3`. The two +channels coexist in one REAPER installation and do not share state. - bank_model Sample metadata + BankIndex + JSON (pure) - peaks Waveform min/max bins from raw PCM (pure) - capture ICaptureBackend: OfflineRenderBackend + RealtimeRecordBackend - insert InsertMedia-based placement (explicit tempo-conform flag) - bank_panel Docked LICE-drawn grid: thumbnails, audition, multi-select - persist Project ext state <-> bank_model JSON; project-relative paths - actions Bindable capture / placement / slot action family +## The load-bearing principle + +Capture and placement are separate acts. Capturing audio writes a file to the bank +and adds an index entry. It **never** puts an item in the arrange view. Placement +is a distinct, on-demand action. Any code path that auto-inserts a capture into the +timeline violates the purpose of the tool. ## One-time setup git submodule update --init -Vendors two submodules: +Vendors three submodules: - `vendor/reaper-sdk` — `sdk/reaper_plugin.h`, `sdk/reaper_plugin_functions.h`, SWELL headers - `vendor/WDL` — WDL utilities and the SWELL cross-platform Win32 layer +- `vendor/vst3sdk` — Steinberg VST3 SDK (Windows-only; requires a nested init after the top-level init): -## Build + git submodule update --init vendor/vst3sdk + cd vendor/vst3sdk && git submodule update --init pluginterfaces base public.sdk + +## Build and test cmake -B build -S . cmake --build build + ctest --test-dir build -Targets: -- `bank_model_tests` — run with `ctest --test-dir build` (or run the binary). - This is your fast loop: iterate the pure core without touching REAPER. -- `reaper_reasampler` — the extension binary. +Pure modules have `_tests` targets that run without REAPER or a DAW. +`CMakeLists.txt` is the authoritative list of all targets. + +### Beta channel + + cmake -B build-beta -S . -DREASAMPLER_CHANNEL=beta + cmake --build build-beta ### macOS / Linux dialog resources -When `bank_panel` is added (Milestone 5), `resource.rc` will need SWELL's resgen -once (Win32 compiles it directly). Generate the SWELL dialog source and add it to -the non-Windows build: +`src/resource.rc` must be pre-processed by SWELL's resgen once per platform: - php vendor/WDL/WDL/swell/mac_resgen.php src/resource.rc # macOS - # (Linux uses the same generated output.) + php vendor/WDL/WDL/swell/mac_resgen.php src/resource.rc # macOS; Linux reuses the output -Then add the generated file to the `APPLE` / Linux `target_sources` blocks in -CMakeLists.txt. The SWS extension's build is the canonical reference if you get -stuck here — it's the fiddliest step and only bites once. +Add the generated file to the appropriate `APPLE` / Linux `target_sources` block in +CMakeLists.txt. The SWS extension build is the canonical reference for this step. -## Install / test +## Install Copy the built binary into REAPER's `UserPlugins/` folder -(Options -> Show REAPER resource path), then **restart REAPER** (extensions load -at startup; there is no hot reload). The extension logs "ReaSampler loaded." to -the REAPER console on startup; no actions are registered yet. +(Options → Show REAPER resource path), then **restart REAPER**. Extensions load at +startup only; there is no hot reload. -Debug by attaching your debugger to the REAPER process. `ShowConsoleMsg` is a -quick printf. +## Repo layout -## Where to build next +The codebase is organized around one discipline: **pure, REAPER-free testable core +split from REAPER-facing shells**. -See `PLAN.md` for the full milestone roadmap and `TODO.md` for the near-term slice. -The current first work is **Milestone 1** — flesh out `bank_model`: define the full -`Sample` field set, implement `BankIndex` (add / remove / query / tier / dedup), -add JSON serialize/deserialize, and drive it all through the existing CTest harness. +- `src/` — pure core modules (no REAPER types, unit-testable outside the DAW) and + REAPER-facing shells (extension entry point, panel, actions, capture backends, etc.) +- `src/vst/` — the VST3 instrument: pure voice engine + zone payload + editor UI + pure modules, and the VST3 shells +- `tests/` — unit tests for the pure core modules +- `vendor/` — git submodules + +See `CLAUDE.md` for the full module inventory, architectural contracts, and the +precise boundary between pure core and REAPER-facing shells. + +## Further reading + +- `CLAUDE.md` — architecture, module inventory, and build/API contracts +- `CONTEXT.md` — the authoritative spec (large: ~186k — grep the relevant section rather than reading whole) +- `CONTEXT-ARCHIVE.md` — build detail for landed work +- `PLAN.md` — roadmap +- `COMPLETED.md` — landed milestones diff --git a/TODO.md b/TODO.md deleted file mode 100644 index a78f531..0000000 --- a/TODO.md +++ /dev/null @@ -1,63 +0,0 @@ -# TODO.md — near-term actionable slice - -The immediate, ordered tasks to execute the first step of `PLAN.md`: Milestone 0 -(transition) → Milestone 1 (`bank_model`) → Milestone 2 (`peaks`). Everything past -M2 lives in `PLAN.md`, not here. Verify REAPER API names/flags against -`vendor/reaper-sdk/sdk/reaper_plugin_functions.h` before use. - -## Now — Milestone 0: transition scaffold - -1. Delete the MPE modules: `src/mpe_model.{h,cpp}`, `src/mpe_view.{h,cpp}`, - `tests/test_mpe_model.cpp`. -2. CMakeLists.txt — rename `project(reaper_mpeview …)` and the MODULE target to - `reaper_reasampler`; update `OUTPUT_NAME`, `PREFIX ""`, and the WIN32/APPLE/ - Linux SUFFIX blocks to the new target name. -3. CMakeLists.txt — replace the `mpe_model` static lib with a `bank_model` static - lib (`src/bank_model.cpp`, `PUBLIC src` includes); replace `mpe_model_tests` - with `bank_model_tests` (`tests/test_bank_model.cpp`), keep `add_test` / CTest. -4. `src/main.cpp` — remove `#include "mpe_view.h"` and every `MpeView_*` call - (`MpeView_Toggle`, `MpeView_IsOpen`, `MpeView_OnTimer`, `MpeView_Cleanup`). - Leave a minimal, loadable extension entry that resolves API pointers and logs - to console; keep the `command_id`/`gaccel`/`hookcommand` registration pattern - as a commented seam for the future action family. -5. `src/main.cpp` — replace the `CEREBELLUM_MPEVIEW_TOGGLE` action string with the - chosen sampler action-id prefix (record the prefix in a comment; it is - forever-stable once shipped). -6. Confirm the tree still configures and builds: - `cmake -B build -S .` → `cmake --build build` → `ctest --test-dir build`. - (bank_model tests may be a single placeholder assertion at this point.) -7. README.md — retarget the layout / "where to build next" sections to the - sampler module set so the first implementer is not misled by MPE prose. - -## Next — Milestone 1: bank_model + JSON round-trip (pure, no REAPER) - -8. `src/bank_model.h` — define `Sample` with the full field set from CONTEXT.md - §Data model (id, name, relative path, source mode, source range project-time + - PPQ, track GUID(s), wet/dry, channels, SR, length sec + beats, capture tempo, - optional key, peak/RMS/LUFS, clip flag, tier, content hash, provenance, ts). -9. `src/bank_model.h/.cpp` — `BankIndex`: ordered, keyed by id; `add` / `remove` / - `query`. -10. Dedup: content-hash lookup so an add with an existing hash collapses. -11. Tiers: `scratch` | `archive`, tier-move, tier filtering; scratch auto-prunable. -12. JSON serialize/deserialize to/from `std::string` (self-contained; no external - JSON dep unless one is already vendored — check first). -13. Enforce **relative-paths-only** at the model boundary (reject/normalize - absolute paths on add). -14. `tests/test_bank_model.cpp` — assert: full-field round-trip lossless; dedup - collapses equal-hash adds; tier move + filter correct; absolute-path rejected; - empty-index and malformed-JSON edge cases. - -## Then — Milestone 2: peaks (pure, no REAPER) - -15. `src/peaks.h/.cpp` — min/max bin computation from interleaved PCM for a target - bin count; per-channel (no silent fold). Add `peaks.cpp` to the `bank_model` - lib (or a sibling pure lib) so tests link it. -16. `tests/test_peaks.cpp` (+ CTest entry) — assert: full-scale sine envelope ≈ - ±amplitude per bin; ramp envelope monotonic; silence/DC → zero envelope; - short-buffer and non-divisible-length (remainder bin) edge cases. - -## Definition of done for this slice -- `ctest --test-dir build` green with `bank_model_tests` and `peaks` tests present. -- No `mpe`/`Mpe`/`MPE` symbols remain in `src/` or `tests/`. -- The extension target builds under the new name and loads in REAPER (console log - on load); it registers no half-wired actions.