summaryrefslogtreecommitdiff
path: root/tools/spectral_editor/index.html
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-06 13:36:19 +0100
committerskal <pascal.massimino@gmail.com>2026-02-06 13:36:19 +0100
commita0888c1afa8bf178b7a57d4e80373ad867a3474a (patch)
treeec7c4526d41e08c629c2e88115071b1614dbae34 /tools/spectral_editor/index.html
parent3002553be5bf880ead27fb3e415bc97d484b43eb (diff)
feat(spectral_editor): Complete Phase 2 milestone - Full-featured web editor
MILESTONE: Spectral Brush Editor Phase 2 Complete (February 6, 2026) Phase 2 delivers a production-ready web-based editor for creating procedural audio by tracing spectrograms with parametric Bezier curves. This tool enables replacing 5KB .spec binary assets with ~100 bytes of C++ code (50-100× compression). Core Features Implemented: ======================== Audio I/O: - Load .wav and .spec files as reference spectrograms - Real-time audio preview (procedural vs original) - Live volume control with GainNode (updates during playback) - Export to procedural_params.txt (human-readable, re-editable format) - Generate C++ code (copy-paste ready for demo integration) Curve Editing: - Multi-curve support with individual colors and volumes - Bezier curve control points (frame, frequency, amplitude) - Drag-and-drop control point editing - Per-curve volume control (0-100%) - Right-click to delete control points - Curves only render within control point range (no spill) Profile System (All 3 types implemented): - Gaussian: exp(-(dist² / σ²)) - smooth harmonic falloff - Decaying Sinusoid: exp(-decay × dist) × cos(ω × dist) - metallic resonance - Noise: noise × exp(-(dist² / decay²)) - textured grit with decay envelope Visualization: - Log-scale frequency axis (20 Hz to 16 kHz) for better bass visibility - Logarithmic dB-scale intensity mapping (-60 dB to +40 dB range) - Reference opacity slider (0-100%) for mixing original/procedural views - Playhead indicator (red dashed line) during playback - Mouse crosshair with tooltip (frame number, frequency) - Control point info panel (frame, frequency, amplitude) Real-time Spectrum Viewer (NEW): - Always-visible bottom-right overlay (200×100px) - Shows frequency spectrum for frame under mouse (hover mode) - Shows current playback frame spectrum (playback mode) - Dual display: Reference (green) + Procedural (red) overlaid - dB-scale bar heights for accurate visualization - Frame number label (red during playback, gray when hovering) Rendering Architecture: - Destination-to-source pixel mapping (prevents gaps in log-scale) - Offscreen canvas compositing for proper alpha blending - Alpha channel for procedural intensity (pure colors, not dimmed) - Steeper dB falloff for procedural curves (-40 dB floor vs -60 dB reference) UI/UX: - Undo/Redo system (50-action history) - Keyboard shortcuts (1/2/Space for playback, Ctrl+Z/Ctrl+Shift+Z, Delete, Esc) - File load confirmation (warns about unsaved curves) - Automatic curve reset on new file load Technical Details: - DCT/IDCT implementation (JavaScript port matching C++ runtime) - Overlap-add synthesis with Hanning window - Web Audio API integration (32 kHz sample rate) - Zero external dependencies (pure HTML/CSS/JS) Files Modified: - tools/spectral_editor/script.js (~1730 lines, main implementation) - tools/spectral_editor/index.html (UI structure, spectrum viewer) - tools/spectral_editor/style.css (VSCode dark theme styling) - tools/spectral_editor/README.md (updated features, roadmap) Phase 3 TODO (Next): =================== - Effect combination system (noise + Gaussian modulation, layer compositing) - Improved C++ code testing (validation, edge cases) - Better frequency scale (mu-law or perceptual scale, less bass-heavy) - Pre-defined shape library (kick, snare, hi-hat templates) - Load procedural_params.txt back into editor (re-editing) - FFT-based DCT optimization (O(N log N) vs O(N²)) Integration: - Generate C++ code → Copy to src/audio/procedural_samples.cc - Add PROC() entry to assets/final/demo_assets.txt - Rebuild demo → Use AssetId::SOUND_PROC handoff(Claude): Phase 2 complete. Next: FFT implementation task for performance optimization. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'tools/spectral_editor/index.html')
-rw-r--r--tools/spectral_editor/index.html39
1 files changed, 38 insertions, 1 deletions
diff --git a/tools/spectral_editor/index.html b/tools/spectral_editor/index.html
index 52f1d8f..a9391dd 100644
--- a/tools/spectral_editor/index.html
+++ b/tools/spectral_editor/index.html
@@ -27,6 +27,10 @@
<p>Load a .wav or .spec file to begin</p>
<p class="hint">Click "Load .wav/.spec" button or press Ctrl+O</p>
</div>
+ <!-- Mini spectrum viewer (bottom-right overlay) -->
+ <div id="spectrumViewer" class="spectrum-viewer">
+ <canvas id="spectrumCanvas" width="200" height="100"></canvas>
+ </div>
</div>
<!-- Toolbar (right side, 20% width) -->
@@ -39,6 +43,22 @@
<span class="icon">×</span> Delete
</button>
<div id="curveList" class="curve-list"></div>
+
+ <h3>Selected Point</h3>
+ <div id="pointInfo" class="point-info">
+ <div class="info-row">
+ <span class="info-label">Frame:</span>
+ <span id="pointFrame" class="info-value">-</span>
+ </div>
+ <div class="info-row">
+ <span class="info-label">Frequency:</span>
+ <span id="pointFreq" class="info-value">-</span>
+ </div>
+ <div class="info-row">
+ <span class="info-label">Amplitude:</span>
+ <span id="pointAmp" class="info-value">-</span>
+ </div>
+ </div>
</div>
</div>
@@ -56,9 +76,20 @@
<label for="sigmaSlider" id="sigmaLabel">Sigma:</label>
<input type="range" id="sigmaSlider" class="slider" min="1" max="100" value="30" step="0.1">
<input type="number" id="sigmaValue" class="number-input" min="1" max="100" value="30" step="0.1">
+
+ <label for="curveVolumeSlider">Curve Vol:</label>
+ <input type="range" id="curveVolumeSlider" class="slider" min="0" max="100" value="100" step="1">
+ <input type="number" id="curveVolumeValue" class="number-input" min="0" max="100" value="100" step="1">
+ </div>
+
+ <!-- Middle section: Display controls -->
+ <div class="control-section">
+ <label for="refOpacitySlider">Ref Opacity:</label>
+ <input type="range" id="refOpacitySlider" class="slider" min="0" max="100" value="50" step="1">
+ <input type="number" id="refOpacityValue" class="number-input" min="0" max="100" value="50" step="1">
</div>
- <!-- Middle section: Curve selection -->
+ <!-- Curve selection -->
<div class="control-section">
<label for="curveSelect">Active Curve:</label>
<select id="curveSelect" class="select-input">
@@ -68,6 +99,12 @@
<!-- Right section: Playback controls -->
<div class="control-section playback-controls">
+ <label for="volumeSlider">Volume:</label>
+ <input type="range" id="volumeSlider" class="slider" min="0" max="100" value="100" step="1">
+ <input type="number" id="volumeValue" class="number-input" min="0" max="100" value="100" step="1">
+ </div>
+
+ <div class="control-section playback-controls">
<button id="playProceduralBtn" class="btn-playback" title="Play procedural sound (Key 1)">
<span class="icon">▶</span> <kbd>1</kbd> Procedural
</button>