From 802e97ee695de1bc8657c5cbca653bb2f13b90a8 Mon Sep 17 00:00:00 2001 From: skal Date: Mon, 9 Feb 2026 15:35:14 +0100 Subject: docs: Condense essential context files (856→599 lines) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract detailed examples and untriaged tasks to on-demand docs. Created BACKLOG.md, ARCHITECTURE.md, CODING_STYLE.md, TOOLS_REFERENCE.md. Reduces always-loaded token budget by 30% while preserving all information. Co-Authored-By: Claude Sonnet 4.5 --- doc/ARCHITECTURE.md | 60 +++++++++++++++ doc/BACKLOG.md | 197 +++++++++++++++++++++++++++++++++++++++++++++++++ doc/CODING_STYLE.md | 109 +++++++++++++++++++++++++++ doc/CONTRIBUTING.md | 71 +++++------------- doc/HOWTO.md | 86 ++++++--------------- doc/TOOLS_REFERENCE.md | 89 ++++++++++++++++++++++ 6 files changed, 498 insertions(+), 114 deletions(-) create mode 100644 doc/ARCHITECTURE.md create mode 100644 doc/BACKLOG.md create mode 100644 doc/CODING_STYLE.md create mode 100644 doc/TOOLS_REFERENCE.md (limited to 'doc') diff --git a/doc/ARCHITECTURE.md b/doc/ARCHITECTURE.md new file mode 100644 index 0000000..1a32300 --- /dev/null +++ b/doc/ARCHITECTURE.md @@ -0,0 +1,60 @@ +# Architectural Overview + +Detailed system architecture for the 64k demo project. + +--- + +## Hybrid 3D Renderer + +**Core Idea**: Uses standard rasterization to draw proxy hulls (boxes), then raymarches inside the fragment shader to find the exact SDF surface. + +**Transforms**: Uses `inv_model` matrices to perform all raymarching in local object space, handling rotation and non-uniform scaling correctly. + +**Shadows**: Instance-based shadow casting with self-shadowing prevention (`skip_idx`). + +--- + +## Sequence & Effect System + +**Effect**: Abstract base for visual elements. Supports `compute` and `render` phases. + +**Sequence**: Timeline of effects with start/end times. + +**MainSequence**: Top-level coordinator and framebuffer manager. + +**seq_compiler**: Transpiles `assets/demo.seq` into C++ `timeline.cc`. + +--- + +## Asset & Build System + +**asset_packer**: Embeds binary assets (like `.spec` files) into C++ arrays. + +**Runtime Manager**: O(1) retrieval with lazy procedural generation support. + +**Automation**: `gen_assets.sh`, `build_win.sh`, and `check_all.sh` for multi-platform validation. + +--- + +## Audio Engine + +### Synthesis +Real-time additive synthesis from spectrograms via FFT-based IDCT (O(N log N)). Stereo output (32kHz, 16-bit, interleaved L/R). Uses orthonormal DCT-II/DCT-III transforms with Numerical Recipes reordering method. + +### Variable Tempo +Music time abstraction with configurable tempo_scale. Tempo changes don't affect pitch. + +### Event-Based Tracker +Individual TrackerEvents trigger as separate voices with dynamic beat calculation. Notes within patterns respect tempo scaling. + +### Backend Abstraction +`AudioBackend` interface with `MiniaudioBackend` (production), `MockAudioBackend` (testing), and `WavDumpBackend` (offline rendering). + +### Dynamic Updates +Double-buffered spectrograms for live thread-safe updates. + +### Procedural Library +Melodies and spectral filters (noise, comb) generated at runtime. + +### Pattern System +TrackerPatterns contain lists of TrackerEvents (beat, sample_id, volume, pan). Events trigger individually based on elapsed music time. diff --git a/doc/BACKLOG.md b/doc/BACKLOG.md new file mode 100644 index 0000000..403ecc9 --- /dev/null +++ b/doc/BACKLOG.md @@ -0,0 +1,197 @@ +# Future Goals & Ideas (Untriaged) + +This file contains low-priority tasks and ideas that have not yet been triaged for active development. + +--- + +## Audio Tools + +### Task #64: specplay Enhancements +Extend audio analysis tool with new features: +- **Priority 1**: Spectral visualization (ASCII art), waveform display, frequency analysis, dynamic range +- **Priority 2**: Diff mode (compare .wav vs .spec), batch mode (CSV report, find clipping) +- **Priority 3**: WAV export (.spec → .wav), normalization +- **Priority 4**: Spectral envelope, harmonic analysis, onset detection +- **Priority 5**: Interactive mode (seek, loop, volume control) + +See `tools/specplay_README.md` for detailed feature list. + +### Task #65: Data-Driven Tempo Control +Move tempo variation from code to data files. + +**Current**: `g_tempo_scale` is hardcoded in `main.cc` with manual animation curves + +**Goal**: Define tempo curves in `.seq` or `.track` files + +**Approach A**: Add TEMPO directive to `.seq` format +- Example: `TEMPO 0.0 1.0`, `TEMPO 10.0 2.0`, `TEMPO 20.0 1.0` +- seq_compiler generates tempo curve array in timeline.cc + +**Approach B**: Add tempo column to music.track +- Each pattern trigger can specify tempo_scale override +- tracker_compiler generates tempo events in music_data.cc + +**Benefits**: Non-programmers can edit tempo, easier iteration, version control friendly + +**Priority**: Low (current approach works) + +### Task #67: DCT/FFT Performance Benchmarking +Add timing measurements to audio tests. + +**Goal**: Compare performance of different DCT/IDCT implementations + +**Location**: Add timing code to `test_dct.cc` or `test_fft.cc` + +**Measurements**: +- Reference IDCT/FDCT (naive O(N²)) +- FFT-based DCT/IDCT (current O(N log N)) +- Future x86_64 SIMD-optimized versions + +**Output Format**: +- Average time per transform (microseconds) +- Throughput (transforms per second) +- Speedup factor vs reference + +**Test Sizes**: DCT_SIZE=512 (production), plus 128, 256, 1024 for scaling + +**Implementation**: +- Use `std::chrono::high_resolution_clock` +- Run 1000+ iterations to reduce noise +- Report min/avg/max times +- Guard with `#if !defined(STRIP_ALL)` + +**Priority**: Very Low (nice-to-have) + +### Task #69: Convert Audio Pipeline to Clipped Int16 +Use clipped int16 for all audio processing. + +**Current**: Float32 throughout (generation, mixing, synthesis, output) + +**Goal**: Convert to int16 for faster processing and reduced memory + +**Rationale**: +- Simpler arithmetic (no float operations) +- Smaller memory footprint (2 bytes vs 4 bytes) +- Hardware-native format (most audio devices use int16) +- Eliminates float→int16 conversion at output +- Natural clipping behavior + +**Scope**: +- Output path: Definitely convert (backends, WAV dump) +- Synthesis: Consider keeping float32 for quality +- Mixing: Could use int16 with overflow handling +- Asset storage: Already int16 in .spec files + +**Implementation Phases**: +1. **Phase 1: Output Only** (~50 lines) - Convert `synth_render()` output to int16 +2. **Phase 2: Mixing Stage** (~200 lines) - Convert voice mixing to int16 arithmetic +3. **Phase 3: Full Pipeline** (~500+ lines) - Convert spectrograms to int16 storage + +**Trade-offs**: +- Quality loss: 16-bit vs 32-bit float precision +- Dynamic range: Limited to [-32768, 32767] +- Clipping: Must handle overflow carefully +- Code complexity: Saturation arithmetic + +**Testing Requirements**: +- Verify no audible quality degradation +- Ensure clipping behavior matches float version +- Check mixing overflow doesn't cause artifacts +- Validate WAV dumps bit-identical + +**Size Impact**: +- Phase 1: Negligible (~50 bytes) +- Phase 2: ~100-200 bytes +- Phase 3: 50% memory, ~1-2KB code savings + +**Priority**: Low (final optimization only if 64k budget requires it) + +**Notes**: Quality must be validated - may not be worth trade-off + +--- + +## Developer Tools + +### Task #66: External Asset Loading for Debugging +mmap() asset files instead of embedded data. + +**Current**: All assets embedded in `assets_data.cc` (regenerate on every change) + +**Goal**: Load assets from external files in debug builds for faster iteration + +**Scope**: macOS only, non-STRIP_ALL builds only + +**Implementation**: +- Add `DEMO_ENABLE_EXTERNAL_ASSETS` CMake option +- Modify `GetAsset()` to check for external file first (e.g., `assets/final/`) +- Use `mmap()` to map file into memory +- Fallback to embedded data if file not found + +**Benefits**: Edit shaders/assets without regenerating assets_data.cc (~10s rebuild) + +**Trade-offs**: Adds runtime file I/O, only useful during development + +**Priority**: Low (current workflow acceptable) + +--- + +## Visual Effects + +### Task #73: Extend Shader Parametrization [IN PROGRESS - 2/4 complete] +Extend uniform parameter system to remaining effects. + +**Goal**: Add parametrization to DistortEffect, SolarizeEffect + +**Pattern**: Follow FlashEffect implementation (UniformHelper, params struct, .seq syntax) + +**Completed**: ChromaAberrationEffect (offset_scale, angle), GaussianBlurEffect (strength) + +**Priority**: Medium (quality-of-life for artists) + +**Estimated Impact**: ~200-300 bytes per effect + +### Task #52: Procedural SDF Font +Minimal bezier/spline set for [A-Z, 0-9] and SDF rendering. + +### Task #55: SDF Random Planes Intersection +Implement `sdPolyhedron` (crystal/gem shapes) via plane intersection. + +### Task #54: Tracy Integration +Integrate Tracy debugger for performance profiling. + +### Task #58: Advanced Shader Factorization +Further factorize WGSL code into smaller, reusable snippets. + +### Task #59: Comprehensive RNG Library +Add WGSL snippets for float/vec2/vec3 noise (Perlin, Gyroid, etc.) and random number generators. + +### Task #60: OOP Refactoring +Investigate if more C++ code can be made object-oriented without size penalty (vs functional style). + +### Task #61: GPU Procedural Generation +Implement system to generate procedural data (textures, geometry) on GPU and read back to CPU. + +### Task #62: Physics Engine Enhancements (PBD & Rotation) +- **Task #62.1**: Quaternion rotation for `Object3D` with angular momentum +- **Task #62.2**: Position Based Dynamics (PBD) - Re-evaluate velocity after resolving collisions/constraints + +### Task #63: Refactor Large Files +Split `src/gpu/gpu.cc`, `src/3d/visual_debug.cc` and `src/gpu/effect.cc` into sub-functionalities. + +--- + +## Performance Optimization + +### Task #70: SIMD x86_64 Implementation +Implement critical functions using intrinsics for x86_64 platforms. + +**Goal**: Optimize hot paths for audio and procedural generation + +**Scope**: +- IDCT/FDCT transforms +- Audio mixing and voice synthesis +- CPU-side procedural texture/geometry generation + +**Constraint**: Non-critical; fallback to generic C++ must be maintained + +**Priority**: Very Low diff --git a/doc/CODING_STYLE.md b/doc/CODING_STYLE.md new file mode 100644 index 0000000..533cffb --- /dev/null +++ b/doc/CODING_STYLE.md @@ -0,0 +1,109 @@ +# Coding Style Examples + +Detailed examples for the project's C++ coding style. + +--- + +## Core Rules Examples + +### Const Placement +```cpp +const T* name // Correct +const T *name // Wrong +``` + +### Pre-Increment +```cpp +++x // Correct +x++ // Wrong (except when postfix needed) +``` + +### Operator Spacing +```cpp +x = (a + b) * c; // Correct - spaces around all operators +x=(a+b)*c; // Wrong - no spaces +``` + +### No Auto (except complex iterators) +```cpp +int count = get_count(); // Correct +auto count = get_count(); // Wrong + +for (auto it = map.begin(); ...) // OK - complex iterator type +``` + +### No C++ Casts +```cpp +(int)value // Correct +static_cast(value) // Wrong +``` + +--- + +## Preprocessor Style + +```cpp +#if defined(MY_TAG) + // code here +#endif /* defined(MY_TAG) */ +``` + +Always use `defined()` and closing comment. + +--- + +## Struct Initialization + +### Good +```cpp +const WGPUDescriptor desc = { + .format = g_format, + .dimension = WGPUTextureViewDimension_2D, +}; +``` + +### Bad +```cpp +WGPUDescriptor desc = {}; +desc.format = g_format; +desc.dimension = WGPUTextureViewDimension_2D; +``` + +Use designated initializers, not field-by-field assignment. + +--- + +## Class Keywords Indentation + +```cpp +class MyClass { + public: // 1 space indent + void foo(); + + private: // 1 space indent + int field_; +}; +``` + +--- + +## Comments + +### Function Comments +```cpp +// Initializes the audio engine with default settings. +void audio_init() { + ... +} +``` + +One-line comment for non-obvious functions. + +### File Headers +```cpp +// demo64k - 64 kilobyte demo +// src/audio/synth.cc +// Audio synthesis engine +``` + +Three-line header for all source files. diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index 7490fe6..de6378a 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -1,5 +1,7 @@ # Contributing Guidelines +--- + ## Commit Policy ### Verify Before Committing @@ -8,7 +10,6 @@ ```bash ./scripts/check_all.sh ``` -Runs tests, builds tools, cross-compiles Windows. **Manual:** ```bash @@ -26,18 +27,9 @@ cd build && ctest --output-on-failure cmake -S . -B build_debug_check -DDEMO_ENABLE_DEBUG_LOGS=ON cmake --build build_debug_check -j4 ``` -Must compile without errors. **Debug macros** (`src/util/debug.h`): -- `DEBUG_LOG_AUDIO`, `DEBUG_LOG_RING_BUFFER`, `DEBUG_LOG_TRACKER` -- `DEBUG_LOG_SYNTH`, `DEBUG_LOG_3D`, `DEBUG_LOG_ASSETS`, `DEBUG_LOG_GPU` - -Example: -```cpp -#if defined(DEBUG_LOG_AUDIO) - DEBUG_AUDIO("[CALLBACK #%d] frames=%d\n", ++count, frames); -#endif -``` +- `DEBUG_LOG_AUDIO`, `DEBUG_LOG_RING_BUFFER`, `DEBUG_LOG_TRACKER`, `DEBUG_LOG_SYNTH`, `DEBUG_LOG_3D`, `DEBUG_LOG_ASSETS`, `DEBUG_LOG_GPU` ### Code Formatting ```bash @@ -50,6 +42,8 @@ Never format `third_party/`. - 3-line header comment - Max 500 lines (split if larger) +--- + ## Coding Style ### Core Rules @@ -61,36 +55,9 @@ Never format `third_party/`. - No `auto` (except complex iterators) - No C++ casts (`static_cast`, `reinterpret_cast`) -### Preprocessor -```cpp -#if defined(MY_TAG) - ... -#endif /* defined(MY_TAG) */ -``` - -### Struct Initialization -```cpp -// Good -const WGPUDescriptor desc = { - .format = g_format, - .dimension = WGPUTextureViewDimension_2D, -}; - -// Bad -WGPUDescriptor desc = {}; -desc.format = g_format; -desc.dimension = WGPUTextureViewDimension_2D; -``` - -### Class Keywords -```cpp - private: // 1 space indent - int field_; -``` +See `doc/CODING_STYLE.md` for detailed examples. -### Comments -- 1-line comment for non-obvious functions -- 3-line header for all source files +--- ## Development Protocols @@ -170,18 +137,18 @@ After hierarchy changes (moving files, renaming), verify: ./scripts/gen_coverage_report.sh ``` -Update scripts with hardcoded paths. +--- ## Uniform Buffer Checklist -To ensure consistency and prevent alignment-related issues, follow these guidelines when working with uniform buffers: - -1. **Define WGSL Structs:** Clearly define uniform structs in WGSL, paying close attention to type alignment (`f32`, `vec2`, `vec3`, `vec4`) and using explicit padding (`_pad0: vec2`) where necessary. -2. **Mirror in C++:** Create corresponding C++ structs that mirror the WGSL struct's definitions. -3. **`static_assert` for Size:** Every C++ struct corresponding to a WGSL uniform buffer **must** have a `static_assert` verifying its size matches the expected WGSL size. Use `sizeof(MyStruct) == EXPECTED_SIZE`. -4. **Standard Bindings:** - * **Binding 2:** Always use `CommonPostProcessUniforms` (or a similar common structure) for general per-frame data (resolution, time, beat, etc.). - * **Binding 3:** Use effect-specific parameter structs for unique effect data. -5. **Shader Consistency:** Ensure WGSL shaders correctly declare and use uniforms at the specified bindings (`@group(0) @binding(2)` for common uniforms, `@group(0) @binding(3)` for effect parameters). -6. **Validation Script:** Run `tools/validate_uniforms.py` as part of your development workflow to catch any discrepancies in size or alignment between C++ and WGSL definitions. Ensure this script passes without errors. -7. **Documentation:** Refer to `doc/UNIFORM_BUFFER_GUIDELINES.md` for detailed information on WGSL alignment rules and best practices. +To ensure consistency and prevent alignment-related issues: + +1. **Define WGSL Structs:** Pay attention to type alignment (`f32`, `vec2`, `vec3`, `vec4`) and use explicit padding where necessary. +2. **Mirror in C++:** Create corresponding C++ structs that mirror WGSL definitions. +3. **`static_assert` for Size:** Every C++ struct must have a `static_assert` verifying size matches WGSL. +4. **Standard Bindings:** + - **Binding 2:** Always use `CommonPostProcessUniforms` for per-frame data (resolution, time, beat). + - **Binding 3:** Use effect-specific parameter structs for unique data. +5. **Shader Consistency:** Ensure WGSL shaders correctly declare uniforms at specified bindings. +6. **Validation Script:** Run `tools/validate_uniforms.py` to catch discrepancies. +7. **Documentation:** Refer to `doc/UNIFORM_BUFFER_GUIDELINES.md` for detailed alignment rules. diff --git a/doc/HOWTO.md b/doc/HOWTO.md index 2595258..876d7dc 100644 --- a/doc/HOWTO.md +++ b/doc/HOWTO.md @@ -2,6 +2,8 @@ Common commands for building and testing. +--- + ## Building ### Debug Build @@ -11,10 +13,7 @@ cmake --build build -j4 ./build/demo64k ``` -Options: -- `--fullscreen`: Run in fullscreen -- `--resolution WxH`: Set window size (e.g., 1024x768) -- `--seek TIME`: Jump to timestamp (debug builds only) +Options: `--fullscreen`, `--resolution WxH`, `--seek TIME` (debug only) Keyboard: `Esc` (exit), `F` (toggle fullscreen) @@ -50,24 +49,29 @@ cmake --build build_final -j4 cmake -S . -B build -DDEMO_BUILD_TESTS=ON -DDEMO_BUILD_TOOLS=ON cmake --build build -j4 ``` -Enables tests and tools without stripping debug features. -**Note**: `DEMO_ALL_OPTIONS=ON` enables tests, tools, AND `STRIP_ALL`, which removes debug-only code (e.g., `test_demo` PeakMeterEffect). Use selective flags for debugging. +**Note:** `DEMO_ALL_OPTIONS=ON` enables tests, tools, AND `STRIP_ALL`, which removes debug-only code. Use selective flags for debugging. + +--- ## Build System -**Dependency Tracking**: CMake tracks 42 demo + 17 test assets. Editing shaders/audio auto-triggers rebuild. +**Dependency Tracking:** CMake tracks 42 demo + 17 test assets. Editing shaders/audio auto-triggers rebuild. -**Header Organization**: +**Header Organization:** - `asset_manager_dcl.h`: Forward declarations - `asset_manager.h`: Core API (GetAsset/DropAsset) - `asset_manager_utils.h`: Typed helpers +--- + ## Git Clone ```bash git clone ssh://git@51.38.51.127/~/demo.git ``` +--- + ## Audio System ### AudioEngine API @@ -92,10 +96,7 @@ audio_shutdown(); - `seek(time)`: Jump to timestamp (debug only) **Direct Synth APIs** (performance-critical): -- `synth_register_spectrogram()`: Register samples -- `synth_trigger_voice()`: Trigger playback -- `synth_get_output_peak()`: Get audio level -- `synth_render()`: Low-level rendering +- `synth_register_spectrogram()`, `synth_trigger_voice()`, `synth_get_output_peak()`, `synth_render()` **Testing:** ```cpp @@ -105,6 +106,8 @@ engine.update(1.0f); engine.shutdown(); ``` +--- + ## Auxiliary Texture Masking Share textures between effects: @@ -118,6 +121,8 @@ WGPUTextureView view = demo_->get_auxiliary_view("mask_name"); ``` See `doc/MASKING_SYSTEM.md` for details. +--- + ## Demo Timeline Edit `assets/demo.seq`: @@ -127,6 +132,8 @@ SEQUENCE 0.0 0 ``` Rebuild to update timeline. +--- + ## Testing **Run all tests:** @@ -142,56 +149,7 @@ cd build && ctest - `SynthEngineTest`: Audio synthesis - `SequenceSystemTest`: Timeline logic -## Code Coverage (macOS) -```bash -brew install lcov -./scripts/gen_coverage_report.sh [target_dir] -``` - -## Tools - -### Windows Cross-Compilation -```bash -./scripts/fetch_win_deps.sh -./scripts/build_win.sh -./scripts/run_win.sh -``` - -### spectool (Audio Analysis) -```bash -cmake -S . -B build -DDEMO_BUILD_TOOLS=ON -cmake --build build -j4 - -# Analyze -./build/spectool analyze input.wav output.spec - -# Play -./build/spectool play input.spec -``` - -### specview (Visualization) -```bash -./build/specview input.spec -``` - -### specplay (Diagnostic) -```bash -./build/specplay input.spec -# or -./build/specplay input.wav -``` -Output: Peak, RMS, clipping detection. - -### Submodule Updates -```bash -cd third_party/wgpu-native -git fetch -git checkout trunk -git reset --hard origin/trunk -cd ../.. -git add third_party/wgpu-native -git commit -m "chore: Update wgpu-native" -``` +--- ## Asset Management @@ -218,3 +176,7 @@ const uint8_t* data = GetAsset(AssetId::KICK_1, &size); ``` Build system auto-runs `asset_packer` when asset lists change. + +--- + +For developer tools reference (spectool, Windows cross-compilation, code coverage), see `doc/TOOLS_REFERENCE.md`. diff --git a/doc/TOOLS_REFERENCE.md b/doc/TOOLS_REFERENCE.md new file mode 100644 index 0000000..61412a9 --- /dev/null +++ b/doc/TOOLS_REFERENCE.md @@ -0,0 +1,89 @@ +# Developer Tools Reference + +Comprehensive reference for all developer tools in the project. + +--- + +## Windows Cross-Compilation + +```bash +# Fetch dependencies +./scripts/fetch_win_deps.sh + +# Build Windows binary +./scripts/build_win.sh + +# Run with Wine +./scripts/run_win.sh +``` + +--- + +## spectool (Audio Analysis) + +```bash +# Build +cmake -S . -B build -DDEMO_BUILD_TOOLS=ON +cmake --build build -j4 + +# Analyze WAV → .spec +./build/spectool analyze input.wav output.spec + +# Play .spec file +./build/spectool play input.spec +``` + +--- + +## specview (Visualization) + +```bash +# View spectrogram +./build/specview input.spec +``` + +Displays spectrogram visualization. + +--- + +## specplay (Diagnostic) + +```bash +# Analyze .spec file +./build/specplay input.spec + +# Or analyze .wav file +./build/specplay input.wav +``` + +Output: Peak, RMS, clipping detection. + +--- + +## Code Coverage (macOS) + +```bash +# Install lcov +brew install lcov + +# Generate coverage report +./scripts/gen_coverage_report.sh [target_dir] +``` + +Creates HTML coverage report. + +--- + +## Submodule Updates + +```bash +cd third_party/wgpu-native +git fetch +git checkout trunk +git reset --hard origin/trunk +cd ../.. +git add third_party/wgpu-native +git commit -m "chore: Update wgpu-native" +``` + +Updates wgpu-native to latest trunk. -- cgit v1.2.3