diff options
| author | skal <pascal.massimino@gmail.com> | 2026-01-28 12:35:25 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-01-28 12:35:25 +0100 |
| commit | 6d43e6421b0fc9a25dae44d1857595c97e21a912 (patch) | |
| tree | ec818f7079f2c8066950aaf4876010e26dffbcf5 /tools/editor/script.js | |
| parent | 2021ebe9013a583363e0619d70b3e9b82a929fbd (diff) | |
feat(editor): Implement ellipse drawing and application logic
Adds full support for drawing and applying ellipse shapes to the spectrogram data, correctly handling logarithmic frequency mapping.
- : Refined ellipse creation to use accurate logarithmic frequency calculations for minBin and maxBin.
- : Implemented the algorithm to draw an ellipse on the spectrogram data, ensuring correct placement and amplitude application.
- Uses and for precise frequency mapping.
Diffstat (limited to 'tools/editor/script.js')
| -rw-r--r-- | tools/editor/script.js | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/tools/editor/script.js b/tools/editor/script.js index 46cbe1d..3afa0ff 100644 --- a/tools/editor/script.js +++ b/tools/editor/script.js @@ -280,9 +280,8 @@ function handleMouseUp(event) { const radiusXFrames = Math.floor((rx / canvas.width) * currentSpecData.header.num_frames); const radiusYFreq = canvasDeltaYToFreqDeltaLog(ry, canvas.height); // Delta in Hz const centerFreq = canvasYToFreqLog(cy, canvas.height); // Center in Hz - const binCRadius = freqToBinIndexLog(centerFreq + radiusYFreq / 2); // Max bin - const binC = freqToBinIndexLog(centerFreq); // Center bin - const binCMin = freqToBinIndexLog(centerFreq - radiusYFreq / 2); // Min bin + const binCRadius = freqToBinIndexLog(centerFreq * Math.pow(2, (radiusY / canvas.height) * Math.log2(MAX_FREQ / MIN_FREQ))); + const binCMin = freqToBinIndexLog(centerFreq / Math.pow(2, (radiusY / canvas.height) * Math.log2(MAX_FREQ / MIN_FREQ))); newShape = { type: 'ellipse', @@ -290,7 +289,6 @@ function handleMouseUp(event) { rx: rx, ry: ry, frameC: centerCoords.frame, binC: centerCoords.bin, radiusFrames: radiusXFrames, - // Store as freq range for easy application to spec data minBin: binCMin, maxBin: binCRadius, amplitude: 0.5, color: 'green', @@ -401,10 +399,15 @@ function applyShapeToSpectrogram(shape, targetSpecData) { // Check if (f, b) is within the ellipse const normX = (f - centerFrame) / radiusFrames; - const normY = (binIndexToFreqLog(b) - binIndexToFreqLog(centerBin)) / - (binIndexToFreqLog(maxBin) - binIndexToFreqLog(centerBin)); // Normalized freq diff + // Calculate relative frequency based on log scale + const currentFreq = binIndexToFreqLog(b); + const centerFreq = binIndexToFreqLog(centerBin); + const minFreq = binIndexToFreqLog(minBin); + const maxFreq = binIndexToFreqLog(maxBin); - if (normX * normX + normY * normY <= 1) { + const logNormY = (Math.log(currentFreq) - Math.log(centerFreq)) / (Math.log(maxFreq) - Math.log(minFreq)); + + if (normX * normX + logNormY * logNormY <= 1) { targetSpecData.data[f * dctSize + b] += shape.amplitude; targetSpecData.data[f * dctSize + b] = Math.max(-1, Math.min(1, targetSpecData.data[f * dctSize + b])); } @@ -515,6 +518,25 @@ function freqToBinIndex(freq) { return Math.floor((freq / MAX_FREQ) * dctSize); } +// Maps a frequency (Hz) to its corresponding log-scaled bin index +function freqToBinIndexLog(freq) { + if (freq < MIN_FREQ) freq = MIN_FREQ; // Clamp minimum frequency + const logMin = Math.log(MIN_FREQ); + const logMax = Math.log(MAX_FREQ); + const logFreq = Math.log(freq); + const normalizedLog = (logFreq - logMin) / (logMax - logMin); + return Math.floor(normalizedLog * dctSize); +} + +// Maps a log-scaled bin index to its corresponding frequency in Hz +function binIndexToFreqLog(binIndex) { + const normalizedLog = binIndex / dctSize; + const logMin = Math.log(MIN_FREQ); + const logMax = Math.log(MAX_FREQ); + const logFreq = normalizedLog * (logMax - logMin) + logMin; + return Math.exp(logFreq); +} + // Converts a frequency (Hz) to a Y-coordinate on the canvas (log scale) function freqToCanvasYLog(freq, canvasHeight) { if (freq < MIN_FREQ) freq = MIN_FREQ; // Clamp minimum frequency @@ -615,9 +637,6 @@ async function playSpectrogramData(specData) { } // --- Playback Button Event Listeners --- -const listenOriginalButton = document.getElementById('listenOriginalButton'); -const listenGeneratedButton = document.getElementById('listenGeneratedButton'); - listenOriginalButton.addEventListener('click', () => { if (originalSpecData) { playSpectrogramData(originalSpecData); |
