Resolve ReaSampler 9000 samples against the instance's own project, not the focused tab

sampleRoots matches getReaperParent(3) among EnumProjects' open projects; every instrument sample read goes through an ordered root list (one root today) so a later temp-bank root slots in after it.
This commit is contained in:
2026-09-25 14:55:50 -04:00
parent c3e7556261
commit 0976ea13a8
11 changed files with 304 additions and 42 deletions
+3 -1
View File
@@ -45,7 +45,8 @@ subdirectories:
- **File seam (audio, permanent).** The sample **audio** is the on-disk 32-bit-float
WAVs — project-relative, travelling with the `.rpp`. The instrument resolves those
paths the same way `persist` does (a shared convention, not a re-implementation).
paths the same way `persist` does (a shared convention, not a re-implementation),
against the project the instance lives in (`map/sample_roots`).
There is no live PCM stream across the bridge, by design.
- **Live-state seam (the mapping, via the bridge).** For everything that is not raw
audio — the bank index, the mapping, which project is active — the instrument reads
@@ -367,6 +368,7 @@ anything for a trigger shape.
- `params_payload` — the PARAMS-PAYLOAD half of that codec, split from the envelope half on the axis the format already has: the payload carries its own version and grows independently, so the two version ladders are two responsibilities. An INTERNAL seam — the public entry points stay `serialize`/`deserializeComponentState`. The prose ladder and every version constant stay in `component_state_io.h`, their one home.
- `bank_sync` — generation change-detection + assignment-request consume: owns the yes/no decision logic so the rules are provable without a host. The processor shell owns cadence and side effects.
- `bridge_marshal` — pure marshalling helper for the REAPER VST-host bridge read: interprets the `GetProjExtState` int return against its filled buffer.
- `sample_roots` — where a bank-relative sample path resolves: `ownProjectDir` picks the instance's own project out of the shell's enumeration BY IDENTITY (no fallback to any other project), `sampleRootCandidates` orders the roots to try, and `readFromFirstRoot` reads the first that yields bytes. The shell half and its rationale are `shell/instrument`'s.
- `trigger_seam` — the shared Trigger play-SPAN formula: how a %-length becomes the source-frame span the overlay draws over and the bake's window holds, threading `startFrame` correctly and clamping the fraction the same way `Voice::start` does (the engine evaluates the same formula inline rather than depending on `map/`). The spline fold every consumer must apply first — `effectiveLengthFraction` — is `play_params.h`'s, beside the rest of that rule family. (Its fade frames↔fraction converters retired with the fade pair itself.)
### `ui/`