summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-03-07streamline docskal
2026-03-07feat(tools): add offline WGSL validator + fix ntsc.wgsl syntaxskal
- scripts/validate_shaders.py: compose #includes then validate with naga-cli (mirrors InitShaderComposer snippet map; skips runtime-substitution shaders) - src/effects/ntsc.wgsl: remove broken GLSL-syntax vignette() function (GLSL const/param syntax, f32→vec2f assignment; inline vignette at line 55 already handles darkening) handoff(Gemini): validator at scripts/validate_shaders.py; install naga with cargo install naga-cli; 29/29 shaders pass Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07fix(cmake): normalize asset paths to fix incremental rebuild trackingskal
Paths like ../../src/effects/ntsc.wgsl were stored non-normalized in the DEPENDS list, preventing Ninja/Make from detecting file changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07feat(effects): add Ntsc post-process effect with fisheye distortionskal
WGSL-only WgslEffect implementing barrel/fisheye distortion, RGB chroma separation, scanlines, per-pixel temporal noise, rolling jitter line, vignette, and warm NTSC phosphor tint. Applied across all main sequences. handoff(Gemini): Ntsc effect added; 13 effects total, 35+1 tests expected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07refactor(effects): introduce WgslEffect for shader-only post-process effectsskal
Replace boilerplate .h/.cc pairs for simple single-pass effects with a generic WgslEffect base class that takes a shader string + optional WgslEffectParams (binding 3). Port Flash, Passthrough, Heptagon, Scratch, and GaussianBlur to thin header-only wrappers — no .cc files, no CMake entries needed. Removes 5 .cc files (-243 lines). Update EFFECT_WORKFLOW.md, CONTRIBUTING.md, and AI_RULES.md to document the WgslEffect (Path A) vs full class (Path B) workflow. Doc cleanup: fix stale GaussianBlurParams/PostProcessEffect references and test counts. handoff(Claude): WgslEffect landed; 5 effects ported; docs updated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06feat(effects): add Scratch post-process effect with reusable scratch_lines ↵skal
snippet - src/shaders/render/scratch_lines.wgsl: reusable WGSL snippet registered as "render/scratch_lines"; call scratch_lines(uv, resolution, time)->f32 from any effect. Uses hash_1f from math/noise; 8 lines/frame, ~24fps flicker. - src/effects/scratch.{wgsl,h,cc}: thin Scratch effect wrapping the snippet. - Applied to "intro" and "rotating_cube" sequences as the final step. - 35/35 tests passing. handoff(Gemini): Scratch effect added. render/scratch_lines snippet is reusable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06test: remove obsolete test_sequence.ccskal
2026-03-05docs: streamline and align AI context filesskal
Synchronized GEMINI.md and CLAUDE.md to provide a consistent and comprehensive context-loading structure for both AI agents. - Consolidated the Tier 3 (Design Docs) and Tier 4 (Archive) sections to include a detailed, verified list of all relevant documentation. - Standardized the use of the '@' prefix for all file paths, assuming a common loader directive. - Ensured project rules and maintenance guidelines are identical between both files.
2026-03-05docs: add control flow braces rule to coding styleskal
2026-03-05style: run clang-format to adhere to coding styleskal
2026-03-05fix(test): WavDumpBackendTest uses sine tone instead of empty ring bufferskal
Without music loaded, synth renders silence; reading from the ring buffer yielded all-zero samples causing the non_zero_count assertion to fail. Replace the ring-buffer read path with a direct 440 Hz sine wave so the test focuses on WAV format/encoding, not audio pipeline content. handoff(Claude): WavDumpBackendTest now passes (35/35 tests green). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05fix(audio): correct OLA synthesis and extract shared ola_encode/ola_decodeskal
- Remove erroneous Hann synthesis window from synth.cc (g_hann * tmp[j]). Hann analysis at 50% overlap satisfies w[n]+w[n+H]=1, so rectangular synthesis gives perfect reconstruction; applying Hann twice was wrong. - Extract ola_encode()/ola_decode()/ola_num_frames() into src/audio/ola.h+cc. spectool and test_wav_roundtrip now use the shared functions. synth.cc lazy-decode path stays inlined (see TODO for future refactor). - Drop dead <atomic> include and g_hann array from synth.cc. - Drop dead window.h include from spectool.cc. - Update PROJECT_CONTEXT.md, COMPLETED.md, TODO.md to reflect correct analysis-only Hann window and new ola.h API. handoff(Gemini): OLA synthesis bug fixed + ola.h factorized. synth.cc lazy-decode still inline (TODO item added). 34/35 tests pass; WavDumpBackendTest failure is pre-existing and unrelated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05fix(spectool): rename --wav flag to wav subcommand for consistencyskal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05chore: remove dead specplay tool and all referencesskal
specplay was removed from the build but source/docs remained. Delete tools/specplay.cc, tools/specplay_README.md, and remove specplay sections from TOOLS_REFERENCE.md and BACKLOG.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05feat(spectool): add --wav decode, IMDCT, and roundtrip testskal
- spectool --wav <input.spec> <output.wav>: decodes .spec to mono 16-bit WAV at 32 kHz using IDCT-OLA synthesis (no synthesis window). The analysis Hann window at 50% overlap satisfies w[n]+w[n+H]=1, so the synthesis window must be rectangular for perfect reconstruction. - Add imdct_512 / imdct_fft to audio lib (fft.cc, fft.h, idct.cc, dct.h) for future MDCT-based synthesis. - test_wav_roundtrip: in-process OLA analyze+decode SNR test (≥30 dB). Currently measures 53 dB on a 440 Hz sine. - Fix stale test_spectool.cc: version assertion updated from 1 to SPEC_VERSION_V2_OLA (was always wrong since OLA fix landed). - Docs: TOOLS_REFERENCE.md removes dead specview, documents --wav / --normalize / test_gen. HOWTO.md adds decode section. TRACKER.md notes spec v2 OLA format and decode command. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05fix(audio): OLA encoder never ran; version never propagated to decoderskal
Two bugs kept the v2 OLA path permanently disabled: 1. SpectrogramResourceManager::load_asset() never set spec.version from SpecHeader::version — all .spec assets loaded with version=0, so ola_mode was always false in the voice. 2. spectool analyze_audio() used non-overlapping chunks (stride=DCT_SIZE), hamming_window_512, and hardcoded header.version=1 — OLA analysis was never implemented in the encoder. Fixes: propagate header->version in load_asset(); switch spectool to OLA_HOP_SIZE stride, hann_window_512, and SPEC_VERSION_V2_OLA. Regenerated all .spec files. handoff(Gemini): OLA enc/dec chain now correct end-to-end. .spec files are v2 (50% overlap, Hann). No API changes; 33/34 tests pass (WavDumpBackendTest pre-existing failure unrelated). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05fix(spectool): pre-fill audio buffer before audio_start() in play modeskal
Trigger voice and render ahead before starting the audio device to avoid "Audio buffer not pre-filled" warning and silent playback. handoff(Claude): spectool play now produces sound correctly.
2026-03-05remove dead tool 'specview'skal
2026-03-05remove old .trackskal
2026-03-05add training photosskal
2026-03-05music = one big drum sample (for now!)skal
2026-03-05feat(tracker): add /* */ block comment support to .track parserskal
handoff(Gemini): tracker_compiler now handles single-line and multi-line block comments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03test(assets): add MP3 asset type test (TEST_MP3/ASSET_TEST_MP3)skal
Adds a minimal test.mp3 fixture to the test workspace and verifies GetAssetType returns AssetType::MP3 and GetAsset returns non-null data. handoff(Gemini): MP3 asset test added, 34/34 tests passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03chore(audio): regenerate .spec files as v2 (OLA, Hann, hop=256)skal
handoff(Gemini): all .spec files rebuilt with v2 encoder; click-free OLA synthesis active.
2026-03-03feat(assets): replace is_procedural/is_gpu_procedural bools with AssetType ↵skal
enum, add MP3 type - Add AssetType enum {STATIC, PROC, PROC_GPU, MP3} to AssetRecord - Add GetAssetType() API to asset_manager.h/cc - asset_packer: parse 'MP3' compression keyword in assets.txt - tracker: remove magic-byte is_mp3_asset(); use GetAssetType() instead - assets.txt: NEVER_MP3 now uses 'MP3' compression type - doc/ASSET_SYSTEM.md: rewritten to document new types and API handoff(Gemini): AssetType enum landed; MP3 detection is now explicit via asset metadata.
2026-03-03fix(build): add spectool to DEMO_BUILD_TOOLS cmake targetskal
spectool was missing from DemoTools.cmake; scripts/gen_spectrograms.sh could not find build/spectool. Document the regeneration workflow in HOWTO.md. handoff(Claude): spectool now builds with -DDEMO_BUILD_TOOLS=ON
2026-03-02docs: update PROJECT_CONTEXT, TODO, COMPLETED for OLA-IDCTskal
- PROJECT_CONTEXT: audio section reflects OLA-IDCT (Hann, 50% overlap); test count 35->34; Next Up notes .spec regen needed - TODO: remove stale MP3 sub-task (done), trim test TODOs, add .spec regen as Priority 3, update test count to 34/34 - COMPLETED: archive OLA-IDCT task with implementation summary
2026-03-02feat(audio): OLA-IDCT synthesis with Hann window to eliminate clicksskal
Add v2 spectrogram format (SPEC_VERSION_V2_OLA) using overlap-add IDCT with 50% overlap (hop=256, OLA_OVERLAP=256) and Hann windowing. - dct.h: OLA_HOP_SIZE=256, OLA_OVERLAP=256 - synth.h: SPEC_VERSION_V1/V2_OLA constants; version field on Spectrogram - window.h/cc: hann_window_512() alongside existing hamming_window_512() - synth.cc: g_hann[] precomputed at init; OLA path in synth_render when ola_mode=true (IDCT -> Hann -> add overlap tail -> save new tail -> output OLA_HOP_SIZE samples); v1 path unchanged for backward compat - tracker.cc: MP3 encoder now uses sliding 512-sample Hann window with OLA_HOP_SIZE advance per frame; sets version=SPEC_VERSION_V2_OLA; .spec files propagate header->version; generated notes stay v1 Existing .spec files must be regenerated to benefit from click-free OLA. handoff(Claude): OLA done. .spec files need regen via MP3 tool to activate v2.
2026-03-02add mp3 assetskal
2026-03-02feat(audio): MP3 asset support in tracker via decode-at-initskal
Detect MP3 blobs by magic bytes in tracker_init(), decode to spectrogram (hamming window + FDCT) using new mp3_decode(), and register with synth exactly like .spec assets. STRIP_ALL builds guard with FATAL_CHECK. handoff(Gemini): MP3 assets now usable in music.track with SAMPLE ASSET_* syntax; see doc/TRACKER.md for usage. No synth/compiler/packer changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01feat(audio): add experimental MP3 on-demand range decoderskal
Adds mp3_open/mp3_decode_range/mp3_close API backed by miniaudio ma_decoder for in-memory MP3 assets. Guarded by #if !defined(STRIP_ALL); any use in stripped builds is a compile error. No new dependencies: drmp3 is already compiled via MINIAUDIO_IMPLEMENTATION in audio.cc. handoff(Gemini): mp3_sample.{h,cc} in AUDIO_SOURCES. Usage: Mp3Decoder* d = mp3_open(GetAsset(id, &sz), sz); mp3_decode_range(d, start_frame, num_frames, pcm_out); mp3_close(d); Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28fix(shadertoy): update convert_shadertoy.py shader output path to src/effects/skal
Shader output and Next Steps instructions now use src/effects/<name>.wgsl instead of workspaces/main/shaders/<name>.wgsl. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28refactor(effects): co-locate effect WGSL shaders with their .h/.cc in ↵skal
src/effects/ Move 13 effect-specific shaders from workspaces/main/shaders/ to src/effects/ so each effect's .h, .cc, and .wgsl are together. Update assets.txt paths in both main and test workspaces. Update EFFECT_WORKFLOW.md to reflect new location. Shared/reusable snippets remain in src/shaders/. handoff(Gemini): shaders moved; src/effects/ now has .h, .cc, and .wgsl per effect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28fix(scene2): rewrite broken WGSL shader to fix test_demo_effects crashskal
scene2.wgsl was invalid WGSL (mixed GLSL syntax, wrong function signatures, undeclared variables, no return statement). Rewrote as valid WGSL preserving the original volumetric cloud raymarching logic. 11/11 effects now pass. handoff(Claude): scene2.wgsl fixed, all tests green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28fix Scene2 -> Scene2Effectskal
2026-02-28feat(tools/shadertoy): add --dry-run flag to skip file writingskal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28fix(tools/shadertoy): fix Next Steps instructions and update EFFECT_WORKFLOW.mdskal
- Fix assets.txt path: shaders/xxx.wgsl (not ../../src/shaders/) - Fix shader output path to workspaces/main/shaders/ - Step 5: reference cmake/DemoSourceLists.cmake COMMON_GPU_EFFECTS (not CMakeLists.txt GPU_SOURCES) - Add step for test_demo_effects.cc Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28fix(tools/shadertoy): sync templates and script to current codebase conventionsskal
- template.h/cc: new Effect constructor/render signatures, RAII wrappers, HEADLESS_RETURN_IF_NULL, #pragma once - template.wgsl: sequence_uniforms + render/fullscreen_uv_vs includes, UniformsSequenceParams at binding 2, VertexOutput in fs_main - convert_shadertoy.py: paths src/effects/ + src/shaders/, new Effect pattern (create_post_process_pipeline, pp_update_bind_group), correct field names (beat_time/beat_phase), updated next-steps instructions - README.md: streamlined to quick-ref; accurate GLSL→WGSL table and uniforms Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28fix(shader_editor): sync CommonUniforms to current struct, fix layoutskal
- Update CommonUniforms: remove _pad0/_pad1, add beat_time/beat_phase, move _pad to end (matches src/shaders/common_uniforms.wgsl) - Fix JS uniform write order to match new layout - Fix flex-direction: row override (common.css forced column, hiding editor) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28refactor: move common/shaders/ to src/shaders/skal
Relocates shared WGSL shaders under src/ where all source code lives, eliminating the top-level common/ directory. - Update asset references in workspaces/main/assets.txt and workspaces/test/assets.txt - Update docs: PROJECT_CONTEXT.md, ARCHITECTURE.md, WORKSPACE_SYSTEM.md, SHADER_REUSE_INVESTIGATION.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28remove unused util/math.hskal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28misc: cleanup comments and formatting in headersskal
- asset_manager_dcl.h: clarify purpose vs asset_manager.h - camera_params.h: broaden description to include 3D rendering - sdf_cpu.h: simplify calc_normal formatting - platform.h: add missing newline at EOF Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28refactor(gpu): move RenderPipelineBuilder impl to pipeline_builder.ccskal
Keeps .h as declarations only; moves all method bodies to .cc. Adds pipeline_builder.cc to COMMON_GPU_EFFECTS in DemoSourceLists.cmake. handoff(Claude): pipeline_builder split to .h/.cc, builds clean.
2026-02-28refactor(gpu): move SamplerCache impl to .cc, expose single entry pointskal
get_or_create() and clear() moved out of the header-only class. SamplerSpec and presets remain inline (trivial, no deps). handoff(Gemini): sampler_cache split into .h/.cc, sampler_cache.cc added to COMMON_GPU_EFFECTS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28remove SDFEffect base class and sdf_test, update SDF_EFFECT_GUIDEskal
- Delete unused SDFEffect base class (src/gpu/sdf_effect.h) - Delete sdf_test.wgsl and SHADER_SDF_TEST from assets.txt - Rewrite SDF_EFFECT_GUIDE.md based on Scene1 canonical pattern: correct bindings (2/3), vec4f syntax, UniformsSequenceParams - Fix missing newline at end of gpu.h handoff(Claude): SDF cleanup done, guide updated to match current Effect API
2026-02-28remove vestigial demo_effects.ccskal
handoff(Gemini): deleted src/gpu/demo_effects.cc (empty stub), removed from headless GPU_SOURCES in DemoSourceLists.cmake, dropped stale #include from post_process_helper.cc. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28replace wgsl type: vec4<f32> -> vec4f ..skal
2026-02-28fix: double-free of external views in NodeRegistry and PASSTHROUGH shader testskal
- NodeRegistry: skip external nodes (texture==nullptr) in ~NodeRegistry() and resize() to avoid double-releasing views set via set_external_view() - test_shader_assets: update PASSTHROUGH check to match #include pattern handoff(Claude): 35/35 tests passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28fix(shaders): deduplicate VertexOutput/vs_main via render/fullscreen_uv_vs ↵skal
snippet - Fix vs_main return type (VertexOutput, not vec4<f32>) - Fix #include paths in passthrough, gaussian_blur, heptagon, combined_postprocess - ShaderComposer: assert + suggest correct path on missing #include (non-STRIP_ALL) - VerifyIncludes: upgrade WARNING to ERROR + assert, add "did you mean?" hint Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27remove old files, add new training setskal