fix(ingest): convert-on-import to 32f WAV, undo-group bank+assign, overflow guards

Non-WAV sources decode via PCM_source::GetSamples and land as canonical 32f
RIFF/WAVE; hash taken post-conversion so re-imports dedup. Undo block covers
bank mutation + assign_request atomically. Overflow guards + adversarial tests.
This commit is contained in:
2026-07-26 21:56:09 -04:00
parent 8074e21057
commit 373948c18a
5 changed files with 378 additions and 78 deletions
+20 -1
View File
@@ -867,15 +867,34 @@ static std::string RunCapture(const reasampler::CaptureActionDef& def)
// inserts a timeline item (load-bearing principle); the only addition here is the
// bank-index-id -> assignment-request write after the sample lands. If the capture
// failed / no-op'd (empty id), no assignment is written (nothing to assign).
//
// UNDO GROUPING: both the bank mutation (RunCapture -> saveToActiveProject) AND the
// assignment-request write (ingestAssignActiveInstance -> writeAssignmentRequest) are
// wrapped in a single undo block so Ctrl-Z rolls back both ext-state keys atomically.
// An undo that removes the captured sample also clears the assign_request that named it,
// preventing a stale request from pointing at a removed sample. The block uses the house
// pattern (UNDO_STATE_MISCCFG, discarded on an unsaved project with empty label + zero
// flag) matching the bank-op family in actions.cpp.
static void RunCaptureItemAssign()
{
// Reuse the Item-scope def from the capture table (index 0) — same range logic, same
// FX-scope neutralize, same bank/persist landing as the plain "capture item" action.
Undo_BeginBlock2(nullptr);
const std::string sampleId =
RunCapture(reasampler::captureActionTable()[0]);
if (sampleId.empty()) return; // capture failed / no-op — RunCapture already reported
if (sampleId.empty())
{
// Capture failed or no-op'd — RunCapture already reported. Discard the empty point.
Undo_EndBlock2(nullptr, "", 0);
return;
}
// Assign inside the same block so undo clears both keys together.
reasampler::ingestAssignActiveInstance(g_session.book().activeBankId(), sampleId);
Undo_EndBlock2(nullptr, "ReaSampler: capture + assign to active instance",
UNDO_STATE_MISCCFG);
reasampler::bankPanelRefresh();
ShowConsoleMsg("ReaSampler ingest: captured into the bank and assigned to the active "
"instance.\n");