Ξ-W2-T1 remediation: print master gain into the bake, derive the window from the dialed sound, reset play mode to Trigger

This commit is contained in:
2026-08-01 17:05:28 -04:00
parent 60308a3655
commit 39c2d1cdb4
31 changed files with 679 additions and 201 deletions
+16 -3
View File
@@ -235,10 +235,15 @@ void ReaSamplerProcessor::adoptBakedCapture(const SampleRefEntry& entry,
}
setSelectedSampleId(entry.sampleId);
setInstrumentParams(reset);
setMasterGainLinear(masterGainLinear);
{
// ARMED, not stored: publishBuiltLocked applies it inside the same locked section as
// the pointer swap. Storing it here instead would put the reset gain under the OLD
// capture for the whole bridge-read-plus-WAV-decode the reload below runs first.
std::lock_guard<std::mutex> lock(reloadMutex_);
gainAtNextPublish_ = masterGainLinear;
}
// ONE reload for the re-point and the reset together: it decodes the new file and
// publishes the neutral parameters in the same swap, so no block is ever rendered with
// one of the two applied and not the other.
// publishes the neutral parameters in the same swap.
reloadInstrument();
}
@@ -292,6 +297,14 @@ void ReaSamplerProcessor::publishBuiltLocked(std::unique_ptr<LoadedInstrument> b
}),
graveyard_.end());
LoadedInstrument* prev = live_.exchange(built.release());
// A bake's reset gain lands here rather than at its call site, so the gain and the
// capture it belongs to become audible to process() in the same instant. A tail still
// ringing out of the drain does take the new gain — one gain sits above every snapshot,
// the same shape as ONE BLOCK, ONE RATE (see builtSampleRate_).
if (gainAtNextPublish_) {
setMasterGainLinear(*gainAtNextPublish_);
gainAtNextPublish_.reset();
}
LoadedInstrument* evicted = draining_.exchange(prev);
if (evicted) graveyard_.push_back(std::unique_ptr<LoadedInstrument>(evicted));
}