Settle the render window on the time selection and delete the experiment that proved it

The millisecond floor lives in the custom-bounds field, not the engine, so
RENDER_BOUNDSFLAG=2 is now the only bounds mode: the two-position type, the
console verdict and the STARTPOS/ENDPOS drift probe all go. capture.cpp 697 -> 622.
This commit is contained in:
2026-08-02 16:55:12 -04:00
parent d85e50c143
commit 8331df2e91
14 changed files with 205 additions and 862 deletions
+28 -82
View File
@@ -111,12 +111,8 @@ static void testLabelsSeparateExactlyWhatTheRenderSeparates() {
// --- tail: TailMode -> RENDER_* mapping (docs/product/capture-tail.md) --------
// The tail assertions below are about the MODE's mapping; the one value that also
// depends on the bounds channel has its own test, so they all pin the channel that
// every shipped capture rendered on.
static TailRenderSettings tailFor(TailMode mode, double manualTailMs) {
return tailRenderSettingsFor(mode, manualTailMs,
RenderBoundsChannel::CustomTimeBounds);
return tailRenderSettingsFor(mode, manualTailMs);
}
static void testTailNoneIsExactBounds() {
@@ -136,11 +132,11 @@ static void testTailNoneIsExactBounds() {
}
static void testTailAutoIsSurgicalTrim() {
// Auto -> custom-bounds tail bit, 8 s cap, SURGICAL normalize (ONLY &32768), and
// the -72 dB TRIMEND ratio. The disable-all bit must NOT be set (it is semantically
// opposed to trim — this assertion catches a regression to the None normalize).
// Auto -> the time-selection tail bit, 8 s cap, SURGICAL normalize (ONLY &32768),
// and the -72 dB TRIMEND ratio. The disable-all bit must NOT be set (it is
// semantically opposed to trim — this catches a regression to the None normalize).
TailRenderSettings t = tailFor(TailMode::Auto, 0.0);
CHECK(t.tailFlag == kTailFlagCustomBounds); // &1
CHECK(t.tailFlag == kTailFlagTimeSelection); // &4
CHECK(t.tailMs == kMaxTailMs); // 8000
CHECK(t.normalize == kNormalizeTrimEnd); // exactly 32768, nothing else
CHECK((t.normalize & kNormalizeDisableAll) == 0); // disable-all is NOT set
@@ -161,11 +157,11 @@ static void testAutoTrimRatioDerivesFromDb() {
}
static void testTailManualFixedNoTrim() {
// Manual -> custom-bounds tail, the requested ms (within cap), disable-all
// Manual -> the time-selection tail bit, the requested ms (within cap), disable-all
// normalize (no trim). A Manual capture is a fixed tail, so it keeps today's
// disable-all exactly like the no-tail path.
TailRenderSettings t = tailFor(TailMode::Manual, 2500.0);
CHECK(t.tailFlag == kTailFlagCustomBounds);
CHECK(t.tailFlag == kTailFlagTimeSelection);
CHECK(t.tailMs == 2500.0);
CHECK(t.normalize == kNormalizeDisableAll);
CHECK(t.trimEnd == 0.0);
@@ -181,59 +177,29 @@ static void testTailManualClampsToCap() {
CHECK(tailFor(TailMode::Manual, -50.0).tailMs == 0.0);
}
// --- bounds channel: RENDER_BOUNDSFLAG mode + the tail bit it drags along ------
// --- bounds mode: RENDER_BOUNDSFLAG + the tail bit paired with it ---------------
static void testEachChannelNamesItsOwnBoundsFlagMode() {
// The two RENDER_BOUNDSFLAG values, as literals from the SDK header — 0 = custom
// time bounds, 2 = time selection. Pinned as numbers so a renumbering of the enum
// cannot silently point a capture at "entire project" or "selected media items".
CHECK(renderBoundsFlagFor(RenderBoundsChannel::CustomTimeBounds) == 0);
CHECK(renderBoundsFlagFor(RenderBoundsChannel::TimeSelection) == 2);
static void testTheBoundsModeIsTheTimeSelectionAndItsTailBitIsPairedWithIt() {
// Literals from the SDK header, pinned as numbers so neither can drift onto
// another bounds mode's value: RENDER_BOUNDSFLAG 2 = time selection (~3042), and
// RENDER_TAILFLAG's bits are keyed per bounds mode, &4 = time selection (~3047).
// The custom-bounds pair (0 / &1) is DELIBERATELY absent — that mode floors the
// window to the millisecond (render_settings.h) and must not come back.
CHECK(kRenderBoundsTimeSelection == 2);
CHECK(kTailFlagTimeSelection == 4);
CHECK(kTailFlagNone == 0);
}
static void testTailBitFollowsTheBoundsChannel() {
// RENDER_TAILFLAG's bits are per-bounds-mode: &1 covers custom time bounds, &4
// covers the time selection. A tail set under the other channel's bit renders no
// tail at all, which is why the mapping takes the channel rather than trusting a
// caller to OR the right one in.
CHECK(tailFlagBitFor(RenderBoundsChannel::CustomTimeBounds) == 1);
CHECK(tailFlagBitFor(RenderBoundsChannel::TimeSelection) == 4);
static void testEveryTailModeSetsTheBitTheBoundsModeReads() {
// A tail set under a different bounds mode's bit renders no tail at all, so both
// tail-bearing modes must carry &4 — a fix applied to Auto alone would leave
// Manual silently tailless.
for (TailMode mode : {TailMode::Auto, TailMode::Manual})
CHECK(tailRenderSettingsFor(mode, 2500.0).tailFlag == kTailFlagTimeSelection);
// Both tail-bearing modes follow it — a fix applied to Auto alone would leave
// Manual rendering under a bit the bounds mode does not read.
for (TailMode mode : {TailMode::Auto, TailMode::Manual}) {
CHECK(tailRenderSettingsFor(mode, 2500.0,
RenderBoundsChannel::CustomTimeBounds)
.tailFlag == kTailFlagCustomBounds);
CHECK(tailRenderSettingsFor(mode, 2500.0,
RenderBoundsChannel::TimeSelection)
.tailFlag == kTailFlagTimeSelection);
}
}
static void testNoneSetsNoTailBitOnEitherChannel() {
// None is exact bounds on every channel: no tail bit, so no channel's bit either.
CHECK(tailRenderSettingsFor(TailMode::None, 5000.0,
RenderBoundsChannel::CustomTimeBounds)
.tailFlag == kTailFlagNone);
CHECK(tailRenderSettingsFor(TailMode::None, 5000.0,
RenderBoundsChannel::TimeSelection)
.tailFlag == kTailFlagNone);
}
static void testTheChannelLabelNamesTheModeAndItsStore() {
// The console verdict is read by someone deciding which channel to keep, so the
// label has to name both the mode number and where the window actually went.
const std::string custom = renderBoundsChannelLabel(RenderBoundsChannel::CustomTimeBounds);
CHECK(custom.find("RENDER_BOUNDSFLAG=0") != std::string::npos);
CHECK(custom.find("RENDER_STARTPOS") != std::string::npos);
const std::string ts = renderBoundsChannelLabel(RenderBoundsChannel::TimeSelection);
CHECK(ts.find("RENDER_BOUNDSFLAG=2") != std::string::npos);
CHECK(ts.find("GetSet_LoopTimeRange") != std::string::npos);
// Two channels that read alike in the console would make the experiment unreadable.
CHECK(custom != ts);
// None is exact bounds: no tail bit at all, whatever ms it is handed.
CHECK(tailRenderSettingsFor(TailMode::None, 5000.0).tailFlag == kTailFlagNone);
CHECK(tailRenderSettingsFor(TailMode::None, 0.0).tailFlag == kTailFlagNone);
}
// --- realtimeRecordWindowEnd: the T2 record-window extension -----------------
@@ -384,23 +350,6 @@ static void testMultiTrackStemRenderIsNamedForRefusal() {
CHECK(!isMultiTrackStemRender(sourceModeForScope(CaptureScope::Item, true), 2));
}
static void testSourceBypassesBoundsChannelOnlyForContentDerivedSources() {
// SelectedItems (&32) and RazorArea (&4096) derive their bounds from the
// selected items'/areas' own extents -- RENDER_BOUNDSFLAG is never consulted, so
// a bounds-channel verdict is not evidence for either (the regression this
// predicate exists to catch: RunBatchCaptureItems always renders through
// SelectedItems, so this false-EXACT would fire on every batch-item capture).
CHECK(sourceBypassesBoundsChannel(SourceMode::SelectedItems));
CHECK(sourceBypassesBoundsChannel(SourceMode::RazorArea));
// Every other source is genuinely time-bounded through RENDER_STARTPOS/ENDPOS or
// the time selection, so the channel IS the evidence for these.
CHECK(!sourceBypassesBoundsChannel(SourceMode::MasterMix));
CHECK(!sourceBypassesBoundsChannel(SourceMode::TimeSelection));
CHECK(!sourceBypassesBoundsChannel(SourceMode::SelectedTracks));
CHECK(!sourceBypassesBoundsChannel(SourceMode::Realtime));
}
static void testRefusalMessagesAreSiblingsWithDistinctExits() {
const std::string item = multiTrackRefusalMessage(CaptureScope::Item);
const std::string track = multiTrackRefusalMessage(CaptureScope::Track);
@@ -528,10 +477,8 @@ int main() {
testAutoTrimRatioDerivesFromDb();
testTailManualFixedNoTrim();
testTailManualClampsToCap();
testEachChannelNamesItsOwnBoundsFlagMode();
testTailBitFollowsTheBoundsChannel();
testNoneSetsNoTailBitOnEitherChannel();
testTheChannelLabelNamesTheModeAndItsStore();
testTheBoundsModeIsTheTimeSelectionAndItsTailBitIsPairedWithIt();
testEveryTailModeSetsTheBitTheBoundsModeReads();
testRealtimeWindowNoneIsExact();
testRealtimeWindowAutoAddsCap();
testRealtimeWindowManualAddsClampedLength();
@@ -543,7 +490,6 @@ int main() {
testScopeSourceModes();
testRangedItemScopeRendersTimeBounded();
testMultiTrackStemRenderIsNamedForRefusal();
testSourceBypassesBoundsChannelOnlyForContentDerivedSources();
testRefusalMessagesAreSiblingsWithDistinctExits();
testRefusalMessagesMatchGoldenLiterals();
testRangeInference();
+74 -319
View File
@@ -2,13 +2,12 @@
// Covers the bounds-equality number (a window's exact frame count at the project
// rate), the verdict the offline backend refuses a capture on, the predicate
// that decides whether REAPER's selected-items render source can express a
// requested window at all, and the two short-render diagnostics.
// requested window at all, and the millisecond-floor shape a refusal quotes.
#include "../src/core/capture/render_window.h"
#include <cmath>
#include <cstdio>
#include <string>
using namespace reasampler::capture;
@@ -16,10 +15,6 @@ static int g_fail = 0;
#define CHECK(cond) do { if(!(cond)) { \
std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)
static bool contains(const std::string& haystack, const std::string& needle) {
return haystack.find(needle) != std::string::npos;
}
// --- frameCountFor: the bounds equality, stated as a number ------------------
static void testFrameCountIsExactNotRounded() {
@@ -358,308 +353,86 @@ static void testOffGridRecognizesASubMillisecondRemainder() {
CHECK(!isOnMillisecondGrid(1.0 - 1.0 / 48000.0));
}
// --- describeBoundsExperiment: the console verdict on a bounds channel --------
// --- the settled time-selection observations, as pure arithmetic ---------------
//
// Two live 48 kHz TailMode::None renders on RENDER_BOUNDSFLAG=2 came back EXACT at
// 97627 frames. The console printed run TWO's start verbatim (2.0338983050847457s);
// run ONE started at 0s and its end was never printed, so the value below is a
// reconstruction from run two's own printed start — it pins the count, not which
// double REAPER was handed.
static void testAnExactRenderReadsExactAndNamesItsChannel() {
const std::string s =
describeBoundsExperiment("time selection (RENDER_BOUNDSFLAG=2)",
0.0, 1.6551724137931001, 79448, 48000);
CHECK(contains(s, "EXACT"));
CHECK(!contains(s, "SHORT"));
CHECK(contains(s, "time selection (RENDER_BOUNDSFLAG=2)"));
CHECK(contains(s, "79448"));
CHECK(contains(s, "48000 Hz"));
// The END here carries a sub-millisecond remainder, so this run DID test it --
// the END-untested caveat must not fire on a window it didn't apply to.
CHECK(!contains(s, "END edge is UNTESTED"));
static void testTheSettledExactRenderOnTheOnGridStart() {
CHECK(frameCountFor(0.0, 2.0338983050847457, 48000) == 97627);
// Run one could not test the START: 0s is on the grid, which floor, ceil and round
// all leave alone, so a start-flooring render prints the identical count.
CHECK(isOnMillisecondGrid(0.0));
// Its END, though, WAS under test — a floored end would have printed 43 frames fewer.
CHECK(msFlooredEndFrameCount(0.0, 2.0338983050847457, 48000) == 97584);
CHECK(!renderHonoredBounds(97627, 97584));
}
static void testTheLiveShortfallReadsShortAndNamesTheMillisecondShape() {
// The observation, replayed through the verdict: 79440 produced against 79448.
const std::string s =
describeBoundsExperiment("custom time bounds (RENDER_BOUNDSFLAG=0)",
0.0, 1.6551724137931001, 79440, 48000);
CHECK(contains(s, "SHORT"));
CHECK(!contains(s, "EXACT"));
CHECK(contains(s, "79440"));
CHECK(contains(s, "79448"));
// 79440 IS the ms-floored count, so the verdict has to say the floor did not move.
CHECK(contains(s, "floored to the millisecond"));
}
static void testAShortfallThatIsNotTheMillisecondShapeClaimsNothingAboutIt() {
// A render 3 frames short is short, but 79445 is not the floored count — the
// millisecond sentence must not appear, or it would assert a shape that is absent.
CHECK(msFlooredEndFrameCount(0.0, 1.6551724137931001, 48000) != 79445);
const std::string s =
describeBoundsExperiment("custom time bounds", 0.0, 1.6551724137931001,
79445, 48000);
CHECK(contains(s, "SHORT"));
CHECK(!contains(s, "floored to the millisecond"));
}
static void testARenderPastTheWindowReadsLong() {
// The whole-item widening, through the verdict: 30 s printed for a 1 s window.
const std::string s =
describeBoundsExperiment("custom time bounds", 5.0, 6.0, 30 * 48000, 48000);
CHECK(contains(s, "LONG"));
CHECK(contains(s, "1440000 frames"));
CHECK(contains(s, "the 48000 the window asks for"));
}
static void testAWindowAlreadyOnTheGridIsUnaffectedByTheChannelSwitch() {
// A window whose end is a whole millisecond has nothing for a floor to take: the
// exact count and the floored count are the same number, so an exact render reads
// EXACT and the millisecond sentence never fires.
CHECK(frameCountFor(0.0, 2.0, 48000) == msFlooredEndFrameCount(0.0, 2.0, 48000));
const std::string s =
describeBoundsExperiment("time selection", 0.0, 2.0, 96000, 48000);
CHECK(contains(s, "EXACT"));
CHECK(contains(s, "96000"));
CHECK(!contains(s, "floored to the millisecond"));
// 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;
static void testTheSettledExactRenderTestedBothEdges() {
// Run two: both edges carry a sub-millisecond remainder, and the render still
// printed the window's exact count.
const double start = 2.0338983050847457, end = 4.0677966101694913;
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);
CHECK(frameCountFor(start, end, 48000) == 97627);
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"));
// What makes that EXACT proof rather than a coincidence: NO millisecond-floored
// model of this window reproduces 97627, and every one of them sits outside the
// gate's one-frame tolerance. This is the assertion the whole experiment rests on.
const long long startAlone = frameCountFor(2.033, end, 48000);
const long long endAlone = frameCountFor(start, 4.067, 48000);
const long long bothTogether = frameCountFor(2.033, 4.067, 48000);
CHECK(startAlone == 97670);
CHECK(endAlone == 97589);
CHECK(bothTogether == 97632);
CHECK(!renderHonoredBounds(97627, startAlone));
CHECK(!renderHonoredBounds(97627, endAlone));
CHECK(!renderHonoredBounds(97627, bothTogether));
}
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
static void testOnAndOffGridWindowsAreHonoredIdentically() {
// Nothing on the settled path may treat a grid-aligned window differently from one
// carrying a remainder — the whole point of leaving the flooring channel behind.
const double onStart = 1.000, onEnd = 2.000;
const double offStart = 1.0001724, offEnd = 2.0001724;
CHECK(isOnMillisecondGrid(onStart));
CHECK(isOnMillisecondGrid(onEnd));
CHECK(!isOnMillisecondGrid(offStart));
CHECK(!isOnMillisecondGrid(offEnd));
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"));
const long long on = frameCountFor(onStart, onEnd, 48000);
const long long off = frameCountFor(offStart, offEnd, 48000);
CHECK(on == 48000);
CHECK(off == 48000);
// The discriminating half: the off-grid window is one a flooring render WOULD get
// wrong (47992 against 48000) while the on-grid one is untouched by a floor. The
// gate's verdict must not notice that difference at any delta.
CHECK(msFlooredEndFrameCount(offStart, offEnd, 48000) == 47992);
CHECK(msFlooredEndFrameCount(onStart, onEnd, 48000) == on);
for (long long delta = -3; delta <= 3; ++delta)
CHECK(renderHonoredBounds(on, on + delta) ==
renderHonoredBounds(off, off + delta));
}
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() {
// One frame off frameCountFor is the gate's own edge-convention slack
// (render_window.h), not the millisecond floor -- the verdict must say so rather
// than reading like a genuine miss or like the floor was escaped.
const std::string shortByOne =
describeBoundsExperiment("time selection", 0.0, 4.067797, 195253, 48000);
CHECK(contains(shortByOne, "SHORT"));
CHECK(contains(shortByOne, "WITHIN TOLERANCE"));
CHECK(!contains(shortByOne, "floored to the millisecond"));
const std::string longByOne =
describeBoundsExperiment("time selection", 0.0, 4.067797, 195255, 48000);
CHECK(contains(longByOne, "LONG"));
CHECK(contains(longByOne, "WITHIN TOLERANCE"));
// A genuine miss (outside the tolerance) carries no such tag.
const std::string shortByThree =
describeBoundsExperiment("time selection", 0.0, 4.067797, 195251, 48000);
CHECK(contains(shortByThree, "SHORT"));
CHECK(!contains(shortByThree, "WITHIN TOLERANCE"));
}
static void testABypassingSourceReadsNotJudgedAndNamesTheSourceNotTheChannel() {
// SelectedItems/RazorArea derive their own bounds from content -- the channel
// named by channelLabel was never consulted, so a matching frame count here would
// be a coincidence, not evidence the channel escaped the floor.
const std::string s =
describeBoundsExperiment("time selection", 0.0, 1.6551724137931001,
79448, 48000, "selected media items");
CHECK(contains(s, "NOT JUDGED"));
CHECK(contains(s, "selected media items"));
CHECK(!contains(s, "EXACT"));
// The channel is still named at the top of the line -- only the verdict changes.
CHECK(contains(s, "time selection"));
}
static void testANullOrEmptyBypassLabelFallsBackToTheOrdinaryVerdict() {
// 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"));
}
static void testAnOnGridStartSaysTheStartEdgeIsUntested() {
// Both live observations started at 0 s — the value that hides a start-side floor.
const std::string s =
describeBoundsExperiment("time selection", 0.0, 1.6551724137931001, 79448, 48000);
CHECK(contains(s, "UNTESTED"));
CHECK(contains(s, "millisecond grid"));
}
static void testAnOffGridStartSaysTheStartEdgeIsTested() {
// 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", start, end, expected, 48000);
CHECK(contains(s, "IS tested"));
CHECK(!contains(s, "UNTESTED"));
CHECK(contains(s, "EXACT"));
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"));
}
static void testAt44100WhereAMillisecondIsNotAWholeNumberOfFrames() {
// 44.1 kHz: the window is 463 frames, the ms-floored one 441 (both pinned in
// testMillisecondFloorAt44100WhereAMillisecondIsNotWholeFrames). The verdict has to
// reach the same two numbers at a rate where a millisecond is 44.1 frames.
const std::string exact =
describeBoundsExperiment("time selection", 0.0, 0.0105, 463, 44100);
CHECK(contains(exact, "EXACT"));
CHECK(contains(exact, "44100 Hz"));
const std::string floored =
describeBoundsExperiment("custom time bounds", 0.0, 0.0105, 441, 44100);
CHECK(contains(floored, "SHORT"));
CHECK(contains(floored, "floored to the millisecond"));
}
static void testAnUnmeasuredRenderAnswersNothingRatherThanPassing() {
// Auto/Manual are not judged against a frame count, and an empty render has none.
// The line must still print and must not read as a pass — its silence would.
const std::string s =
describeBoundsExperiment("time selection", 0.0, 1.6551724137931001, 0, 0);
CHECK(!s.empty());
CHECK(contains(s, "NOT JUDGED"));
CHECK(!contains(s, "EXACT"));
CHECK(contains(s, "time selection"));
}
static void testAnUnnamedChannelStillProducesAReadableLine() {
CHECK(contains(describeBoundsExperiment(nullptr, 0.0, 1.0, 48000, 48000),
"unnamed"));
CHECK(contains(describeBoundsExperiment("", 0.0, 1.0, 48000, 48000), "unnamed"));
}
// --- describeBoundsDrift: the read-back's verdict ------------------------------
static void testBoundsThatReadBackUnchangedDescribeNothing() {
// The answer that proves the request crossed into REAPER intact — including for a
// window whose end is nowhere near a millisecond boundary.
CHECK(describeBoundsDrift(0.0, 4.067797, 0.0, 4.067797, 48000).empty());
CHECK(describeBoundsDrift(1.0001724, 2.0001724, 1.0001724, 2.0001724, 48000).empty());
}
static void testADriftedEndNamesBothWindowsAndBothCounts() {
const std::string s =
describeBoundsDrift(0.0, 4.067797, 0.0, 4.067, 48000);
CHECK(!s.empty());
// Both counts as literals from the DAW observation, not re-derived from the same
// functions the sentence was built with.
CHECK(contains(s, "195254")); // what the request asks for
CHECK(contains(s, "195216")); // what the drifted window would hold
CHECK(contains(s, "48000 Hz"));
}
static void testTheReportPrintsEnoughDigitsToShowTheDrift() {
// A report whose two numbers print identically is evidence of nothing. Two ends a
// single ULP apart — far under the sixth decimal a shorter rendering would stop at
// — must still read as two different numbers. Pinned as the actual %.17g literals
// (not the needle the two ends share, "s)", which occurs at every precision and so
// proves nothing): a report that regressed to a shorter format like %.6g would
// print the same six significant digits for both ends, and these two `contains`
// checks would then fail.
const double asked = 4.067797;
const double stored = std::nextafter(asked, 5.0);
char askedBuf[32], storedBuf[32];
std::snprintf(askedBuf, sizeof(askedBuf), "%.17g", asked);
std::snprintf(storedBuf, sizeof(storedBuf), "%.17g", stored);
CHECK(std::string(askedBuf) != std::string(storedBuf));
const std::string s = describeBoundsDrift(0.0, asked, 0.0, stored, 48000);
CHECK(!s.empty());
CHECK(contains(s, askedBuf));
CHECK(contains(s, storedBuf));
}
static void testADriftedStartIsCaughtToo() {
// The edge both observations could not test.
const std::string s = describeBoundsDrift(1.0001724, 2.0, 1.000, 2.0, 48000);
CHECK(!s.empty());
CHECK(contains(s, "1.0001724"));
}
static void testAnUnknownRateStillReportsTheDriftWithoutFrames() {
// A project that never pinned a rate reads 0. The drift is still worth saying; a
// frame count over an unknown rate is not.
const std::string s = describeBoundsDrift(0.0, 4.067797, 0.0, 4.067, 0);
CHECK(!s.empty());
CHECK(!contains(s, "frames"));
static void testOnAndOffGridAt44100WhereAMillisecondIsNotWholeFrames() {
// 44.1 kHz: a millisecond is 44.1 frames, so a grid-aligned window's edges are NOT
// frame-aligned. The exact counts must still be exact and the two must still be
// judged identically.
const double onStart = 1.000, onEnd = 2.000;
const double offStart = 1.0001724, offEnd = 2.0001724;
const long long on = frameCountFor(onStart, onEnd, 44100);
const long long off = frameCountFor(offStart, offEnd, 44100);
CHECK(on == 44100);
CHECK(off == 44100);
CHECK(msFlooredEndFrameCount(offStart, offEnd, 44100) == 44092);
CHECK(msFlooredEndFrameCount(onStart, onEnd, 44100) == on);
for (long long delta = -3; delta <= 3; ++delta)
CHECK(renderHonoredBounds(on, on + delta) ==
renderHonoredBounds(off, off + delta));
}
int main() {
@@ -689,28 +462,10 @@ int main() {
testTheTwoLiveShortRendersPinnedAtFullPrecision();
testOnGridRecognizesWholeMillisecondsIncludingTheBinaryTrap();
testOffGridRecognizesASubMillisecondRemainder();
testAnExactRenderReadsExactAndNamesItsChannel();
testTheLiveShortfallReadsShortAndNamesTheMillisecondShape();
testAShortfallThatIsNotTheMillisecondShapeClaimsNothingAboutIt();
testARenderPastTheWindowReadsLong();
testAWindowAlreadyOnTheGridIsUnaffectedByTheChannelSwitch();
testEqualRemaindersCancelUnderAFullFloorEvenOffGrid();
testEndOffGridByUnderHalfAFrameStillCollidesWithAFlooredEnd();
testALongVerdictNeverCarriesTheFloorSentence();
testASubFrameWindowIsNotJudgedNotExact();
testAWithinToleranceDeltaIsTaggedNotFloorShaped();
testABypassingSourceReadsNotJudgedAndNamesTheSourceNotTheChannel();
testANullOrEmptyBypassLabelFallsBackToTheOrdinaryVerdict();
testAnOnGridStartSaysTheStartEdgeIsUntested();
testAnOffGridStartSaysTheStartEdgeIsTested();
testAt44100WhereAMillisecondIsNotAWholeNumberOfFrames();
testAnUnmeasuredRenderAnswersNothingRatherThanPassing();
testAnUnnamedChannelStillProducesAReadableLine();
testBoundsThatReadBackUnchangedDescribeNothing();
testADriftedEndNamesBothWindowsAndBothCounts();
testTheReportPrintsEnoughDigitsToShowTheDrift();
testADriftedStartIsCaughtToo();
testAnUnknownRateStillReportsTheDriftWithoutFrames();
testTheSettledExactRenderOnTheOnGridStart();
testTheSettledExactRenderTestedBothEdges();
testOnAndOffGridWindowsAreHonoredIdentically();
testOnAndOffGridAt44100WhereAMillisecondIsNotWholeFrames();
if (g_fail) { std::printf("%d check(s) FAILED\n", g_fail); return 1; }
std::printf("render_window: all checks passed\n");