Close derived-bake-window review findings: NaN-guard remaining wire doubles, pin Trigger-span agreement, retire dead quantizer
Guards params_payload.cpp's filter-tail seconds and both keyTrack sites against NaN; pins Voice::start's Trigger-span formula against trigger_seam; retires unused shortestDivisionAtLeast.
This commit is contained in:
@@ -244,6 +244,7 @@ void readBakeHold(ByteReader& r, InstrumentParams& p) {
|
||||
// bipolar at EVERY version — a pre-v12 blob's y values are already valid bipolar ones, so its
|
||||
// v12 domain re-tag needs no version branch (see component_state_io.h).
|
||||
void readFilterTail(ByteReader& r, InstrumentParams& p) {
|
||||
const FilterSeconds fallback; // the construction defaults, read rather than restated
|
||||
FilterSeconds& f = p.play.filter;
|
||||
f.enabled = (r.u8() != 0);
|
||||
f.settings.cutoffNorm = static_cast<float>(bitsToDouble(r.u64()));
|
||||
@@ -260,11 +261,11 @@ void readFilterTail(ByteReader& r, InstrumentParams& p) {
|
||||
f.modAmount = std::isfinite(modAmount) ? modAmount : 0.0;
|
||||
f.velAmount = std::isfinite(velAmount) ? velAmount : 0.0;
|
||||
f.keyTrack = std::isfinite(keyTrack) ? keyTrack : 0.0;
|
||||
f.env.attackSeconds = bitsToDouble(r.u64());
|
||||
f.env.holdSeconds = bitsToDouble(r.u64());
|
||||
f.env.decaySeconds = bitsToDouble(r.u64());
|
||||
f.env.sustainLevel = bitsToDouble(r.u64());
|
||||
f.env.releaseSeconds = bitsToDouble(r.u64());
|
||||
f.env.attackSeconds = finiteOr(bitsToDouble(r.u64()), fallback.env.attackSeconds);
|
||||
f.env.holdSeconds = finiteOr(bitsToDouble(r.u64()), fallback.env.holdSeconds);
|
||||
f.env.decaySeconds = finiteOr(bitsToDouble(r.u64()), fallback.env.decaySeconds);
|
||||
f.env.sustainLevel = finiteOr(bitsToDouble(r.u64()), fallback.env.sustainLevel);
|
||||
f.env.releaseSeconds = finiteOr(bitsToDouble(r.u64()), fallback.env.releaseSeconds);
|
||||
readCurveTail(r, f.velocityCurve, reasampler::instrument::engine::CurveDomain::Bipolar);
|
||||
}
|
||||
|
||||
@@ -371,8 +372,10 @@ PayloadRead readLegacyZonePayload(ByteReader& r, std::uint32_t pv, double projec
|
||||
readSecondsPlayTail(r, p, projectRate);
|
||||
}
|
||||
// A pre-v6 payload leaves keyTrack = 1.0 (100% ET), so an already-saved instance
|
||||
// repitches BIT-IDENTICALLY. A pre-v7 payload leaves VelocityCurve::flat().
|
||||
if (keyTrackTail) p.keyTrack = bitsToDouble(r.u64());
|
||||
// repitches BIT-IDENTICALLY. A pre-v7 payload leaves VelocityCurve::flat(). A NaN
|
||||
// reaches keyTrackedRatio -> baseRatio_ -> readPos_'s per-sample cast (voice.h) — the
|
||||
// same guard the v8+ single-record reader applies to its own keyTrack below.
|
||||
if (keyTrackTail) p.keyTrack = finiteOr(bitsToDouble(r.u64()), InstrumentParams{}.keyTrack);
|
||||
if (curveTail) {
|
||||
readCurveTail(r, p.velocityCurve,
|
||||
reasampler::instrument::engine::CurveDomain::Unipolar);
|
||||
@@ -500,7 +503,10 @@ PayloadRead readParamsPayload(ByteReader& r, double projectRate) {
|
||||
const std::uint8_t hasStart = r.u8();
|
||||
if (hasStart) p.startPoint = r.i64();
|
||||
readSecondsPlayTail(r, p, projectRate);
|
||||
p.keyTrack = bitsToDouble(r.u64());
|
||||
// NaN reaches keyTrackedRatio (voice.h) -> baseRatio_ -> readPos_'s per-sample
|
||||
// static_cast<std::int64_t> — UB on the per-sample path. Guarded here, codec-side, so
|
||||
// that path needs no check of its own.
|
||||
p.keyTrack = finiteOr(bitsToDouble(r.u64()), InstrumentParams{}.keyTrack);
|
||||
readCurveTail(r, p.velocityCurve, reasampler::instrument::engine::CurveDomain::Unipolar);
|
||||
if (pv >= kParamsFilterVersion) readFilterTail(r, p);
|
||||
if (pv >= kParamsCurveVersion) readCurveStageTail(r, p);
|
||||
|
||||
Reference in New Issue
Block a user