loop: crossfade the Gate sustain seam, and unshadow the loop handles that made loop points look gone

This commit is contained in:
2026-07-31 17:36:36 -04:00
parent a90ccd9a00
commit 0fe4166d7d
25 changed files with 991 additions and 64 deletions
+7
View File
@@ -227,6 +227,12 @@ struct InstrumentParams {
std::optional<SampleLoop> loopOverride; // instrument-owned sustain loop; absent -> intrinsic
std::optional<std::int64_t> startPoint; // instrument-owned initial read frame; absent -> 0
// Pre-seam crossfade at the loop reset, in SOURCE frames — a source-timeline quantity
// like the loop points, so it needs no rate to resolve and cannot be rescaled by a
// project/file rate mismatch. 0 is the hard seam a blob predating the field lifts to.
// Never a bank fact: the fade is a performance choice, the loop points are the file's.
std::int64_t loopCrossfadeFrames = 0;
// Key-tracking scalar: how far playback pitch tracks the keyboard around the root. 1.0
// (100%, standard 12-tone-ET) is the default — a blob predating this field lifts to
// exactly 1.0, so already-saved instances are bit-identical. 0.0 = no tracking (every
@@ -259,6 +265,7 @@ struct ResolvedCapture {
double keyTrack = 1.0;
VelocityCurve velocityCurve = VelocityCurve::flat();
SampleLoop loop; // effective: loopOverride, else bank intrinsic
std::int64_t loopCrossfadeFrames = 0; // instrument-owned; no bank intrinsic to beat
std::int64_t startFrame = 0; // effective initial read frame: startPoint, else 0
PlaySeconds play; // stored SECONDS; resolved to frames at build
};