Close derived-bake-window review findings: NaN-guard remaining wire doubles, pin Trigger-span agreement, retire dead quantizer
Guards params_payload.cpp's filter-tail seconds and both keyTrack sites against NaN; pins Voice::start's Trigger-span formula against trigger_seam; retires unused shortestDivisionAtLeast.
This commit is contained in:
@@ -3,15 +3,13 @@
|
||||
//
|
||||
// Covers: the beat length of all 39 divisions against a literal rung table (NOT the module's
|
||||
// own exponent formula); the 1/64 and 64/1 extremes; the four named example divisions; the
|
||||
// label notation; picker order and index round-trip; off-ladder clamping of BOTH persisted
|
||||
// fields, measured through the readers rather than by comparing two clamped values; and
|
||||
// shortestDivisionAtLeast's never-short contract across the rung boundaries.
|
||||
// label notation; picker order and index round-trip; and off-ladder clamping of BOTH persisted
|
||||
// fields, measured through the readers rather than by comparing two clamped values.
|
||||
|
||||
#include "../src/core/instrument/note/musical_division.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
||||
using namespace reasampler::instrument::note;
|
||||
|
||||
@@ -206,54 +204,7 @@ static void testOutOfRangeIndexClampsIntoTheSet() {
|
||||
CHECK(divisionAt(kDivisionCount) == divisionAt(kDivisionCount - 1));
|
||||
}
|
||||
|
||||
// --- shortestDivisionAtLeast --------------------------------------------------
|
||||
|
||||
// The contract is never-short: whatever comes back is at least the requested length, and
|
||||
// nothing shorter on the ladder also is. Swept over every rung and over the gaps between them.
|
||||
static void testShortestAtLeastIsNeverShortAndNeverLonger() {
|
||||
for (int i = 0; i < kDivisionCount; ++i) {
|
||||
const double target = divisionBeats(divisionAt(i));
|
||||
for (const double want : {target, target * 0.99, target * 0.5}) {
|
||||
const Division got = shortestDivisionAtLeast(want);
|
||||
CHECK(divisionBeats(got) >= want - 1e-12);
|
||||
// Nothing on the ladder is both long enough and shorter than the answer.
|
||||
for (int j = 0; j < kDivisionCount; ++j) {
|
||||
const double other = divisionBeats(divisionAt(j));
|
||||
CHECK(!(other >= want && other < divisionBeats(got) - 1e-12));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Picker order is NOT length order — a rung's triplet is shorter than the previous rung's
|
||||
// dotted — so the answer is not simply "the next index up".
|
||||
static void testShortestAtLeastCrossesRungBoundaries() {
|
||||
// 5 beats: the 2/1 triplet (8 * 2/3 == 5.33) beats the dotted half (6) above it.
|
||||
CHECK(shortestDivisionAtLeast(5.0) == makeDivision(3, DivisionModifier::Triplet));
|
||||
// An exact rung length answers with that rung, not the one above it.
|
||||
CHECK(shortestDivisionAtLeast(4.0) == makeDivision(2, DivisionModifier::Straight));
|
||||
}
|
||||
|
||||
// Degenerate inputs land on an end rather than anywhere in the middle.
|
||||
static void testShortestAtLeastDegenerateInputs() {
|
||||
CHECK(shortestDivisionAtLeast(0.0) == divisionAt(0));
|
||||
CHECK(shortestDivisionAtLeast(-10.0) == divisionAt(0));
|
||||
// Past the longest programmable note (the dotted top rung), the top rung is the answer.
|
||||
const Division longest = makeDivision(kMaxQuarterExponent, DivisionModifier::Dotted);
|
||||
CHECK(almostEqual(divisionBeats(longest), kMaxDivisionBeats));
|
||||
CHECK(shortestDivisionAtLeast(kMaxDivisionBeats * 2.0) == longest);
|
||||
// A non-finite request names no length to be at least, so it takes the SAME never-short
|
||||
// answer as one nothing covers. Landing on the bottom rung instead would turn a corrupt
|
||||
// value into a near-instant note.
|
||||
CHECK(shortestDivisionAtLeast(std::nan("")) == longest);
|
||||
CHECK(shortestDivisionAtLeast(std::numeric_limits<double>::infinity()) == longest);
|
||||
}
|
||||
|
||||
int main() {
|
||||
testShortestAtLeastIsNeverShortAndNeverLonger();
|
||||
testShortestAtLeastCrossesRungBoundaries();
|
||||
testShortestAtLeastDegenerateInputs();
|
||||
|
||||
testLadderSpansSixtyfourthToSixtyFourWhole();
|
||||
testEveryStraightRungHasItsWrittenBeatLength();
|
||||
testDottedIsHalfAgainAndTripletIsTwoThirds();
|
||||
|
||||
Reference in New Issue
Block a user