Bake window: derive it from the rate the voice actually reads at, so a dialled Rate or downward Pitch no longer truncates the file
This commit is contained in:
@@ -295,6 +295,39 @@ static void testRateDefaultAndEndpointsRoundTripBitwise() {
|
||||
}
|
||||
}
|
||||
|
||||
// The exact-unity detent is DERIVED from the bounds, not assumed to sit at centre. The shipped
|
||||
// bounds are reciprocal so the two agree today, but they are a MEASURED range: re-measure them
|
||||
// asymmetric and a detent pinned to 0.5 makes the map fold back on itself around centre. Run at
|
||||
// a deliberately non-reciprocal pair, which is exactly the case the ratio-of-ratios and
|
||||
// round-trip tests above would still have passed.
|
||||
static void testRateDetentFollowsAsymmetricBoundsInsteadOfCentre() {
|
||||
constexpr double kLo = 0.4;
|
||||
constexpr double kHi = 3.0; // kLo * kHi == 1.2, so unity is NOT at 0.5
|
||||
const double unity = rateNormFromRatio(1.0, kLo, kHi);
|
||||
CHECK(unity > 0.0 && unity < 1.0);
|
||||
CHECK(std::fabs(unity - 0.5) > 0.01); // the case a 0.5 detent gets wrong
|
||||
CHECK(rateRatioFromNorm(unity, kLo, kHi) == 1.0); // ...and unity is still EXACT there
|
||||
|
||||
double prev = -1.0;
|
||||
for (int i = 0; i <= 200000; ++i) {
|
||||
const double v = rateRatioFromNorm(static_cast<double>(i) / 200000.0, kLo, kHi);
|
||||
CHECK(v >= prev);
|
||||
if (v < prev) { std::printf(" asymmetric fold at i=%d\n", i); return; }
|
||||
prev = v;
|
||||
}
|
||||
// That sweep steps OVER the detent rather than onto it, so walk its immediate neighbourhood
|
||||
// too — a misplaced exact case shows up there and nowhere else.
|
||||
for (int k = -8; k < 8; ++k) {
|
||||
const double a = rateRatioFromNorm(unity + static_cast<double>(k) * 1e-9, kLo, kHi);
|
||||
const double b = rateRatioFromNorm(unity + static_cast<double>(k + 1) * 1e-9, kLo, kHi);
|
||||
CHECK(b >= a);
|
||||
if (!(b >= a)) { std::printf(" detent fold at k=%d\n", k); return; }
|
||||
}
|
||||
// And the shipped reciprocal bounds still put unity at true knob centre: the general rule
|
||||
// reproduces the special case rather than replacing it.
|
||||
CHECK(rateNormFromRatio(1.0, kRateMin, kRateMax) == 0.5);
|
||||
}
|
||||
|
||||
// Degenerate bounds are a caller bug, not a crash: the map collapses to unity.
|
||||
static void testDegenerateRateBoundsCollapseToUnity() {
|
||||
CHECK(rateRatioFromNorm(0.3, 2.0, 0.5) == 1.0);
|
||||
@@ -394,6 +427,7 @@ int main() {
|
||||
testRateIsLinearInSemitonesAcrossTheWholeTravel();
|
||||
testRateIsMonotone();
|
||||
testRateDefaultAndEndpointsRoundTripBitwise();
|
||||
testRateDetentFollowsAsymmetricBoundsInsteadOfCentre();
|
||||
testDegenerateRateBoundsCollapseToUnity();
|
||||
|
||||
testMillisecondSnap();
|
||||
|
||||
Reference in New Issue
Block a user