fix: guard filter tail NaNs, skip static-filter envelope work, pin stereo filter path, correct stale comments
Codec fallback for non-finite filter fields, a modAmount==0 early-out in tickFilterCutoff, new stereo render tests for the dual-mono mirror, and comment/test accuracy fixes flagged in review (stale deck-width claims, restated invariants, drifted CMake link comments).
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -608,6 +609,30 @@ static void testFilterTailRoundTripsLosslessly() {
|
||||
reasampler::instrument::engine::VelocityCurve::flat()));
|
||||
}
|
||||
|
||||
// A non-finite modAmount/velAmount/keyTrack (a corrupt blob, or any writer that skipped the
|
||||
// same guard the v8 master gain already applies) must lift to the neutral default rather than
|
||||
// reach Voice::tickFilterCutoff, where both clamp compares are false against NaN and the
|
||||
// static_cast<int> is UB. Mirrors testCorruptFieldsFallBackToDefaults' per-field precedent.
|
||||
static void testNonFiniteFilterFieldsLiftToTheNeutralDefault() {
|
||||
ComponentState in;
|
||||
in.selectionId = "pad";
|
||||
FilterSeconds& f = in.params.play.filter;
|
||||
f.enabled = true;
|
||||
f.modAmount = std::numeric_limits<double>::quiet_NaN();
|
||||
f.velAmount = std::numeric_limits<double>::infinity();
|
||||
f.keyTrack = -std::numeric_limits<double>::infinity();
|
||||
|
||||
const ComponentState out =
|
||||
deserializeComponentState(serializeComponentState(in), 48000.0);
|
||||
const FilterSeconds& g = out.params.play.filter;
|
||||
const FilterSeconds def;
|
||||
CHECK(g.modAmount == def.modAmount);
|
||||
CHECK(g.velAmount == def.velAmount);
|
||||
CHECK(g.keyTrack == def.keyTrack);
|
||||
// The fallback is per-field, not per-record: the untouched fields still round-trip.
|
||||
CHECK(g.enabled);
|
||||
}
|
||||
|
||||
// The WRITER emits the CURRENT payload version, and the marker + version sit at the head of
|
||||
// the payload — the self-describing property every legacy branch depends on. Asserted
|
||||
// against the semantic constants, not literals.
|
||||
@@ -1080,6 +1105,7 @@ int main() {
|
||||
testTruncationDegradesCleanly();
|
||||
testV8RecordLiftsToTheOffNeutralFilter();
|
||||
testFilterTailRoundTripsLosslessly();
|
||||
testNonFiniteFilterFieldsLiftToTheNeutralDefault();
|
||||
if (failures == 0) {
|
||||
std::printf("component_state_io_tests: all tests passed\n");
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user