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
+19 -6
View File
@@ -1,19 +1,32 @@
// trigger_seam — the shared Trigger play-span formula: how the stored %-length becomes the
// source-frame span the voice plays and the overlay draws over. One home so the engine's
// note-on resolve and the editor's overlay pack cannot disagree about where a Trigger note
// ends.
// source-frame span the voice plays, the overlay draws over, and the bake's window holds.
// One home so those three cannot disagree about where a Trigger note ends.
//
// playLengthFrames = round(lengthFraction * (frameCount - startFrame))
// playLengthFrames = round(effectiveLengthFraction * (frameCount - startFrame))
#pragma once
#include <cstdint>
#include "core/instrument/engine/play_params.h" // splineActive (the %-knob's inert rule)
namespace reasampler::instrument::map {
// The %-length the voice ACTUALLY plays. A drawn contour is a pure time function over the
// full sample length, so any active spline EG folds the fraction to 1.0 and the stored knob
// goes inert (splineActive, play_params.h) — but the stored value survives, so a pre-spline
// setting is still there to be read. Every consumer of the span must fold it here or it
// silently plays/draws/bakes a fraction of the take.
//
// Templated over the two parameter representations for the same reason splineActive is.
template <class Play>
double effectiveLengthFraction(const Play& p) {
return splineActive(p) ? 1.0 : p.trigger.lengthFraction;
}
// postStart = max(0, frameCount - startFrame); playLength = round(lengthFraction * postStart).
// `startFrame` is the effective start point (0 when absent). Returns 0 when postStart == 0
// or lengthFraction <= 0.
// `startFrame` is the effective start point (0 when absent), `lengthFraction` the EFFECTIVE
// one above. Returns 0 when postStart == 0 or lengthFraction <= 0.
std::int64_t triggerPlayLength(double lengthFraction,
std::int64_t frameCount,
std::int64_t startFrame);