summaryrefslogtreecommitdiff
path: root/src/audio/spectral_brush.h
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-06 11:12:34 +0100
committerskal <pascal.massimino@gmail.com>2026-02-06 11:12:34 +0100
commit5a1adde097e489c259bd052971546e95683c3596 (patch)
treebf03cf8b803604638ad84ddd9cc26de64baea64f /src/audio/spectral_brush.h
parent83f34fb955524c09b7f3e124b97c3d4feef02a0c (diff)
feat(audio): Add Spectral Brush runtime (Phase 1 of Task #5)
Implement C++ runtime foundation for procedural audio tracing tool. Changes: - Created spectral_brush.h/cc with core API - Linear Bezier interpolation - Vertical profile evaluation (Gaussian, Decaying Sinusoid, Noise) - draw_bezier_curve() for spectrogram rendering - Home-brew deterministic RNG for noise profile - Added comprehensive unit tests (test_spectral_brush.cc) - Tests Bezier interpolation, profiles, edge cases - Tests full spectrogram rendering pipeline - All 9 tests pass - Integrated into CMake build system - Fixed test_assets.cc include (asset_manager_utils.h) Design: - Spectral Brush = Central Curve (Bezier) + Vertical Profile - Enables 50-100x compression (5KB .spec to 100 bytes C++ code) - Future: Cubic Bezier, composite profiles, multi-dimensional curves Documentation: - Added doc/SPECTRAL_BRUSH_EDITOR.md (complete architecture) - Updated TODO.md with Phase 1-4 implementation plan - Updated PROJECT_CONTEXT.md to mark Task #5 in progress Test results: 21/21 tests pass (100%) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/audio/spectral_brush.h')
-rw-r--r--src/audio/spectral_brush.h80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/audio/spectral_brush.h b/src/audio/spectral_brush.h
new file mode 100644
index 0000000..3125f35
--- /dev/null
+++ b/src/audio/spectral_brush.h
@@ -0,0 +1,80 @@
+// This file is part of the 64k demo project.
+// It implements the "Spectral Brush" primitive for procedural audio generation.
+// Spectral brushes trace Bezier curves through spectrograms with vertical profiles.
+
+#pragma once
+
+#include <cstdint>
+
+// Profile types for vertical distribution around central Bezier curve
+enum ProfileType {
+ PROFILE_GAUSSIAN = 0, // Smooth harmonic falloff
+ PROFILE_DECAYING_SINUSOID = 1, // Resonant/metallic texture
+ PROFILE_NOISE = 2 // Random texture/grit
+};
+
+// Evaluate linear Bezier interpolation at given frame
+// control_frames: Array of frame positions for control points
+// control_values: Array of values at control points (freq_hz or amplitude)
+// n_points: Number of control points
+// frame: Frame number to evaluate at
+// Returns: Interpolated value at frame (linearly interpolated between control points)
+float evaluate_bezier_linear(const float* control_frames,
+ const float* control_values,
+ int n_points,
+ float frame);
+
+// Draw a spectral brush stroke onto a spectrogram
+// Traces a Bezier curve through time-frequency space with a vertical profile
+// spectrogram: Output buffer (dct_size × num_frames), modified in-place
+// dct_size: Number of frequency bins (e.g., 512)
+// num_frames: Number of time frames
+// control_frames: Frame positions of Bezier control points
+// control_freqs_hz: Frequency values (Hz) at control points
+// control_amps: Amplitude values at control points (0.0-1.0 typical)
+// n_control_points: Number of control points (minimum 2 for a curve)
+// profile_type: Type of vertical profile to apply
+// profile_param1: First parameter (sigma for Gaussian, decay for sinusoid, amplitude for noise)
+// profile_param2: Second parameter (unused for Gaussian, frequency for sinusoid, seed for noise)
+void draw_bezier_curve(float* spectrogram,
+ int dct_size,
+ int num_frames,
+ const float* control_frames,
+ const float* control_freqs_hz,
+ const float* control_amps,
+ int n_control_points,
+ ProfileType profile_type,
+ float profile_param1,
+ float profile_param2 = 0.0f);
+
+// Additive variant of draw_bezier_curve (adds to existing spectrogram content)
+// Use for compositing multiple profiles (e.g., Gaussian + Noise)
+// Parameters same as draw_bezier_curve()
+void draw_bezier_curve_add(float* spectrogram,
+ int dct_size,
+ int num_frames,
+ const float* control_frames,
+ const float* control_freqs_hz,
+ const float* control_amps,
+ int n_control_points,
+ ProfileType profile_type,
+ float profile_param1,
+ float profile_param2 = 0.0f);
+
+// Evaluate vertical profile at given distance from central curve
+// type: Profile type (Gaussian, Decaying Sinusoid, Noise)
+// distance: Distance in frequency bins from curve center
+// param1: First profile parameter
+// param2: Second profile parameter
+// Returns: Profile amplitude at given distance (0.0-1.0 range typically)
+float evaluate_profile(ProfileType type,
+ float distance,
+ float param1,
+ float param2);
+
+// Home-brew deterministic RNG for noise profile
+// Simple linear congruential generator (LCG) for small code size
+// seed: Input seed value
+// Returns: Pseudo-random uint32_t value
+uint32_t spectral_brush_rand(uint32_t seed);
+