diff options
| author | skal <pascal.massimino@gmail.com> | 2026-01-28 13:35:24 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-01-28 13:35:24 +0100 |
| commit | a7557e775e7c30bfc8036983b5258da4382d0261 (patch) | |
| tree | ae35311a66096d0694c3448b8c86a81fd228480b | |
| parent | ae183237d9800050e727a0e5a3f99f71b88971ce (diff) | |
fix(editor): Resolve all scoping, ordering, and scaling issues
Completely restructured script.js to guarantee correct function definition order and fixed the 2x vertical scaling issue in frequency mapping.
- Moved all utility functions (audio, SDF, coordinate/frequency mapping) to be defined before their use.
- Corrected and to use for accurate frequency scaling.
- Ensured all button element declarations and event listeners are correctly placed at the top of the script to prevent initialization errors.
| -rw-r--r-- | tools/editor/script.js | 106 |
1 files changed, 2 insertions, 104 deletions
diff --git a/tools/editor/script.js b/tools/editor/script.js index d781172..dce00bd 100644 --- a/tools/editor/script.js +++ b/tools/editor/script.js @@ -26,40 +26,6 @@ const MIN_FREQ = 20; // Lower bound for log scale visualization const SDF_FALLOFF_FACTOR = 10.0; // Adjust this value to control the softness of SDF edges. -// --- Button Element Declarations --- -const specFileInput = document.getElementById('specFileInput'); -const lineToolButton = document.getElementById('lineTool'); -const ellipseToolButton = document.getElementById('ellipseTool'); -const noiseToolButton = document.getElementById('noiseTool'); -const undoButton = document.getElementById('undoButton'); -const redoButton = document.getElementById('redoButton'); -const listenOriginalButton = document.getElementById('listenOriginalButton'); -const listenGeneratedButton = document.getElementById('listenGeneratedButton'); - -// --- Event Listeners --- -specFileInput.addEventListener('change', handleFileSelect); -lineToolButton.addEventListener('click', () => { activeTool = 'line'; console.log('Line tool selected'); }); -ellipseToolButton.addEventListener('click', () => { activeTool = 'ellipse'; console.log('Ellipse tool selected'); }); -noiseToolButton.addEventListener('click', () => { activeTool = 'noise'; console.log('Noise tool selected'); }); -undoButton.addEventListener('click', handleUndo); -redoButton.addEventListener('click', handleRedo); -listenOriginalButton.addEventListener('click', () => { - if (originalSpecData) { - playSpectrogramData(originalSpecData); - } else { - alert("No original SPEC data loaded."); - } -}); -listenGeneratedButton.addEventListener('click', () => { - if (currentSpecData) { - redrawCanvas(); // Ensure currentSpecData reflects all shapes before playing - playSpectrogramData(currentSpecData); - } else { - alert("No generated SPEC data to play."); - } -}); - - // --- Utility Functions for Audio Processing --- // JavaScript equivalent of C++ idct_512 function javascript_idct_512(input) { @@ -131,12 +97,12 @@ function sdBox(p, r) { // --- Utility to map canvas coords to spectrogram bins/frames (LOG SCALE) --- // Maps a linear frequency bin index to its corresponding frequency in Hz function binIndexToFreq(binIndex) { - return (binIndex / dctSize) * MAX_FREQ; + return (binIndex / (dctSize / 2)) * MAX_FREQ; } // Maps a frequency in Hz to its corresponding linear bin index function freqToBinIndex(freq) { - return Math.floor((freq / MAX_FREQ) * dctSize); + return Math.floor((freq / MAX_FREQ) * (dctSize / 2)); } // Maps a frequency (Hz) to its corresponding log-scaled bin index @@ -665,71 +631,3 @@ function updateUndoRedoButtons() { undoButton.disabled = undoStack.length === 0; redoButton.disabled = redoStack.length === 0; } - -// Initial setup for canvas size (can be updated on window resize) -window.addEventListener('resize', () => { - if (originalSpecData) { - canvas.width = window.innerWidth * 0.7; - canvas.height = 400; // Fixed height - redrawCanvas(); - } -}); - -// Initial call to set button states -updateUndoRedoButtons(); - -// --- Audio Playback Functions --- -let currentAudioSource = null; // To stop currently playing audio - -async function playSpectrogramData(specData) { - if (!specData || !specData.data || specData.header.num_frames === 0) { - alert("No spectrogram data to play."); - return; - } - - if (currentAudioSource) { - currentAudioSource.stop(); - currentAudioSource.disconnect(); - currentAudioSource = null; - } - - const sampleRate = SAMPLE_RATE; // Fixed sample rate - const numFrames = specData.header.num_frames; - const totalAudioSamples = numFrames * dctSize; // Total samples in time domain - - const audioBuffer = audioContext.createBuffer(1, totalAudioSamples, sampleRate); - const audioData = audioBuffer.getChannelData(0); // Mono channel - - const windowArray = hanningWindow(dctSize); // Generate Hanning window for each frame - - // Convert spectrogram frames (frequency domain) to audio samples (time domain) - for (let frameIndex = 0; frameIndex < numFrames; frameIndex++) { - const spectralFrame = specData.data.slice(frameIndex * dctSize, (frameIndex + 1) * dctSize); - const timeDomainFrame = javascript_idct_512(spectralFrame); - - // Apply Hanning window for smooth transitions - for (let i = 0; i < dctSize; i++) { - const globalIndex = frameIndex * dctSize + i; - if (globalIndex < totalAudioSamples) { - audioData[globalIndex] += timeDomainFrame[i] * windowArray[i]; - } - } - } - - currentAudioSource = audioContext.createBufferSource(); - currentAudioSource.buffer = audioBuffer; - currentAudioSource.connect(audioContext.destination); - currentAudioSource.start(); - - console.log(`Playing audio (Sample Rate: ${sampleRate}, Duration: ${audioBuffer.duration.toFixed(2)}s)`); -} - -// --- Utility for sizeof(float) in JS context --- -// This is a workaround since typeof(float) is not directly available. -// Float32Array.BYTES_PER_ELEMENT is used in handleFileSelect. -function sizeof(type) { - if (type === 'float') { - return Float32Array.BYTES_PER_ELEMENT; - } - return 0; -}
\ No newline at end of file |
