capture: close batch-quarantine silence, 0-byte asymmetry, and round-two doc overclaims

Batch captures now name the retained-render folder once instead of nothing; Auto/Manual tail modes refuse a 0-byte render like None does; VERIFICATION.md steps 1-3 no longer invite a false conclusion; docs/comments no longer overclaim.
This commit is contained in:
2026-08-02 08:00:12 -04:00
parent 2005f90c66
commit 0511d16d4f
10 changed files with 127 additions and 26 deletions
+29 -2
View File
@@ -16,11 +16,13 @@
#include "shell/panel/panel_bank_ops.h" // bankPanelSelectedSampleIds / SourceBankId
#include "shell/panel/panel_input.h" // bankPanelRefresh
#include "core/capture/batch_capture.h" // planCaptureUnits / BatchOutcome
#include "core/capture/capture_paths.h" // projectDirOfRpp
#include "core/model/bank_book.h" // BankBook / Bank
#include "core/model/provenance.h" // recipe parse/build, fingerprint
#include "shell/persist/session.h" // ReaSamplerSession
#include "shell/capture/capture_orchestrator.h" // captureAndIndexOne / renderOffline
#include "shell/capture/provenance_shell.h" // fxChainIdentity* / trackByGuid
#include "shell/capture/render_bounds_gate.h" // refusedRenderFolder
#include "shell/capture/scope_resolve.h" // ResolvedSource
#include "shell/capture/track_guid.h" // guidString
@@ -28,6 +30,7 @@
#define REAPERAPI_MINIMAL
#define REAPERAPI_WANT_CountSelectedMediaItems
#define REAPERAPI_WANT_EnumProjects
#define REAPERAPI_WANT_GetSelectedMediaItem
#define REAPERAPI_WANT_GetMediaItem_Track
#define REAPERAPI_WANT_GetMediaItemInfo_Value
@@ -95,6 +98,24 @@ private:
std::vector<MediaItem*> selected_;
};
// Names where refused renders were retained, once, when the batch quarantined at
// least one (BoundsMismatch failures only -- a render that never produced a file has
// nothing to retain). Without this, a batch's per-unit failure detail (which DOES name
// the destination, same as a single capture's console line) never reaches the console
// at all -- the batch summary reports ordinals only.
std::string withQuarantineNote(std::string line, int quarantinedCount) {
if (quarantinedCount <= 0) return line;
std::vector<char> buf(4096, '\0');
EnumProjects(-1, buf.data(), static_cast<int>(buf.size()));
const std::string dir = projectDirOfRpp(std::string(buf.data()));
if (dir.empty()) return line; // unreachable: a quarantine implies a saved project
line += " " + std::to_string(quarantinedCount) + " refused render" +
(quarantinedCount == 1 ? " was" : "s were") + " retained for diagnosis, "
"normally at " + refusedRenderFolder(dir) + " (delete when done) -- one "
"whose move there failed instead stays in the bank folder, unindexed.";
return line;
}
// Deselect-all then select-one so the offline render's &32 bit captures exactly
// this item. Called inside ItemSelectionGuard, which restores the original selection.
void selectOnlyItem(MediaItem* item)
@@ -196,6 +217,7 @@ void RunBatchCaptureItems(ReaSamplerSession& session)
BatchOutcome outcome;
bool anyAdded = false;
int quarantined = 0; // BoundsMismatch failures, each of which retained a file
{
// selGuard restores the original item selection on every exit path.
ItemSelectionGuard selGuard;
@@ -232,6 +254,7 @@ void RunBatchCaptureItems(ReaSamplerSession& session)
const bool ok = (res.status == CaptureStatus::Ok);
outcome.record(unit.ordinal, ok, ok ? std::string{} : res.message);
if (ok) anyAdded = true;
else if (res.status == CaptureStatus::BoundsMismatch) ++quarantined;
}
} // selGuard restores the original selection here, on every path
@@ -243,7 +266,8 @@ void RunBatchCaptureItems(ReaSamplerSession& session)
session.saveToActiveProject();
}
ShowConsoleMsg((outcome.summaryLine("item") + "\n").c_str());
ShowConsoleMsg((withQuarantineNote(outcome.summaryLine("item"), quarantined) +
"\n").c_str());
}
// One sample per razor area, track scope over that area's own range. Track scope
@@ -267,6 +291,7 @@ void RunBatchCaptureRazor(ReaSamplerSession& session)
BatchOutcome outcome;
bool anyAdded = false;
int quarantined = 0; // BoundsMismatch failures, each of which retained a file
{
// selGuard restores the original track selection on every exit path.
TrackSelectionGuard selGuard;
@@ -298,6 +323,7 @@ void RunBatchCaptureRazor(ReaSamplerSession& session)
const bool ok = (res.status == CaptureStatus::Ok);
outcome.record(unit.ordinal, ok, ok ? std::string{} : res.message);
if (ok) anyAdded = true;
else if (res.status == CaptureStatus::BoundsMismatch) ++quarantined;
}
} // selGuard restores the original track selection here, on every path
@@ -307,7 +333,8 @@ void RunBatchCaptureRazor(ReaSamplerSession& session)
session.saveToActiveProject();
}
ShowConsoleMsg((outcome.summaryLine("razor area") + "\n").c_str());
ShowConsoleMsg((withQuarantineNote(outcome.summaryLine("razor area"), quarantined) +
"\n").c_str());
}
// Regenerates a provenanced sample's file from its recorded source's current state