summaryrefslogtreecommitdiff
path: root/tools/mq_editor
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-18 15:39:33 +0100
committerskal <pascal.massimino@gmail.com>2026-02-18 15:39:33 +0100
commit02dd7799396ebe3b5c3764796cfa3cbc72b72110 (patch)
tree054d928cdd7cd178bc5affc1b14156f60351a8f5 /tools/mq_editor
parenta9a60dfd2df938ef1e3ecc0a06d3d50cc329ef30 (diff)
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 <noreply@anthropic.com>
Diffstat (limited to 'tools/mq_editor')
-rw-r--r--tools/mq_editor/mq_extract.js6
1 files changed, 4 insertions, 2 deletions
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;