summaryrefslogtreecommitdiff
path: root/tools/editor/script.js
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-01-28 11:49:52 +0100
committerskal <pascal.massimino@gmail.com>2026-01-28 11:49:52 +0100
commit9b003f762f7fea313ecb3b2b17ef9446881d7a8c (patch)
tree59dd67a03a6bc8d0eaa9274f101799f10f68b060 /tools/editor/script.js
parent5434802315a2e2899a58f8f39437d078aae1d745 (diff)
docs: Finalize project state synchronization
Updates all relevant Markdown files to reflect the completed asset system and build pipeline. - Updates PROJECT_CONTEXT.md with latest architectural decisions. - Updates GEMINI.md with the full list of relevant files. - Adds initial scaffolding for the web editor. - Cleans up any lingering issues with asset generation paths.
Diffstat (limited to 'tools/editor/script.js')
-rw-r--r--tools/editor/script.js130
1 files changed, 122 insertions, 8 deletions
diff --git a/tools/editor/script.js b/tools/editor/script.js
index 9311d6d..45af325 100644
--- a/tools/editor/script.js
+++ b/tools/editor/script.js
@@ -1,11 +1,125 @@
// This is the core JavaScript for the Spectrogram Editor.
-// It handles file loading, visualization, tool interaction, and saving.
+// It handles file loading (.spec), visualization, tool interaction, and saving.
-// Placeholder for core functionality
-console.log("Spectrogram Editor script loaded.");
+// --- Global Variables ---
+let currentSpecData = null; // Stores the parsed spectrogram data
+let dctSize = 512; // Default DCT size, read from header
-// TODO: Implement WAV loading and spectrogram calculation
-// TODO: Implement canvas drawing and event handling for tools
-// TODO: Implement shape generation (strokes, ellipses, noise)
-// TODO: Implement JSON save/load functionality
-// TODO: Implement .spec export functionality
+// --- File Handling ---
+const specFileInput = document.getElementById('specFileInput');
+specFileInput.addEventListener('change', handleFileSelect);
+
+async function handleFileSelect(event) {
+ const file = event.target.files[0];
+ if (!file) {
+ return;
+ }
+
+ try {
+ const buffer = await file.arrayBuffer();
+ const dataView = new DataView(buffer);
+
+ // Parse SPEC header
+ const header = {
+ magic: String.fromCharCode(...new Uint8Array(buffer.slice(0, 4))),
+ version: dataView.getInt32(4, true),
+ dct_size: dataView.getInt32(8, true),
+ num_frames: dataView.getInt32(12, true)
+ };
+
+ if (header.magic !== "SPEC" || header.version !== 1) {
+ console.error("Invalid SPEC file format.");
+ alert("Invalid SPEC file format. Please load a valid .spec file.");
+ return;
+ }
+
+ dctSize = header.dct_size;
+ const dataStart = 16;
+ const numBytes = header.num_frames * header.dct_size * sizeof(float);
+ const spectralDataFloat = new Float32Array(buffer, dataStart, header.num_frames * header.dct_size);
+
+ currentSpecData = {
+ header: header,
+ data: spectralDataFloat
+ };
+
+ console.log("Loaded SPEC file:", header);
+ drawSpectrogram(currentSpecData);
+
+ } catch (error) {
+ console.error("Error loading SPEC file:", error);
+ alert("Failed to load SPEC file. Check console for details.");
+ }
+}
+
+// --- Spectrogram Visualization ---
+const canvas = document.getElementById('spectrogramCanvas');
+const ctx = canvas.getContext('2d');
+
+function drawSpectrogram(specData) {
+ if (!specData || !specData.data) {
+ console.warn("No spectrogram data to draw.");
+ return;
+ }
+
+ const width = canvas.width = window.innerWidth * 0.7; // Example dimensions
+ const height = canvas.height = 400; // Example dimensions
+
+ ctx.clearRect(0, 0, width, height);
+ ctx.fillStyle = '#ffffff';
+ ctx.fillRect(0, 0, width, height);
+
+ const numFrames = specData.header.num_frames;
+ const binsPerFrame = specData.data.length / numFrames;
+
+ if (numFrames === 0 || binsPerFrame === 0) {
+ console.warn("Spectrogram has no frames or invalid data.");
+ return;
+ }
+
+ // Simplified visualization: draw a few lines to represent frames
+ const frameWidth = width / numFrames;
+ ctx.strokeStyle = '#000000';
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+
+ // Draw a simplified representation of the first frame
+ const frameIndex = 0;
+ const frameDataStart = frameIndex * dctSize;
+ const maxVal = 1.0; // Assume normalization or known range for now
+
+ for (let i = 0; i < dctSize; ++i) {
+ const value = specData.data[frameDataStart + i];
+ const x = (i / dctSize) * width;
+ const y = height - (Math.abs(value) / maxVal) * height * 0.5; // Simplified scaling
+
+ if (i === 0) {
+ ctx.moveTo(x, y);
+ } else {
+ ctx.lineTo(x, y);
+ }
+ }
+ ctx.stroke();
+}
+
+// --- Tool Interactions ---
+const lineToolButton = document.getElementById('lineTool');
+const ellipseToolButton = document.getElementById('ellipseTool');
+const noiseToolButton = document.getElementById('noiseTool');
+
+lineToolButton.addEventListener('click', () => console.log('Line tool selected'));
+ellipseToolButton.addEventListener('click', () => console.log('Ellipse tool selected'));
+noiseToolButton.addEventListener('click', () => console.log('Noise tool selected'));
+
+// TODO: Implement canvas event listeners for drawing shapes
+// TODO: Implement shape parameter controls
+// TODO: Implement save/load JSON
+// TODO: Implement .spec export
+
+// Initial setup for canvas size (can be updated on window resize)
+window.addEventListener('resize', () => {
+ // Re-draw or re-initialize canvas size if needed
+ if (currentSpecData) {
+ drawSpectrogram(currentSpecData);
+ }
+}); \ No newline at end of file