S5 Tier-1: zoned keymap editor + performance-map playback/persistence

Zone editor in the IPlugView LICE surface, zoned resolution built off-thread into the
LoadedInstrument keymap with Tier-0 fallback, performance map in VST3 component state
with v1 back-compat. Pure resolve/build/serialize + geometry with CTest coverage.
This commit is contained in:
2026-07-26 17:28:15 -04:00
parent 6ae843345c
commit 2356958930
10 changed files with 1063 additions and 63 deletions
+18 -3
View File
@@ -28,6 +28,7 @@
#include "public.sdk/source/vst/vstsinglecomponenteffect.h"
#include "reaper_bridge.h"
#include "sample_map.h" // PerformanceMap (the instrument's owned zoned keymap)
#include "sampler_core.h"
namespace reasampler::vst {
@@ -97,10 +98,18 @@ public:
// editor borrows it (outlives the editor).
ReaperBridge& bridge() { return bridge_; }
// The current selection id (main/UI thread reads for the editor). Guarded by
// selectionMutex_ — never touched on the audio thread.
// selectionMutex_ — never touched on the audio thread. In Tier 1 the selection is the
// Tier-0 FALLBACK sample (played chromatically when the performance map is empty); the
// zoned map, when non-empty, supersedes it.
std::string selectedSampleId();
void setSelectedSampleId(const std::string& id);
// The performance map (Tier 1: the zoned keymap the instrument owns; D-B). Read/written
// by the editor on the UI thread; snapshotted under performanceMutex_. NEVER read on the
// audio thread — reloadFromBank bakes it into the LoadedInstrument's Keymap off-thread.
PerformanceMap performanceMap();
void setPerformanceMap(const PerformanceMap& map);
private:
ReaperBridge bridge_;
@@ -139,11 +148,17 @@ private:
std::vector<GraveyardEntry> graveyard_; // drained on reclaim + setActive(false) + terminate
std::mutex reloadMutex_; // serializes off-thread reloads + graveyard access
// The selected sample id (instance state). Off-thread only; a small mutex guards the
// string against a getState/editor race. NOT read on the audio thread.
// The selected sample id (Tier-0 fallback sample). Off-thread only; a small mutex
// guards the string against a getState/editor race. NOT read on the audio thread.
std::mutex selectionMutex_;
std::string selectedSampleId_;
// The performance map (Tier 1: the instrument's owned zoned keymap). Off-thread only;
// guarded against a getState/editor race. NOT read on the audio thread — reloadFromBank
// bakes it into the LoadedInstrument's Keymap under the reload lock.
std::mutex performanceMutex_;
PerformanceMap performanceMap_;
// Latched from setupProcessing so setActive/reload can size against it. Read
// off-thread only.
double sampleRate_ = 44100.0;