Fix render-bounds EXACT verdict: enumerate floored models instead of trusting grid membership
Grid-ness of an edge was a proxy for "no floor could explain this count," not the test itself — equal remainders on both edges cancel under a full floor. Now checks all three floored models directly and corrects the SHORT/LONG floor-signature docs.
This commit is contained in:
@@ -27,7 +27,7 @@ Checks for Θ, Ξ, and Ψ work that no unit test can close. Build **Release**, i
|
||||
- [ ] One razor-union case (two disjoint areas, one track) — lands the requested window, no `ReaSampler capture failed:` line (`PLAN.md:2137`)
|
||||
- [ ] Capture an item whose extent already equals the window — still lands, unchanged (the byte-identity regression floor) (`docs/COMPLETED.md:829`)
|
||||
- [ ] **The millisecond floor — what to expect.** A custom-bounds render is known to floor its window's END to the millisecond and write the floored value back over `RENDER_ENDPOS`. Mechanism, why two `RENDER_BOUNDSFLAG` channels exist, and the two live observations behind this: `src/core/capture/render_settings.h`'s `RenderBoundsChannel` and `docs/TODO.md` "An offline capture can be refused...". **Both live observations started at `0s`, on the grid, so nothing is known about the START edge**
|
||||
- [ ] **The one experiment — does another bounds mode escape the floor?** This build renders on the TIME SELECTION channel (`RENDER_BOUNDSFLAG=2`, window handed over via `GetSet_LoopTimeRange`) instead of custom time bounds. Every capture prints one line beginning `ReaSampler capture -- bounds channel:` — including the two paths that answer before any bounds are judged (unsupported format, no output file), which print `NOT JUDGED` rather than staying silent. Read the verdict: a bare **SHORT**/**LONG** (no tag), or one naming "floored to the millisecond", is the floor's signature — it did not escape this channel. **(WITHIN TOLERANCE)** on a SHORT/LONG is the gate's ordinary ±1-frame edge-convention slack (`render_window.h`), not the floor — don't read it as either result. **EXACT on a window whose END is off the millisecond grid** is the fix — the floor did not reach this channel. **EXACT on a window whose END lands on the grid is NOT conclusive**: the line adds "The END edge is UNTESTED here too" — a floored render prints the identical count by coincidence, so re-run with an off-grid end before trusting EXACT. **NOT JUDGED naming a bounds channel** means that capture answered nothing (tail mode was not None, the render was empty, the render never even reached a bounds check) OR the render source itself derives its own bounds and never consulted the channel — selected-items/razor captures always read this way, so pick a window narrower than the selected item(s) to route through the time-bounded source instead
|
||||
- [ ] **The one experiment — does another bounds mode escape the floor?** This build renders on the TIME SELECTION channel (`RENDER_BOUNDSFLAG=2`, window handed over via `GetSet_LoopTimeRange`) instead of custom time bounds. On every return past the point a bounds channel is chosen (the format/mode/empty-range/no-project refusals answer earlier and print nothing), one line beginning `ReaSampler capture -- bounds channel:` prints — including the two paths that answer before any bounds are judged (unsupported format, no output file), which print `NOT JUDGED` rather than staying silent. Read the verdict: **the floor's signature is ONLY a sentence naming "floored to the millisecond"** — a bare SHORT with no such sentence means the shortfall's cause is unestablished, and LONG can never be the floor's signature (a floor only removes frames, never adds them). **(WITHIN TOLERANCE)** on a SHORT/LONG is the gate's ordinary ±1-frame edge-convention slack (`render_window.h`), not the floor — don't read it as either result, and it can mask a floor: a window whose start and end sit in the same millisecond bucket makes the floored count equal the exact one, so a real one-frame floor there reads as a bare SHORT (WITHIN TOLERANCE) with no floor sentence at all. **EXACT is the fix only when the line carries no further caveat.** The verdict checks the observed count against every millisecond-floored model of the window (start floored alone, end floored alone, both together) and names any that reproduce it — grid membership on either edge is a proxy for that collision, not the test itself, so the caveat can fire even when NEITHER edge sits on the millisecond grid (sub-millisecond remainders on the two edges can cancel under a full floor — a dragged, fixed-length time selection is the reproducible case). Re-run with a window the caveat doesn't name before trusting EXACT. **NOT JUDGED naming a bounds channel** means that capture answered nothing (tail mode was not None, the render was empty, the render never even reached a bounds check, or the window rounds to 0 frames at this rate) OR the render source itself is INFERRED (not SDK-confirmed) to derive its own bounds and never consult the channel — selected-items captures always read this way; razor edits never do today, because no offline capture path assigns `SourceMode::RazorArea` (razor is a range source resolved through track/item scope, not a render source of its own) — so pick a window narrower than the selected item(s) to route through the time-bounded source instead
|
||||
- [ ] **Same run, the START edge.** The verdict line also says whether the run tested the start. Capture a range whose start is NOT a whole millisecond (set View → time unit to Samples, then nudge the selection start off the grid) so the line reads `The START edge IS tested here`. Report that line verbatim — it is the only evidence available for whether the start floors too, and a start floor is the case that would break the null test silently rather than loudly
|
||||
- [ ] **Auto and Manual tail.** Repeat the off-grid-start/off-grid-end capture once with the panel tail toggle at **Auto** and once at **Manual**. Neither is judged against a frame count, so the evidence is the `after render` drift lines: report whether either channel's bounds read back changed. `[verify — DAW]` A tail is assumed to render PAST the window end — the SDK header (`:3048`) confirms only that `RENDER_TAILMS` is a length in ms, not that it extends past the end. If that assumption is wrong, an end floor could be costing Auto/Manual real content with no detector (`checkRenderedBounds` returns immediately for `tailMode != None`) — so also report by ear/measurement whether either tail capture comes up short against the source, not only whether the bounds fields drifted
|
||||
- [ ] Whichever way the experiment lands, the refused render is still kept for diagnosis at `<project folder>/reasampler_refused/` (the refusal line names the path; a failed move leaves it unindexed in the bank folder and says so). Delete the folder when done — nothing in the bank references it
|
||||
|
||||
@@ -145,13 +145,16 @@ RenderSettingsChoice renderSettingsFor(SourceMode mode, double wetDry);
|
||||
// naming them apart would assert a render distinction that does not exist.
|
||||
const char* renderSourceLabel(SourceMode mode);
|
||||
|
||||
// True for a render source that derives its bounds from content rather than from
|
||||
// RENDER_BOUNDSFLAG at all: SelectedItems (&32) and RazorArea (&4096) bound
|
||||
// themselves to the selected items'/areas' own extents (see the &32 inference in
|
||||
// src/core/capture/CLAUDE.md §Gotchas; RazorArea is read the same way, sharing the
|
||||
// single-file bit for the same reason). A capture on one of these never consults
|
||||
// RenderBoundsChannel, so describeBoundsExperiment's verdict must not be read as
|
||||
// evidence about the channel for it — the caller names the source instead.
|
||||
// True for a render source INFERRED (not SDK-confirmed) to derive its bounds from
|
||||
// content rather than RENDER_BOUNDSFLAG: SelectedItems (&32), per the observed-defect
|
||||
// inference in src/core/capture/CLAUDE.md §Gotchas, and RazorArea (&4096) by analogy to
|
||||
// it — the SDK header (~3042) actually separates bounds (RENDER_BOUNDSFLAG, its own
|
||||
// value 4 = selected media items) from source (&32), which leans the other way.
|
||||
// RazorArea stays in the set on that inference even though no offline capture path
|
||||
// assigns it today — razor is a RANGE source (capture_batch.cpp's razor units render
|
||||
// through track scope), not a render source of its own. A capture on either never
|
||||
// consults RenderBoundsChannel, so describeBoundsExperiment's verdict must not be read
|
||||
// as evidence about the channel — the caller names the source instead.
|
||||
bool sourceBypassesBoundsChannel(SourceMode mode);
|
||||
|
||||
// --- Capture scope: the FX-scope invariant ------------------------------------
|
||||
|
||||
@@ -76,20 +76,30 @@ std::string describeBoundsExperiment(const char* channelLabel,
|
||||
s += ". ";
|
||||
|
||||
if (bypassingSourceLabel && bypassingSourceLabel[0]) {
|
||||
s += "NOT JUDGED -- rendered from " + std::string(bypassingSourceLabel) +
|
||||
", which derives its bounds from content and never consulted this channel;"
|
||||
" this capture is not evidence either way about it.";
|
||||
s += "NOT JUDGED -- this capture's render source is " +
|
||||
std::string(bypassingSourceLabel) +
|
||||
", INFERRED (not SDK-confirmed) to derive its bounds from content rather"
|
||||
" than consult this channel; this capture is not evidence either way about it.";
|
||||
return s;
|
||||
}
|
||||
|
||||
if (sampleRate <= 0) {
|
||||
s += "NOT JUDGED -- the landed render's frames were never counted against the "
|
||||
s += "NOT JUDGED -- this capture's frames were never counted against the "
|
||||
"window, so this capture is not evidence either way about the channel.";
|
||||
return s;
|
||||
}
|
||||
|
||||
const long long expected = frameCountFor(reqStart, reqEnd, sampleRate);
|
||||
const long long delta = actualFrames - expected;
|
||||
|
||||
// A window under a frame at this rate has nothing to compare: a 0-frame render
|
||||
// against a 0-frame window is a coincidence of degenerate inputs, not a match.
|
||||
if (expected == 0 && actualFrames == 0) {
|
||||
s += "NOT JUDGED -- the requested window rounds to 0 frames at this rate, so a "
|
||||
"0-frame render is not evidence either way about the channel.";
|
||||
return s;
|
||||
}
|
||||
|
||||
// Within the gate's own edge-convention slack (render_window.h): its normal
|
||||
// tolerance, not evidence the millisecond floor was escaped or hit.
|
||||
const bool withinTolerance =
|
||||
@@ -101,13 +111,14 @@ std::string describeBoundsExperiment(const char* channelLabel,
|
||||
" the window asks for at " + std::to_string(sampleRate) + " Hz.";
|
||||
|
||||
// The shape both live short renders matched to the frame. A match says this channel
|
||||
// produced a floored window; it does not locate where inside REAPER the floor is.
|
||||
if (delta != 0) {
|
||||
// produced a floored window; it does not locate where inside REAPER the floor is. A
|
||||
// floor only removes frames, so this can only ever match a SHORT, never a LONG.
|
||||
if (delta < 0) {
|
||||
const long long msFloored =
|
||||
msFlooredEndFrameCount(reqStart, reqEnd, sampleRate);
|
||||
if (msFloored > 0 && actualFrames == msFloored)
|
||||
s += " That is exactly the count this window holds with its end floored to"
|
||||
" the millisecond -- this channel did not escape the floor.";
|
||||
" the millisecond -- the shape REAPER's render was measured producing.";
|
||||
}
|
||||
|
||||
s += isOnMillisecondGrid(reqStart)
|
||||
@@ -117,15 +128,38 @@ std::string describeBoundsExperiment(const char* channelLabel,
|
||||
: " The START edge IS tested here: " + exactly(reqStart) +
|
||||
"s carries a sub-millisecond remainder.";
|
||||
|
||||
// An EXACT verdict on an on-grid END is not proof: a channel that floors the end
|
||||
// would have printed this same count, since floor/ceil/round all leave a grid point
|
||||
// alone. Without this, EXACT reads as settled when this run could not have told the
|
||||
// two apart.
|
||||
if (delta == 0 && isOnMillisecondGrid(reqEnd)) {
|
||||
s += " The END edge is UNTESTED here too: " + exactly(reqEnd) +
|
||||
"s is already on the millisecond grid, so a channel that floors the end"
|
||||
" would have printed this same EXACT count -- re-run over a window whose"
|
||||
" end is off the grid before reading EXACT as the fix.";
|
||||
// EXACT is proof only when no millisecond-floored model of this window could have
|
||||
// produced the same count. Grid membership on an edge is a PROXY for that collision,
|
||||
// not the test itself: sub-millisecond remainders on the two edges can cancel under
|
||||
// a full floor even when neither edge is on the grid (a dragged, fixed-length time
|
||||
// selection reproduces this), and a remainder under half a frame collides with a
|
||||
// floored edge without ever registering as off-grid. Enumerate every floored model
|
||||
// directly rather than inferring from grid membership.
|
||||
if (delta == 0) {
|
||||
const double flooredStart = floorToMilliseconds(reqStart);
|
||||
const double flooredEnd = floorToMilliseconds(reqEnd);
|
||||
const bool startAlone =
|
||||
actualFrames == frameCountFor(flooredStart, reqEnd, sampleRate);
|
||||
const bool endAlone =
|
||||
actualFrames == frameCountFor(reqStart, flooredEnd, sampleRate);
|
||||
const bool bothTogether =
|
||||
actualFrames == frameCountFor(flooredStart, flooredEnd, sampleRate);
|
||||
|
||||
if (startAlone || endAlone || bothTogether) {
|
||||
std::string models;
|
||||
auto addModel = [&](const char* label) {
|
||||
if (!models.empty()) models += ", or ";
|
||||
models += label;
|
||||
};
|
||||
if (startAlone) addModel("floors the START edge alone");
|
||||
if (endAlone) addModel("floors the END edge alone");
|
||||
if (bothTogether) addModel("floors START and END together");
|
||||
|
||||
s += " EXACT here is not proof: a render that " + models +
|
||||
" to the millisecond would print this identical count -- re-run over a"
|
||||
" window where a floored edge would show a different count before"
|
||||
" reading EXACT as the fix.";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -85,20 +85,32 @@ bool isOnMillisecondGrid(double seconds);
|
||||
// at all. Always non-empty — a capture that answered nothing has to say so, or its
|
||||
// silence reads as a pass.
|
||||
//
|
||||
// EXACT never stands alone as proof: an END that sits on the millisecond grid prints
|
||||
// the SAME EXACT count whether the channel honored the window or floored it and landed
|
||||
// back on the grid by coincidence, so that case is called out in the sentence rather
|
||||
// than left to read as settled — same principle as the existing START-edge caveat.
|
||||
// EXACT never stands alone as proof: the observed count is checked against every
|
||||
// millisecond-floored model of the same window (start floored alone, end floored alone,
|
||||
// both together), and any model that reproduces it is named in the sentence. Grid
|
||||
// membership on an edge is a PROXY for that collision, not the test itself — remainders
|
||||
// on the two edges can cancel under a full floor even when NEITHER edge sits on the
|
||||
// grid, and a remainder under half a frame collides with a floored edge without ever
|
||||
// registering as off-grid at all. Checking the models directly is what a grid test on
|
||||
// either edge alone cannot do.
|
||||
//
|
||||
// A non-zero delta that still falls inside the gate's own tolerance (renderHonoredBounds)
|
||||
// is tagged "(WITHIN TOLERANCE)" — that is the gate's ordinary edge-convention slack, not
|
||||
// evidence of the millisecond floor; a bare SHORT/LONG, or a delta matching
|
||||
// msFlooredEndFrameCount exactly, is the floor's signature.
|
||||
// evidence of the millisecond floor. The floor's signature is ONLY the "floored to the
|
||||
// millisecond" sentence (a delta matching msFlooredEndFrameCount exactly); a bare
|
||||
// SHORT with no such sentence means the shortfall's cause is unestablished, and LONG can
|
||||
// never be the floor's signature — a floor only removes frames, never adds them. A
|
||||
// window whose start and end sit in the same millisecond bucket makes msFlooredEndFrameCount
|
||||
// equal the exact count, so a real one-frame floor there reads as a bare SHORT (WITHIN
|
||||
// TOLERANCE) with no floor sentence at all — that combination is not evidence the floor
|
||||
// didn't happen, just a case this diagnostic can't see into.
|
||||
//
|
||||
// `sampleRate <= 0` means the landed file was never measured: a tail mode adds frames by
|
||||
// design and is not judged, an empty render has none, and a render whose layout failed to
|
||||
// parse or declared no sample rate is refused before it can be judged either — the
|
||||
// sentence then says the run answered nothing rather than inventing a comparison.
|
||||
// sentence then says the run answered nothing rather than inventing a comparison. A
|
||||
// window that rounds to 0 frames at this rate reads NOT JUDGED the same way: a 0-frame
|
||||
// render against a 0-frame window is not a comparison either.
|
||||
//
|
||||
// `bypassingSourceLabel`, when non-null and non-empty, means the render source itself
|
||||
// defined the window (render_settings::sourceBypassesBoundsChannel) — `channelLabel` was
|
||||
|
||||
@@ -563,10 +563,11 @@ CaptureResult OfflineRenderBackend::capture(const CaptureRequest& request) {
|
||||
// because a verdict that appeared only on some outcomes would read its own absence
|
||||
// on the rest as a pass. Auto/Manual are not judged against a frame count (they add
|
||||
// frames by design) and the sentence says so rather than comparing anyway.
|
||||
// SelectedItems/RazorArea derive their bounds from content and never consult the
|
||||
// channel at all (render_settings::sourceBypassesBoundsChannel) — the batch-item
|
||||
// path renders through SelectedItems on every capture, so without this the verdict
|
||||
// would print an EXACT/SHORT/LONG claim about a channel that was never in play.
|
||||
// SelectedItems/RazorArea are INFERRED (not SDK-confirmed) to derive their bounds
|
||||
// from content and never consult the channel at all
|
||||
// (render_settings::sourceBypassesBoundsChannel) — the batch-item path renders
|
||||
// through SelectedItems on every capture, so without this the verdict would print an
|
||||
// EXACT/SHORT/LONG claim about a channel that was never in play.
|
||||
const char* boundsBypassLabel = sourceBypassesBoundsChannel(request.sourceMode)
|
||||
? renderSourceLabel(request.sourceMode)
|
||||
: nullptr;
|
||||
|
||||
+103
-16
@@ -417,10 +417,79 @@ static void testAWindowAlreadyOnTheGridIsUnaffectedByTheChannelSwitch() {
|
||||
CHECK(contains(s, "EXACT"));
|
||||
CHECK(contains(s, "96000"));
|
||||
CHECK(!contains(s, "floored to the millisecond"));
|
||||
// The false positive this window is the shape of: an end-floored render would have
|
||||
// printed this identical EXACT count, so the line must say this run cannot tell the
|
||||
// two apart rather than reading EXACT as settled.
|
||||
CHECK(contains(s, "END edge is UNTESTED"));
|
||||
// The false positive this window is the shape of: a render that floored either edge
|
||||
// alone, or both together, would have printed this identical EXACT count (every
|
||||
// edge here is on the grid) -- the line has to say this run cannot rule any of them
|
||||
// out rather than reading EXACT as settled.
|
||||
CHECK(contains(s, "EXACT here is not proof"));
|
||||
CHECK(contains(s, "floors the START edge alone"));
|
||||
CHECK(contains(s, "floors the END edge alone"));
|
||||
CHECK(contains(s, "floors START and END together"));
|
||||
}
|
||||
|
||||
static void testEqualRemaindersCancelUnderAFullFloorEvenOffGrid() {
|
||||
// C1: a dragged, fixed-length time selection reproduces this. Neither edge sits on
|
||||
// the millisecond grid (isOnMillisecondGrid is false for both), but the START and
|
||||
// END frame-rounding remainders are EQUAL (rs == re == 8 frames), so a render that
|
||||
// floors both edges together lands on the identical count -- the grid predicate on
|
||||
// either edge alone would have missed this collision entirely.
|
||||
const double start = 1.0001724, end = 2.0001724;
|
||||
CHECK(!isOnMillisecondGrid(start));
|
||||
CHECK(!isOnMillisecondGrid(end));
|
||||
const long long expected = frameCountFor(start, end, 48000);
|
||||
CHECK(expected == 48000);
|
||||
// The both-edges-floored render lands on the SAME count as the exact one.
|
||||
CHECK(frameCountFor(1.000, 2.000, 48000) == expected);
|
||||
// Neither edge floored ALONE reproduces it -- only the combined floor does.
|
||||
CHECK(frameCountFor(1.000, end, 48000) != expected);
|
||||
CHECK(frameCountFor(start, 2.000, 48000) != expected);
|
||||
|
||||
const std::string s =
|
||||
describeBoundsExperiment("time selection", start, end, expected, 48000);
|
||||
CHECK(contains(s, "EXACT"));
|
||||
CHECK(contains(s, "EXACT here is not proof"));
|
||||
CHECK(contains(s, "floors START and END together"));
|
||||
CHECK(!contains(s, "floors the START edge alone"));
|
||||
CHECK(!contains(s, "floors the END edge alone"));
|
||||
}
|
||||
|
||||
static void testEndOffGridByUnderHalfAFrameStillCollidesWithAFlooredEnd() {
|
||||
// C1's second live shape: isOnMillisecondGrid reads this END as off-grid, but the
|
||||
// remainder is under half a frame at 48 kHz, so flooring it doesn't move its frame
|
||||
// index -- a grid test on the edge alone would still miss this collision.
|
||||
const double start = 0.0, end = 1.000005;
|
||||
CHECK(!isOnMillisecondGrid(end));
|
||||
const long long expected = frameCountFor(start, end, 48000);
|
||||
CHECK(expected == 48000);
|
||||
CHECK(frameCountFor(start, 1.000, 48000) == expected); // the floored-end model matches
|
||||
|
||||
const std::string s =
|
||||
describeBoundsExperiment("time selection", start, end, expected, 48000);
|
||||
CHECK(contains(s, "EXACT"));
|
||||
CHECK(contains(s, "EXACT here is not proof"));
|
||||
CHECK(contains(s, "floors the END edge alone"));
|
||||
}
|
||||
|
||||
static void testALongVerdictNeverCarriesTheFloorSentence() {
|
||||
// A floor only removes frames, so LONG can never be its signature -- the sentence
|
||||
// must not appear even though the delta here is a "clean" one-frame LONG.
|
||||
const std::string s =
|
||||
describeBoundsExperiment("time selection", 5.0, 6.0, 48001, 48000);
|
||||
CHECK(contains(s, "LONG"));
|
||||
CHECK(!contains(s, "floored to the millisecond"));
|
||||
}
|
||||
|
||||
static void testASubFrameWindowIsNotJudgedNotExact() {
|
||||
// A window under one frame at this rate rounds to 0 expected frames. A 0-frame
|
||||
// render against that is a 0-vs-0 coincidence of degenerate inputs, not a match --
|
||||
// it must read NOT JUDGED, never EXACT.
|
||||
const double oneTenthOfAFrame = 1.0 / (48000.0 * 10.0);
|
||||
const long long expected = frameCountFor(0.0, oneTenthOfAFrame, 48000);
|
||||
CHECK(expected == 0);
|
||||
const std::string s =
|
||||
describeBoundsExperiment("time selection", 0.0, oneTenthOfAFrame, 0, 48000);
|
||||
CHECK(contains(s, "NOT JUDGED"));
|
||||
CHECK(!contains(s, "EXACT"));
|
||||
}
|
||||
|
||||
static void testAWithinToleranceDeltaIsTaggedNotFloorShaped() {
|
||||
@@ -460,10 +529,18 @@ static void testABypassingSourceReadsNotJudgedAndNamesTheSourceNotTheChannel() {
|
||||
}
|
||||
|
||||
static void testANullOrEmptyBypassLabelFallsBackToTheOrdinaryVerdict() {
|
||||
CHECK(contains(describeBoundsExperiment("time selection", 0.0, 1.0, 48000, 48000,
|
||||
nullptr),
|
||||
"EXACT"));
|
||||
CHECK(contains(describeBoundsExperiment("time selection", 0.0, 1.0, 48000, 48000, ""),
|
||||
// Off-grid, non-cancelling edges (see testEqualRemaindersCancelUnderAFullFloorEvenOffGrid
|
||||
// for the window shape that WOULD trip the collision caveat, whose own text also
|
||||
// contains "EXACT") so this assertion is pinned to the verdict word itself, not to a
|
||||
// caveat sentence that happens to contain the same substring.
|
||||
const double start = 1.0001724, end = 2.0009724;
|
||||
const long long expected = frameCountFor(start, end, 48000);
|
||||
const std::string withNull =
|
||||
describeBoundsExperiment("time selection", start, end, expected, 48000, nullptr);
|
||||
CHECK(contains(withNull, "EXACT"));
|
||||
CHECK(!contains(withNull, "EXACT here is not proof"));
|
||||
CHECK(contains(describeBoundsExperiment("time selection", start, end, expected, 48000,
|
||||
""),
|
||||
"EXACT"));
|
||||
}
|
||||
|
||||
@@ -476,18 +553,24 @@ static void testAnOnGridStartSaysTheStartEdgeIsUntested() {
|
||||
}
|
||||
|
||||
static void testAnOffGridStartSaysTheStartEdgeIsTested() {
|
||||
// The run that would settle the start question: a start carrying its own remainder.
|
||||
// Whether REAPER floors the start or not, THIS run is the one that shows it.
|
||||
// The run that would genuinely settle the start question: a start carrying its own
|
||||
// remainder, paired with an end whose remainder does NOT cancel it (unlike
|
||||
// testEqualRemaindersCancelUnderAFullFloorEvenOffGrid's window, where the same shape
|
||||
// of start value pairs with an end that cancels it and the collision caveat fires
|
||||
// instead). No floored model reproduces this count, so EXACT here is unqualified.
|
||||
const double start = 1.0001724, end = 2.0009724;
|
||||
const long long expected = frameCountFor(start, end, 48000);
|
||||
const std::string s =
|
||||
describeBoundsExperiment("time selection", 1.0001724, 2.0001724, 48000, 48000);
|
||||
describeBoundsExperiment("time selection", start, end, expected, 48000);
|
||||
CHECK(contains(s, "IS tested"));
|
||||
CHECK(!contains(s, "UNTESTED"));
|
||||
// A floored start would have printed 48008 frames, not 48000 — so the same line
|
||||
// reads EXACT here and SHORT/LONG on the floored outcome.
|
||||
CHECK(frameCountFor(1.000, 2.0001724, 48000) == 48008);
|
||||
CHECK(contains(s, "EXACT"));
|
||||
CHECK(contains(describeBoundsExperiment("time selection", 1.0001724, 2.0001724,
|
||||
48008, 48000),
|
||||
CHECK(!contains(s, "EXACT here is not proof"));
|
||||
// A start-floored-alone render would have printed a DIFFERENT count here, so a
|
||||
// mismatch against `expected` on a re-run is real evidence, not ambiguous.
|
||||
CHECK(frameCountFor(1.000, end, 48000) != expected);
|
||||
CHECK(contains(describeBoundsExperiment("time selection", start, end,
|
||||
frameCountFor(1.000, end, 48000), 48000),
|
||||
"LONG"));
|
||||
}
|
||||
|
||||
@@ -611,6 +694,10 @@ int main() {
|
||||
testAShortfallThatIsNotTheMillisecondShapeClaimsNothingAboutIt();
|
||||
testARenderPastTheWindowReadsLong();
|
||||
testAWindowAlreadyOnTheGridIsUnaffectedByTheChannelSwitch();
|
||||
testEqualRemaindersCancelUnderAFullFloorEvenOffGrid();
|
||||
testEndOffGridByUnderHalfAFrameStillCollidesWithAFlooredEnd();
|
||||
testALongVerdictNeverCarriesTheFloorSentence();
|
||||
testASubFrameWindowIsNotJudgedNotExact();
|
||||
testAWithinToleranceDeltaIsTaggedNotFloorShaped();
|
||||
testABypassingSourceReadsNotJudgedAndNamesTheSourceNotTheChannel();
|
||||
testANullOrEmptyBypassLabelFallsBackToTheOrdinaryVerdict();
|
||||
|
||||
Reference in New Issue
Block a user