Fix eight review findings on the render-bounds diagnostics
Corrects a false comment example, fixes two tests that couldn't detect their own regressions, adds two more read-back checkpoints around Main_OnCommand so a drift report self-locates, guards a spurious zero-vs-zero coincidence match, and softens two sentences that overclaimed cause or defect.
This commit is contained in:
@@ -463,14 +463,18 @@ CaptureResult OfflineRenderBackend::capture(const CaptureRequest& request) {
|
||||
|
||||
// Silent unless a bound came back changed. Fires on EVERY tail mode on purpose:
|
||||
// only None is judged against its window after the render, so this is the sole
|
||||
// signal an Auto/Manual capture was shortened before it ever started.
|
||||
{
|
||||
// signal an Auto/Manual capture was shortened before it ever started. Named by
|
||||
// checkpoint so a DAW observation is self-locating: three reads bracket the two
|
||||
// places REAPER could quantize — the store, and the render itself.
|
||||
auto reportDrift = [&](const char* checkpoint, double atStart, double atEnd) {
|
||||
const std::string drift =
|
||||
describeBoundsDrift(request.startSeconds, request.endSeconds,
|
||||
storedStart, storedEnd, effectiveSampleRate);
|
||||
atStart, atEnd, effectiveSampleRate);
|
||||
if (!drift.empty())
|
||||
ShowConsoleMsg(("ReaSampler capture: " + drift + "\n").c_str());
|
||||
}
|
||||
ShowConsoleMsg(("ReaSampler capture (" + std::string(checkpoint) + "): " +
|
||||
drift + "\n").c_str());
|
||||
};
|
||||
reportDrift("at store", storedStart, storedEnd);
|
||||
|
||||
GetSetProjectInfo(proj, "RENDER_CHANNELS",
|
||||
static_cast<double>(request.channelCount), true);
|
||||
@@ -504,8 +508,22 @@ CaptureResult OfflineRenderBackend::capture(const CaptureRequest& request) {
|
||||
}
|
||||
setProjString(proj, "RENDER_FORMAT", fmtBase64);
|
||||
|
||||
// Read again right here: a mismatch against the store-time read-back above
|
||||
// means something between the two writes and this line moved the bounds,
|
||||
// before the render ever ran.
|
||||
reportDrift("before render",
|
||||
GetSetProjectInfo(proj, "RENDER_STARTPOS", 0.0, false),
|
||||
GetSetProjectInfo(proj, "RENDER_ENDPOS", 0.0, false));
|
||||
|
||||
Main_OnCommand(kActionRenderUsingMostRecentSettings, 0);
|
||||
|
||||
// And once more here, while the guard above is still live and before it restores
|
||||
// anything: only the gap between this read and the one immediately above can be
|
||||
// the render itself.
|
||||
reportDrift("after render",
|
||||
GetSetProjectInfo(proj, "RENDER_STARTPOS", 0.0, false),
|
||||
GetSetProjectInfo(proj, "RENDER_ENDPOS", 0.0, false));
|
||||
|
||||
// Main_OnCommand returns void, so a failed render is silent — stat the
|
||||
// expected output path to detect it.
|
||||
const std::string expectedPath = paths.absoluteDir + "/" + paths.fileName;
|
||||
|
||||
@@ -369,6 +369,11 @@ RealtimeRecordBackend::begin(const CaptureRequest& request,
|
||||
|
||||
// recordWindowEnd extends past the range end for a tail mode so the
|
||||
// transport captures the decay; cursor + time selection are restored by restore().
|
||||
// `[verify — DAW]` whether rs/re come back changed on this isSet=true call: the SDK
|
||||
// header names both `double*` but documents no read-back semantics for either
|
||||
// direction, and nothing here reads rs/re again after the call to notice. Lower
|
||||
// stakes than the offline RENDER_* store: completion is driven by the play cursor
|
||||
// reaching the range end (tick(), below), not by re-reading this pair.
|
||||
double rs = request.startSeconds, re = st->recordWindowEnd_;
|
||||
GetSet_LoopTimeRange(true, false, &rs, &re, false);
|
||||
SetEditCurPos(request.startSeconds, false, false);
|
||||
|
||||
@@ -100,12 +100,17 @@ BoundsVerdict checkRenderedBounds(const std::string& renderedPath,
|
||||
if (renderHonoredBounds(expectedFrames, actualFrames)) return v;
|
||||
|
||||
// Says whether this shortfall has the one shape two live short renders already
|
||||
// matched to the frame, so every refusal from here on adds to (or breaks) that
|
||||
// evidence instead of needing the arithmetic done by hand. A count coincidence
|
||||
// only — it does not establish how the render resolved anything.
|
||||
// matched to the frame: the END alone floored to the millisecond. Checked against
|
||||
// the END only -- a refusal whose START is also off-grid and independently floored
|
||||
// would not match this shape, and this note's silence on that refusal is this
|
||||
// check not covering it, not the coincidence breaking. Excludes 0, which every
|
||||
// sub-millisecond window (a legitimate day-one capture) also floors to, and which
|
||||
// would otherwise match a render that produced nothing. A count coincidence only —
|
||||
// it does not establish how the render resolved anything.
|
||||
const long long msFlooredEnd =
|
||||
msFlooredEndFrameCount(request.startSeconds, request.endSeconds, rate);
|
||||
const std::string msNote =
|
||||
actualFrames == msFlooredEndFrameCount(request.startSeconds,
|
||||
request.endSeconds, rate)
|
||||
(msFlooredEnd > 0 && actualFrames == msFlooredEnd)
|
||||
? " Those are exactly the frames this window holds with its end floored to"
|
||||
" the millisecond -- a match on the count, not a measured cause."
|
||||
: std::string();
|
||||
|
||||
Reference in New Issue
Block a user