summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/mq_editor/index.html56
1 files changed, 38 insertions, 18 deletions
diff --git a/tools/mq_editor/index.html b/tools/mq_editor/index.html
index d7cec6a..1ebc0d3 100644
--- a/tools/mq_editor/index.html
+++ b/tools/mq_editor/index.html
@@ -73,6 +73,7 @@
<div class="toolbar">
<input type="file" id="wavFile" accept=".wav">
+ <button id="testWavBtn">⚗ Test WAV</button>
<button id="extractBtn" disabled>Extract Partials</button>
<button id="playBtn" disabled>▶ Play</button>
<button id="stopBtn" disabled>■ Stop</button>
@@ -142,6 +143,22 @@
}
}
+ // Shared: initialize editor from an AudioBuffer
+ function loadAudioBuffer(buffer, label) {
+ audioBuffer = buffer;
+ initAudioContext();
+ extractBtn.disabled = false;
+ playBtn.disabled = false;
+ setStatus('Computing STFT cache...', 'info');
+
+ setTimeout(() => {
+ const signal = audioBuffer.getChannelData(0);
+ stftCache = new STFTCache(signal, audioBuffer.sampleRate, fftSize, parseInt(hopSize.value));
+ setStatus(`${label} — ${audioBuffer.duration.toFixed(2)}s, ${audioBuffer.sampleRate}Hz, ${audioBuffer.numberOfChannels}ch (${stftCache.getNumFrames()} frames cached)`, 'info');
+ viewer = new SpectrogramViewer(canvas, audioBuffer, stftCache);
+ }, 10);
+ }
+
// Load WAV file
wavFile.addEventListener('change', async (e) => {
const file = e.target.files[0];
@@ -150,30 +167,33 @@
setStatus('Loading WAV...', 'info');
try {
const arrayBuffer = await file.arrayBuffer();
- const audioContext = new AudioContext();
- audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
-
- initAudioContext();
- extractBtn.disabled = false;
- playBtn.disabled = false;
- setStatus('Computing STFT cache...', 'info');
-
- // Compute STFT cache
- setTimeout(() => {
- const signal = audioBuffer.getChannelData(0);
- stftCache = new STFTCache(signal, audioBuffer.sampleRate, fftSize, parseInt(hopSize.value));
-
- setStatus(`Loaded: ${audioBuffer.duration.toFixed(2)}s, ${audioBuffer.sampleRate}Hz, ${audioBuffer.numberOfChannels}ch (${stftCache.getNumFrames()} frames cached)`, 'info');
-
- // Create viewer with cache
- viewer = new SpectrogramViewer(canvas, audioBuffer, stftCache);
- }, 10);
+ const ctx = new AudioContext();
+ const buf = await ctx.decodeAudioData(arrayBuffer);
+ loadAudioBuffer(buf, `Loaded: ${file.name}`);
} catch (err) {
setStatus('Error loading WAV: ' + err.message, 'error');
console.error(err);
}
});
+ // Test WAV: generate synthetic signal (two sine waves) in-memory
+ document.getElementById('testWavBtn').addEventListener('click', () => {
+ initAudioContext();
+ const SR = 32000;
+ const duration = 2.0;
+ const numSamples = SR * duration;
+
+ // Two sine waves: 440 Hz (A4) + 660 Hz (E5, perfect fifth), equal amplitude
+ const buf = audioContext.createBuffer(1, numSamples, SR);
+ const data = buf.getChannelData(0);
+ for (let i = 0; i < numSamples; ++i) {
+ data[i] = 0.5 * Math.sin(2 * Math.PI * 440 * i / SR)
+ + 0.5 * Math.sin(2 * Math.PI * 660 * i / SR);
+ }
+
+ loadAudioBuffer(buf, 'Test WAV: 440Hz + 660Hz (2s, 32kHz)');
+ });
+
// Update cache when hop size changes
hopSize.addEventListener('change', () => {
if (stftCache) {