Report the instrument's automatable parameters to the host under a frozen id table, in signal-flow order, with real units
42 of 44 ids issued: pitch key-track and Trigger length stay reserved pending a live path. Master gain reclassified Live — it never reloaded.
This commit is contained in:
@@ -41,6 +41,10 @@ tresult PLUGIN_API ReaSamplerProcessor::setState(IBStream* state) {
|
||||
// calls setupProcessing before setState on load), which the legacy v3 payload's
|
||||
// frames->seconds conversion needs.
|
||||
const ComponentState cs = deserializeComponentState(bytes, sampleRate_);
|
||||
// A LOAD is not an edit: the SDK is explicit that a controller must never pass a restored
|
||||
// value back to the host through IComponentHandler. The push into the controller happens
|
||||
// once at the tail instead, through syncParamsFromModel.
|
||||
paramNotifySuppressed_ = true;
|
||||
setSelectedSampleId(cs.selectionId);
|
||||
setInstrumentParams(cs.params);
|
||||
// Restore the last-consumed assignment generation so a re-open does not re-apply a
|
||||
@@ -86,6 +90,12 @@ tresult PLUGIN_API ReaSamplerProcessor::setState(IBStream* state) {
|
||||
// A new blob is new facts — the legacy lift gets one fresh run per restored state.
|
||||
legacyLiftConcluded_.store(false, std::memory_order_relaxed);
|
||||
reloadInstrument();
|
||||
paramNotifySuppressed_ = false;
|
||||
// Every exposed parameter now reads the blob's value. Ordering against the host's first
|
||||
// parameter block is irrelevant BY CONSTRUCTION rather than by assumption: there is one
|
||||
// model and one funnel per control, so whichever of the two writes last simply wins, and
|
||||
// the host's display follows the model either way.
|
||||
syncParamsFromModel();
|
||||
// This caller has no editor to flush for it. At the TAIL on purpose: a host that services the
|
||||
// restart synchronously deactivates/reactivates, and our setActive(true) resumes or reloads
|
||||
// against the refs above, which are only fully restored once this function has run to here.
|
||||
@@ -153,8 +163,10 @@ InstrumentParams ReaSamplerProcessor::instrumentParams() {
|
||||
}
|
||||
|
||||
void ReaSamplerProcessor::setInstrumentParams(const InstrumentParams& params) {
|
||||
InstrumentParams before;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(paramsMutex_);
|
||||
before = params_;
|
||||
params_ = params;
|
||||
}
|
||||
// Every writer of the parameter set — setState, the editor's commits, the bake's adopt —
|
||||
@@ -173,6 +185,10 @@ void ReaSamplerProcessor::setInstrumentParams(const InstrumentParams& params) {
|
||||
latencyRestartPending_.store(
|
||||
params.limiterEnabled != latencyAnnounced_.load(std::memory_order_relaxed),
|
||||
std::memory_order_release);
|
||||
// The host-notification obligation, at the same one funnel and for the same reason the
|
||||
// limiter mirror sits here: an internal write that skipped it would leave the host
|
||||
// displaying — and, on the next touch, re-imposing — the superseded value.
|
||||
notifyParamsFromModel(before, params);
|
||||
}
|
||||
|
||||
void ReaSamplerProcessor::flushLatencyRestart() {
|
||||
@@ -319,7 +335,14 @@ void ReaSamplerProcessor::setMasterGainLinear(double linear) {
|
||||
if (!(linear >= 0.0)) linear = 0.0; // also catches NaN
|
||||
const double maxLin = masterGainMaxLinear();
|
||||
if (linear > maxLin) linear = maxLin;
|
||||
masterGain_.store(static_cast<float>(linear), std::memory_order_relaxed);
|
||||
const float value = static_cast<float>(linear);
|
||||
const float previous = masterGain_.exchange(value, std::memory_order_relaxed);
|
||||
// Gain's own notification funnel — it is the one exposed control that does not ride the
|
||||
// parameter set, so setInstrumentParams' diff cannot see it. Compared for a real change so a
|
||||
// reload's republish of an unmoved gain writes nothing into a host's automation lane.
|
||||
if (paramNotifySuppressed_ || previous == value) return;
|
||||
notifyParamChanged(instrument::param::kParamMasterGain,
|
||||
instrument::engine::masterGainNormFromLinear(linear));
|
||||
}
|
||||
|
||||
void ReaSamplerProcessor::previewNoteOn(int note) {
|
||||
|
||||
Reference in New Issue
Block a user