instrument: fix AHD DecayEnd overlay/grab defect, pin flaky curve test, close comment/doc findings

This commit is contained in:
2026-07-31 10:19:45 -04:00
parent 2fa1405b06
commit 03fb471c92
10 changed files with 117 additions and 28 deletions
+8 -13
View File
@@ -177,19 +177,14 @@ std::vector<EnvVertex> ahdPolyline(const StageEnvelope& env, const Rect& area,
pts.reserve(6);
pts.push_back(vtx(EnvNode::Origin, area, totalSeconds, t0, 0.0));
pts.push_back(vtx(EnvNode::AttackEnd, area, totalSeconds, t0 + s.attack, 1.0));
EnvVertex holdVtx = vtx(EnvNode::HoldEnd, area, totalSeconds, t0 + s.attack + s.hold, 1.0);
EnvVertex decayVtx = vtx(EnvNode::DecayEnd, area, totalSeconds, t0 + s.total, 0.0);
// A hold that consumes the WHOLE post-attack/decay remainder (holdFraction == 1.0, the
// Trigger AHD default) puts HoldEnd and DecayEnd on the same wall-clock instant, and
// nodeAtPoint's earlier-draw-order tie-break then hides DecayEnd behind HoldEnd forever.
// Nudge apart, clamped to the canvas — the same minimum-separation rationale
// kGateNodeSepPx exists for on the AHDSR schematic, applied to this coincidence instead.
if (decayVtx.x - holdVtx.x < kGateNodeSepPx) {
const int right = area.x + std::max(1, area.width) - 1;
decayVtx.x = std::min(holdVtx.x + kGateNodeSepPx, right);
}
pts.push_back(holdVtx);
pts.push_back(decayVtx);
pts.push_back(vtx(EnvNode::HoldEnd, area, totalSeconds, t0 + s.attack + s.hold, 1.0));
// DecayEnd is drawn at t0 + total, which coincides with HoldEnd exactly when decay ~ 0 —
// independent of holdFraction (total = attack + hold + decay always). Left at its true
// instant rather than nudged: the 1:1 axis this policy exists to keep honest must hold even
// at a shared instant, including the Trigger default's abrupt (zero-decay) cutoff.
// envelope_edit's nodeAtPoint handles the coincidence instead, by dropping DecayEnd from the
// grabbable set when it also cannot move (holdFraction == 1.0).
pts.push_back(vtx(EnvNode::DecayEnd, area, totalSeconds, t0 + s.total, 0.0));
if (s.attack > 0.0) {
pts.push_back(knotVtx(EnvNode::AttackCurve, area, pts[0].x, pts[1].x, 0.0, 1.0,
env.attackCurve));