summaryrefslogtreecommitdiff
path: root/tools/mq_editor/editor.js
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-18 10:51:25 +0100
committerskal <pascal.massimino@gmail.com>2026-02-18 10:51:25 +0100
commitf8f664964594a341884b2e9947f64feea4b925a6 (patch)
tree4ac77ce036b188d5a374267c886a17f3366e1455 /tools/mq_editor/editor.js
parent78faa77b208d20c01c242a942a1ddf9278f4ef17 (diff)
feat(mq_editor): spread autodetection, 50% drop-off line, mini-spectrum peak fix
- autodetectSpread(): measures half-power (-3dB) peak width in spectrogram to infer spread_above/below (replaces near-zero bezier residual approach) - 'Auto' button per partial + 'Auto Spread All' toolbar button - Spread panel inputs now trigger viewer refresh on change - 50% drop-off dotted reference lines on spread band (selected partial only) - Mini-spectrum: use max() instead of mean() over bins per pixel column, fixing high-frequency amplitude mismatch between original and synthesis handoff(Gemini): spread autodetection and mini-spectrum fixes done
Diffstat (limited to 'tools/mq_editor/editor.js')
-rw-r--r--tools/mq_editor/editor.js25
1 files changed, 25 insertions, 0 deletions
diff --git a/tools/mq_editor/editor.js b/tools/mq_editor/editor.js
index 441f787..9cfcdf1 100644
--- a/tools/mq_editor/editor.js
+++ b/tools/mq_editor/editor.js
@@ -126,6 +126,7 @@ class PartialEditor {
{ key: 'spread_above', label: 'spread ↑', step: '0.001' },
{ key: 'spread_below', label: 'spread ↓', step: '0.001' },
];
+ const inputs = {};
for (const p of params) {
const val = rep[p.key] != null ? rep[p.key] : defaults[p.key];
const lbl = document.createElement('span');
@@ -142,10 +143,34 @@ class PartialEditor {
if (!this.partials[index].replicas)
this.partials[index].replicas = { ...defaults };
this.partials[index].replicas[p.key] = v;
+ if (this.viewer) this.viewer.render();
});
+ inputs[p.key] = inp;
grid.appendChild(lbl);
grid.appendChild(inp);
}
+
+ // Auto-detect spread button
+ const autoLbl = document.createElement('span');
+ autoLbl.textContent = 'spread';
+ const autoBtn = document.createElement('button');
+ autoBtn.textContent = 'Auto';
+ autoBtn.title = 'Infer spread_above/below from frequency variance around the bezier curve';
+ autoBtn.addEventListener('click', () => {
+ if (!this.partials) return;
+ const p = this.partials[index];
+ const sc = this.viewer ? this.viewer.stftCache : null;
+ const sr = this.viewer ? this.viewer.audioBuffer.sampleRate : 44100;
+ const fs = sc ? sc.fftSize : 2048;
+ const {spread_above, spread_below} = autodetectSpread(p, sc, fs, sr);
+ if (!p.replicas) p.replicas = { ...defaults };
+ p.replicas.spread_above = spread_above;
+ p.replicas.spread_below = spread_below;
+ inputs['spread_above'].value = spread_above.toFixed(4);
+ inputs['spread_below'].value = spread_below.toFixed(4);
+ });
+ grid.appendChild(autoLbl);
+ grid.appendChild(autoBtn);
}
_makeCurveUpdater(partialIndex, curveKey, field, pointIndex) {