fix(trigger-seam): thread startFrame into both envelope converters; extract pure triggerPlayLength module + tests

This commit is contained in:
2026-07-27 14:37:05 -04:00
parent c12a374b88
commit 8a7dc4b1c6
7 changed files with 296 additions and 40 deletions
+7 -2
View File
@@ -281,12 +281,16 @@ private:
// PACK (draw): zone play params -> AmpEnvelope. Copies AHDSR seconds directly; derives the
// Trigger fade fractions from the source-frame fades over the played span.
AmpEnvelope packEnvelope(const ZonePlaySeconds& play, std::int64_t frames) const;
// `startFrame` is the zone's effective start point (zone.startPoint.value_or(0)).
AmpEnvelope packEnvelope(const ZonePlaySeconds& play, std::int64_t frames,
std::int64_t startFrame) const;
// UNPACK (commit): an edited AmpEnvelope -> the zone's play params. Copies AHDSR seconds
// directly; converts the Trigger fade fractions back to source frames over the played span.
// `startFrame` is the zone's effective start point (zone.startPoint.value_or(0)).
// Mutates `play` in place; only the mode-relevant fields are written.
void unpackEnvelope(const AmpEnvelope& env, std::int64_t frames, ZonePlaySeconds& play) const;
void unpackEnvelope(const AmpEnvelope& env, std::int64_t frames, std::int64_t startFrame,
ZonePlaySeconds& play) const;
// The clamp bounds envelope_edit uses, matching the control-panel sliders' own domains (so a
// node drag can never produce a param a slider couldn't — the S-VIEW-F2 invariant).
@@ -385,6 +389,7 @@ private:
WaveMarker waveMarker_ = WaveMarker::kStart;
SetupMarkers dragStartMarkers_;
std::int64_t dragSampleFrames_ = 0; // decoded length of the sample under the drag
std::int64_t dragStartFrame_ = 0; // zone startPoint at grab time (0 if absent); for env-node drag
// S12 scrollbar-thumb drag: the offset held at grab time (the pixel-delta resolver shifts
// from it). S12/S15/S16 param-slider drag: which control id + the panel it lives in (the