From 02dd7799396ebe3b5c3764796cfa3cbc72b72110 Mon Sep 17 00:00:00 2001 From: skal Date: Wed, 18 Feb 2026 15:39:33 +0100 Subject: fix(mq_editor): correct phaseInterp quadratic coefficient and stale phase prediction - phaseInterp: missing *0.5 on quadratic term made interpolated phase 2x off - trackPartials: phase advance now scaled by (age+1) to cover frames missed during a partial gap, preventing stale predictions after consecutive misses handoff(Claude): two bugs fixed in mq_extract.js phase tracking Co-Authored-By: Claude Sonnet 4.6 --- tools/mq_editor/mq_extract.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/mq_editor/mq_extract.js b/tools/mq_editor/mq_extract.js index a530960..c084b43 100644 --- a/tools/mq_editor/mq_extract.js +++ b/tools/mq_editor/mq_extract.js @@ -40,7 +40,7 @@ function phaseInterp(p_minus, p_center, p_plus, p_frac) { while (dp_plus > Math.PI) dp_plus -= 2 * Math.PI; while (dp_plus < -Math.PI) dp_plus += 2 * Math.PI; - const p_interp = p_center + (dp_plus - dp_minus) * p_frac * 0.5 + (dp_plus + dp_minus) * p_frac * p_frac; + const p_interp = p_center + (dp_plus - dp_minus) * p_frac * 0.5 + (dp_plus + dp_minus) * 0.5 * p_frac * p_frac; return p_interp; } @@ -130,7 +130,8 @@ function trackPartials(frames, params) { const predictedFreq = lastFreq + velocity; // Predict phase for the current frame based on the last frame's frequency. - const phaseAdvance = 2 * Math.PI * lastFreq * hopSize / sampleRate; + // Multiply by (age+1) to account for frames missed during a gap. + const phaseAdvance = 2 * Math.PI * lastFreq * (partial.age + 1) * hopSize / sampleRate; const predictedPhase = lastPhase + phaseAdvance; const tol = Math.max(predictedFreq * trackingRatio, minTrackingHz); @@ -170,6 +171,7 @@ function trackPartials(frames, params) { const velocity = cand.velocity || 0; const predictedFreq = lastFreq + velocity; + // Candidates die on first miss so age is always 0 here, but kept consistent. const phaseAdvance = 2 * Math.PI * lastFreq * hopSize / sampleRate; const predictedPhase = lastPhase + phaseAdvance; -- cgit v1.2.3