instrument: fix AHD node-tracking/tie-break/live-latch defects and close staged-envelope-curve test gaps
This commit is contained in:
@@ -90,8 +90,7 @@ EnvVertex gateVtx(EnvNode node, const Rect& area, double px, double level, bool
|
||||
}
|
||||
|
||||
// The knot for a segment running from `startLevel` to `endLevel`, placed at the segment's
|
||||
// pixel midpoint. Its level is the curve's own value at the segment midpoint, which is what
|
||||
// makes the knot's height and the inner dial two readings of one exponent.
|
||||
// pixel midpoint, its level read through curve_law.h's own law (the knot/dial pairing's home).
|
||||
EnvVertex knotVtx(EnvNode node, const Rect& area, int x0, int x1, double startLevel,
|
||||
double endLevel, double exponent) {
|
||||
const double u = curveMidLevel(exponent);
|
||||
@@ -178,8 +177,19 @@ 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));
|
||||
pts.push_back(vtx(EnvNode::HoldEnd, area, totalSeconds, t0 + s.attack + s.hold, 1.0));
|
||||
pts.push_back(vtx(EnvNode::DecayEnd, area, totalSeconds, t0 + s.total, 0.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);
|
||||
if (s.attack > 0.0) {
|
||||
pts.push_back(knotVtx(EnvNode::AttackCurve, area, pts[0].x, pts[1].x, 0.0, 1.0,
|
||||
env.attackCurve));
|
||||
|
||||
Reference in New Issue
Block a user