One taper, one modifier law: extract param_taper, raise the stage ceiling to 10 s, and make the AHDSR schematic axis the taper itself
This commit is contained in:
@@ -245,22 +245,35 @@ static void testKnobNeedlePointOnCircle() {
|
||||
|
||||
static void testKnobDragUpIncreases() {
|
||||
// Up (negative dy) increases, down decreases, scaled by the drag range.
|
||||
CHECK(approx(knobDragValue(0.5, -32, 128), 0.75));
|
||||
CHECK(approx(knobDragValue(0.5, +32, 128), 0.25));
|
||||
CHECK(approx(knobDragValue(0.5, -32, {}, 128), 0.75));
|
||||
CHECK(approx(knobDragValue(0.5, +32, {}, 128), 0.25));
|
||||
// A full-range upward drag from 0 lands exactly at 1.
|
||||
CHECK(approx(knobDragValue(0.0, -128, 128), 1.0));
|
||||
CHECK(approx(knobDragValue(0.0, -128, {}, 128), 1.0));
|
||||
// Default sensitivity applies when the range is omitted.
|
||||
CHECK(approx(knobDragValue(0.0, -kKnobDragRangePixels), 1.0));
|
||||
}
|
||||
|
||||
static void testKnobDragClamps() {
|
||||
CHECK(approx(knobDragValue(0.9, -64, 128), 1.0)); // over-drag up clamps at 1
|
||||
CHECK(approx(knobDragValue(0.1, +64, 128), 0.0)); // over-drag down clamps at 0
|
||||
CHECK(approx(knobDragValue(0.9, -64, {}, 128), 1.0)); // over-drag up clamps at 1
|
||||
CHECK(approx(knobDragValue(0.1, +64, {}, 128), 0.0)); // over-drag down clamps at 0
|
||||
// The start value itself is clamped before the delta applies.
|
||||
CHECK(approx(knobDragValue(1.5, 0, 128), 1.0));
|
||||
CHECK(approx(knobDragValue(-0.5, 0, 128), 0.0));
|
||||
CHECK(approx(knobDragValue(1.5, 0, {}, 128), 1.0));
|
||||
CHECK(approx(knobDragValue(-0.5, 0, {}, 128), 0.0));
|
||||
// A degenerate drag range yields the clamped start value.
|
||||
CHECK(approx(knobDragValue(0.7, -50, 0), 0.7));
|
||||
CHECK(approx(knobDragValue(0.7, -50, {}, 0), 0.7));
|
||||
}
|
||||
|
||||
// Ctrl scales the drag rate; Shift+Ctrl is Shift, so the rate goes back to coarse. The snap
|
||||
// itself is not this module's — only the rate is.
|
||||
static void testCtrlScalesTheDragRateAndShiftOverridesIt() {
|
||||
const DragModifiers fine{false, true};
|
||||
const DragModifiers both{true, true};
|
||||
CHECK(approx(knobDragValue(0.5, -32, fine, 128), 0.5 + 0.25 * kFineDragScale));
|
||||
CHECK(approx(knobDragValue(0.5, -32, both, 128), 0.75));
|
||||
CHECK(approx(knobDragValue(0.5, -32, DragModifiers{true, false}, 128), 0.75));
|
||||
// Continuity across a transition is the CALLER's re-anchor, not this function's: at a
|
||||
// zero delta both rates agree, which is exactly the state a re-anchor establishes.
|
||||
CHECK(knobDragValue(0.42, 0, fine, 128) == knobDragValue(0.42, 0, {}, 128));
|
||||
}
|
||||
|
||||
// --- controlAtPoint routing ---------------------------------------------------
|
||||
@@ -321,6 +334,7 @@ int main() {
|
||||
testKnobNeedlePointOnCircle();
|
||||
testKnobDragUpIncreases();
|
||||
testKnobDragClamps();
|
||||
testCtrlScalesTheDragRateAndShiftOverridesIt();
|
||||
testControlAtPointRoutes();
|
||||
testControlAtPointMisses();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user