Fix M3 capture: render format, project rate, unsaved-project handling

RENDER_FORMAT now uses the base64 float-WAV config (raw bytes were rejected
into a 16-bit/44.1 fallback); RENDER_SRATE pinned to the project rate.
Unsaved projects prompt Save then refuse if cancelled — no default-location
fallback. Harden deriveBankPaths against empty projectDir.
This commit is contained in:
2026-07-22 17:02:15 -04:00
parent d60fe9ace3
commit a14d33aa75
4 changed files with 114 additions and 63 deletions
+13 -6
View File
@@ -67,13 +67,20 @@ static void testDeriveHandlesTrailingSlashProjectDir() {
CHECK(p.fileName == "mix_7.wav");
}
static void testDeriveEmptyProjectDirFallsBackToRelative() {
// Defensive: with no project dir, absoluteDir is just the bank subfolder
// (the shell rejects the no-path case before this, but the arithmetic must
// not emit a leading slash that would read as absolute).
static void testDeriveEmptyProjectDirIsRejected() {
// Precondition: deriveBankPaths requires a non-empty projectDir.
// In debug builds the assert(!dir.empty()) fires immediately and aborts
// the process — that IS the check, so we don't call into it there.
// In release/NDEBUG builds the assert is elided; we verify the fallback
// contract: absoluteDir is left empty (not a bare "reasampler_bank") so
// any caller that ignores the precondition fails loudly at the render/stat
// step rather than silently writing to CWD.
#ifdef NDEBUG
BankPaths p = deriveBankPaths("", "mix", "");
CHECK(p.absoluteDir == "reasampler_bank");
CHECK(p.absoluteDir.empty());
CHECK(p.relativePath == "reasampler_bank/mix.wav");
#endif
// Debug: assert fires on the call above — contract verified by the crash.
}
static void testDeterministicForSameInputs() {
@@ -108,7 +115,7 @@ int main() {
testDeriveRelativePathIsProjectRelative();
testDeriveAbsoluteDirJoinsProjectDir();
testDeriveHandlesTrailingSlashProjectDir();
testDeriveEmptyProjectDirFallsBackToRelative();
testDeriveEmptyProjectDirIsRejected();
testDeterministicForSameInputs();
testFileStem();