From 35ebfac6c860cc7de7db447b57158a7a3a27daaa Mon Sep 17 00:00:00 2001 From: skal Date: Wed, 18 Feb 2026 05:11:12 +0100 Subject: fix(mq_editor): Catmull-Rom bezier fit, NaN guard, synth FFT toggle - evalBezier: guard dt<=0 to avoid NaN on degenerate curves - fitBezier: replace nearest-neighbor control points with Catmull-Rom tangents (Hermite->Bezier), curve now passes through endpoints - key 'a': toggle mini-spectrum between original and synth FFT handoff(Claude): bezier fix + synth FFT comparison Co-Authored-By: Claude Sonnet 4.6 --- tools/mq_editor/index.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tools/mq_editor/index.html') diff --git a/tools/mq_editor/index.html b/tools/mq_editor/index.html index e8386c2..d7cec6a 100644 --- a/tools/mq_editor/index.html +++ b/tools/mq_editor/index.html @@ -315,6 +315,12 @@ setStatus(`Synthesizing ${keepCount}/${extractedPartials.length} partials (${keepPct.value}%)...`, 'info'); const pcm = synthesizeMQ(partialsToUse, sampleRate, duration); + // Build STFT cache for synth signal (for FFT comparison via key 'a') + if (viewer) { + const synthStft = new STFTCache(pcm, sampleRate, fftSize, parseInt(hopSize.value)); + viewer.setSynthStftCache(synthStft); + } + // Create audio buffer const synthBuffer = audioContext.createBuffer(1, pcm.length, sampleRate); synthBuffer.getChannelData(0).set(pcm); @@ -360,6 +366,12 @@ } else if (e.code === 'KeyP') { e.preventDefault(); if (viewer) viewer.togglePeaks(); + } else if (e.code === 'KeyA') { + e.preventDefault(); + if (viewer) { + viewer.showSynthFFT = !viewer.showSynthFFT; + viewer.renderSpectrum(); + } } }); -- cgit v1.2.3