Retire the zone system: one capture = one parameter set, and re-seam the engine and Sample face into bands

This commit is contained in:
2026-07-30 07:15:54 -04:00
parent a689fb75eb
commit 8d4ccbf841
61 changed files with 5416 additions and 8008 deletions
+18 -23
View File
@@ -1,6 +1,6 @@
// processor_state.cpp — ReaSamplerProcessor's component-state I/O (setState/getState
// against the component_state_io codec) and its UI-thread parameter accessors/setters
// (selection, performance map, channel mode, preview velocity, voice-system params,
// (selection, the one parameter set, channel mode, preview velocity, voice-system params,
// master gain, preview-note mailbox posts). Everything here runs off the audio thread;
// setters hand work to the reload family (processor_reload.cpp) or store atomics
// process() picks up at block start.
@@ -15,7 +15,7 @@
#include "core/instrument/engine/master_gain.h" // masterGainMaxLinear (post-mixer gain clamp)
#include "core/instrument/map/component_state_io.h" // the ComponentState codec
#include "core/instrument/map/sample_map.h" // reconcileSingleCaptureZones / retainRefs / referencedSampleIds
#include "core/instrument/map/sample_map.h" // retainRefs / referencedSampleIds
using namespace Steinberg;
using namespace Steinberg::Vst;
@@ -34,18 +34,14 @@ tresult PLUGIN_API ReaSamplerProcessor::setState(IBStream* state) {
while (state->read(chunk, sizeof(chunk), &got) == kResultOk && got > 0) {
bytes.insert(bytes.end(), chunk, chunk + got);
}
// Component state is {single-capture selection id, opt-in zones}, restored explicitly
// since they're distinct (default face vs. a demoted overlay). deserializeComponentState
// lifts older blobs cleanly (no first-sample fallback in reloadInstrument). sampleRate_
// is the real host rate here — REAPER calls setupProcessing before setState on load.
// Component state is {loaded capture id, one parameter set}. deserializeComponentState
// lifts older blobs cleanly — including the retired zone payloads, which adopt zone
// one's capture into cs.selectionId. sampleRate_ is the real host rate here (REAPER
// calls setupProcessing before setState on load), which the legacy v3 payload's
// frames->seconds conversion needs.
const ComponentState cs = deserializeComponentState(bytes, sampleRate_);
setSelectedSampleId(cs.selectionId);
// Heal-on-load: a blob saved under the pre-fix editor may carry stale full-range zones
// (one per sample ever browsed), the oldest shadowing the saved selection under
// first-match resolve. Authored Zone-view maps (narrow key ranges) pass through untouched.
PerformanceMap restored = cs.map;
reconcileSingleCaptureZones(restored, cs.selectionId); // bool return ignored: reload below runs unconditionally
setPerformanceMap(restored);
setInstrumentParams(cs.params);
// Restore the last-consumed assignment generation so a re-open does not re-apply a
// stale assign_request.
{
@@ -95,11 +91,11 @@ tresult PLUGIN_API ReaSamplerProcessor::setState(IBStream* state) {
tresult PLUGIN_API ReaSamplerProcessor::getState(IBStream* state) {
if (!state) return kResultFalse;
// Persists the full instance state — never written to the "reasampler" bank ext-state.
// No pick + no zones serializes to {"", no zones}, restoring as silence (never
// auto-playing sample #1).
// No pick serializes to {"", default params}, restoring as silence (never auto-playing
// sample #1).
ComponentState state_out;
state_out.selectionId = selectedSampleId();
state_out.map = performanceMap();
state_out.params = instrumentParams();
{
std::lock_guard<std::mutex> lock(channelModeMutex_);
state_out.channelMode = channelMode_;
@@ -121,8 +117,7 @@ tresult PLUGIN_API ReaSamplerProcessor::getState(IBStream* state) {
// present. Filtered (snapshot copy only) to what the instance currently plays, so the
// table cannot grow with browsing history.
state_out.sampleRefs = sampleRefs();
retainRefs(state_out.sampleRefs,
referencedSampleIds(state_out.selectionId, state_out.map));
retainRefs(state_out.sampleRefs, referencedSampleIds(state_out.selectionId));
// Persist the publish identity so the usage key is stable across sessions.
{
std::lock_guard<std::mutex> lock(usageMutex_);
@@ -147,14 +142,14 @@ void ReaSamplerProcessor::setSelectedSampleId(const std::string& id) {
selectedSampleId_ = id;
}
PerformanceMap ReaSamplerProcessor::performanceMap() {
std::lock_guard<std::mutex> lock(performanceMutex_);
return performanceMap_;
InstrumentParams ReaSamplerProcessor::instrumentParams() {
std::lock_guard<std::mutex> lock(paramsMutex_);
return params_;
}
void ReaSamplerProcessor::setPerformanceMap(const PerformanceMap& map) {
std::lock_guard<std::mutex> lock(performanceMutex_);
performanceMap_ = map;
void ReaSamplerProcessor::setInstrumentParams(const InstrumentParams& params) {
std::lock_guard<std::mutex> lock(paramsMutex_);
params_ = params;
}
SampleRefs ReaSamplerProcessor::sampleRefs() {