summaryrefslogtreecommitdiff
path: root/tools/mq_editor/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mq_editor/index.html')
-rw-r--r--tools/mq_editor/index.html111
1 files changed, 37 insertions, 74 deletions
diff --git a/tools/mq_editor/index.html b/tools/mq_editor/index.html
index 345d2b9..60076b3 100644
--- a/tools/mq_editor/index.html
+++ b/tools/mq_editor/index.html
@@ -140,8 +140,8 @@
<canvas id="cursorCanvas" width="1400" height="600" style="position:absolute;top:0;left:0;pointer-events:none;"></canvas>
<!-- Mini spectrum viewer (bottom-right overlay) -->
- <div id="spectrumViewer" style="position: absolute; bottom: 10px; right: 10px; width: 200px; height: 100px; background: rgba(30, 30, 30, 0.9); border: 1px solid #555; border-radius: 3px; pointer-events: none;">
- <canvas id="spectrumCanvas" width="200" height="100"></canvas>
+ <div id="spectrumViewer" style="position: absolute; bottom: 10px; right: 10px; width: 400px; height: 100px; background: rgba(30, 30, 30, 0.9); border: 1px solid #555; border-radius: 3px; pointer-events: none;">
+ <canvas id="spectrumCanvas" width="400" height="100"></canvas>
</div>
</div>
@@ -184,11 +184,13 @@
const keepPctLabel = document.getElementById('keepPctLabel');
const fftSize = 1024; // Fixed
+ function getKeepCount() {
+ return Math.max(1, Math.ceil(extractedPartials.length * parseInt(keepPct.value) / 100));
+ }
+
keepPct.addEventListener('input', () => {
keepPctLabel.textContent = keepPct.value + '%';
- if (viewer && extractedPartials) {
- viewer.setKeepCount(Math.max(1, Math.ceil(extractedPartials.length * parseInt(keepPct.value) / 100)));
- }
+ if (viewer && extractedPartials) viewer.setKeepCount(getKeepCount());
});
// Initialize audio context
@@ -297,7 +299,7 @@
viewer.setFrames(result.frames);
setStatus(`Extracted ${result.partials.length} partials`, 'info');
viewer.setPartials(result.partials);
- viewer.setKeepCount(Math.max(1, Math.ceil(result.partials.length * parseInt(keepPct.value) / 100)));
+ viewer.setKeepCount(getKeepCount());
} catch (err) {
setStatus('Extraction error: ' + err.message, 'error');
@@ -317,18 +319,12 @@
if (stftCache) runExtraction();
});
- // Play audio
- playBtn.addEventListener('click', () => {
- if (!audioBuffer || !audioContext) return;
-
- stopAudio();
-
+ function playAudioBuffer(buffer, statusMsg) {
const startTime = audioContext.currentTime;
currentSource = audioContext.createBufferSource();
- currentSource.buffer = audioBuffer;
+ currentSource.buffer = buffer;
currentSource.connect(audioContext.destination);
currentSource.start();
-
currentSource.onended = () => {
currentSource = null;
playBtn.disabled = false;
@@ -336,43 +332,40 @@
viewer.setPlayheadTime(-1);
setStatus('Stopped', 'info');
};
-
playBtn.disabled = true;
stopBtn.disabled = false;
- setStatus('Playing...', 'info');
-
- // Animate playhead
- function updatePlayhead() {
+ setStatus(statusMsg, 'info');
+ function tick() {
if (!currentSource) return;
- const elapsed = audioContext.currentTime - startTime;
- viewer.setPlayheadTime(elapsed);
- requestAnimationFrame(updatePlayhead);
+ viewer.setPlayheadTime(audioContext.currentTime - startTime);
+ requestAnimationFrame(tick);
}
- updatePlayhead();
- });
-
- // Stop audio
- stopBtn.addEventListener('click', () => {
- stopAudio();
- });
+ tick();
+ }
function stopAudio() {
if (currentSource) {
- try {
- currentSource.stop();
- } catch (e) {
- // Already stopped
- }
+ try { currentSource.stop(); } catch (e) {}
currentSource = null;
}
- if (viewer) {
- viewer.setPlayheadTime(-1);
- }
+ if (viewer) viewer.setPlayheadTime(-1);
playBtn.disabled = false;
stopBtn.disabled = true;
setStatus('Stopped', 'info');
}
+ // Play audio
+ playBtn.addEventListener('click', () => {
+ if (!audioBuffer || !audioContext) return;
+ stopAudio();
+ playAudioBuffer(audioBuffer, 'Playing...');
+ });
+
+ // Stop audio
+ stopBtn.addEventListener('click', () => {
+ stopAudio();
+ });
+
function setStatus(msg, type = '') {
status.innerHTML = msg;
status.className = type;
@@ -390,53 +383,23 @@
setStatus('Synthesizing...', 'info');
- // Synthesize PCM from top-N% partials by amplitude
- const sampleRate = audioBuffer.sampleRate;
- const duration = audioBuffer.duration;
- const keepCount = Math.max(1, Math.ceil(extractedPartials.length * parseInt(keepPct.value) / 100));
+ const keepCount = getKeepCount();
const partialsToUse = extractedPartials.slice(0, keepCount);
setStatus(`Synthesizing ${keepCount}/${extractedPartials.length} partials (${keepPct.value}%)...`, 'info');
+
const integratePhase = document.getElementById('integratePhase').checked;
const disableJitter = document.getElementById('disableJitter').checked;
const disableSpread = document.getElementById('disableSpread').checked;
- const pcm = synthesizeMQ(partialsToUse, sampleRate, duration, integratePhase, {disableJitter, disableSpread});
+ const pcm = synthesizeMQ(partialsToUse, audioBuffer.sampleRate, audioBuffer.duration,
+ integratePhase, {disableJitter, disableSpread});
- // 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);
+ viewer.setSynthStftCache(new STFTCache(pcm, audioBuffer.sampleRate, fftSize, parseInt(hopSize.value)));
}
- // Create audio buffer
- const synthBuffer = audioContext.createBuffer(1, pcm.length, sampleRate);
+ const synthBuffer = audioContext.createBuffer(1, pcm.length, audioBuffer.sampleRate);
synthBuffer.getChannelData(0).set(pcm);
-
- const startTime = audioContext.currentTime;
- currentSource = audioContext.createBufferSource();
- currentSource.buffer = synthBuffer;
- currentSource.connect(audioContext.destination);
- currentSource.start();
-
- currentSource.onended = () => {
- currentSource = null;
- playBtn.disabled = false;
- stopBtn.disabled = true;
- viewer.setPlayheadTime(-1);
- setStatus('Stopped', 'info');
- };
-
- playBtn.disabled = true;
- stopBtn.disabled = false;
- setStatus(`Playing synthesized (${keepCount}/${extractedPartials.length} partials, ${keepPct.value}%)...`, 'info');
-
- // Animate playhead
- function updatePlayhead() {
- if (!currentSource) return;
- const elapsed = audioContext.currentTime - startTime;
- viewer.setPlayheadTime(elapsed);
- requestAnimationFrame(updatePlayhead);
- }
- updatePlayhead();
+ playAudioBuffer(synthBuffer, `Playing synthesized (${keepCount}/${extractedPartials.length} partials, ${keepPct.value}%)...`);
}
// Keyboard shortcuts