Restore the bank fold and usage publish to the resume path, guard setActive against repeats, and make the meter fold's bound literal

The resume also hands back to a full reload when the fold moves the loaded capture's decode source, so the refs table and the audio cannot skew.
This commit is contained in:
2026-08-02 13:15:47 -04:00
parent 5c6525fb91
commit da14509ab5
15 changed files with 218 additions and 76 deletions
+38
View File
@@ -531,6 +531,43 @@ static void testRefreshRefsFromBankUpsertAndOwnership() {
CHECK(refs.size() == 1 && refs[0].ref.rootNote == 40);
}
static void testSameDecodeSourceTracksEveryDecodeInput() {
// The predicate a resumed (already-decoded) instrument is gated on: every field that
// changes what buildSampleData produces must read as different, and the display-only
// name must not.
SelectedSample a;
a.relativePath = "b/a.wav";
a.rootNote = 36;
a.channelCount = 2;
a.loop.hasLoop = true;
a.loop.start = 100;
a.loop.end = 900;
CHECK(sameDecodeSource(a, a));
SelectedSample recaptured = a;
recaptured.relativePath = "b/a2.wav"; // the recapture case: a new file behind one id
CHECK(!sameDecodeSource(a, recaptured));
SelectedSample reRooted = a;
reRooted.rootNote = 40;
CHECK(!sameDecodeSource(a, reRooted));
SelectedSample reChanneled = a;
reChanneled.channelCount = 1; // drives the channel-mode auto-default, hence the decode
CHECK(!sameDecodeSource(a, reChanneled));
SelectedSample loopOff = a;
loopOff.loop.hasLoop = false;
CHECK(!sameDecodeSource(a, loopOff));
SelectedSample loopMoved = a;
loopMoved.loop.start = 101;
CHECK(!sameDecodeSource(a, loopMoved));
loopMoved = a;
loopMoved.loop.end = 901;
CHECK(!sameDecodeSource(a, loopMoved));
}
static void testRetainRefsFiltersToPlayedSet() {
// getState hygiene: only the entries the instance currently plays persist — the table
// cannot grow with browsing history. Order of survivors is preserved.
@@ -1015,6 +1052,7 @@ int main() {
testReferencedSampleIdsIsTheLoadedCapture();
testFindRefLooksUpTheOwnedCopy();
testRefreshRefsFromBankUpsertAndOwnership();
testSameDecodeSourceTracksEveryDecodeInput();
testRetainRefsFiltersToPlayedSet();
testLegacyLiftDecision();
testResolvePlayConvertsWallClockAtTheRate();