Bake window derives itself: %-knob fold, declick pad, Gate held to exhaustion, preview velocity; Hold is the one knob a loop needs

This commit is contained in:
2026-08-01 20:26:04 -04:00
parent d3894dae6d
commit 19aeb92775
36 changed files with 1040 additions and 274 deletions
+5 -6
View File
@@ -67,16 +67,15 @@ StageEnvelope ReaSamplerEditor::packEnvelope(OverlayEnv which, const PlaySeconds
const double t0 = rate > 0.0 ? static_cast<double>(startFrame) / rate : 0.0;
// The Trigger amp and filter AHDs live over the PLAY span; the pitch AHD over the whole
// post-start span, since it keeps running after a Trigger one-shot's amplitude has ended.
// effectiveLengthFraction, not the stored knob: the overlay's amp/filter AHD must read the
// SAME span the engine plays, or its drawn shape and node drags cover only a fraction of
// what the note actually does.
const std::int64_t playLen =
triggerPlayLength(play.trigger.lengthFraction, frames, startFrame);
triggerPlayLength(effectiveLengthFraction(play), frames, startFrame);
const double fullSpan =
rate > 0.0 ? static_cast<double>((std::max)(std::int64_t{0}, frames - startFrame)) / rate
: 0.0;
// Voice::start makes kTrigLength inert while any spline EG is active (trigSpan == postStart,
// not the %-length) — the overlay's amp/filter AHD must read the SAME span the engine plays,
// or its drawn shape and node drags cover only a fraction of what the note actually does.
const double playSpan =
splineActive(play) ? fullSpan : (rate > 0.0 ? static_cast<double>(playLen) / rate : 0.0);
const double playSpan = rate > 0.0 ? static_cast<double>(playLen) / rate : 0.0;
const bool trigger = (play.playMode == PlayMode::Trigger);
switch (which) {
case OverlayEnv::kPitch: