From a9a151a4fdcd46f4737abe98c654c1ec619ef425 Mon Sep 17 00:00:00 2001 From: skal Date: Sat, 7 Feb 2026 15:34:46 +0100 Subject: docs: Reorganize documentation with tiered hierarchy for context optimization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major documentation reorganization to reduce AI agent context size by ~58% and establish sustainable maintenance practices. ## File Moves (Root → doc/) - Move COMPLETED.md (new), HANDOFF*.md, *_ANALYSIS.md, *_SUMMARY.md to doc/ - Keep only 5 essential files in root: CLAUDE.md, GEMINI.md, PROJECT_CONTEXT.md, TODO.md, README.md - Result: Clean root directory with clear project essentials ## New Documentation - doc/CONTEXT_MAINTENANCE.md: Comprehensive guide for keeping context clean - 4-tier hierarchy (Critical/Technical/Design/Archive) - Maintenance schedules (after milestones, monthly, on-demand) - Size targets, red flags, workflows - Monthly checklist template - doc/COMPLETED.md: Historical archive of completed milestones - Moved "Recently Completed" sections from TODO.md and PROJECT_CONTEXT.md - Detailed completion history (February 4-7, 2026) - Frees up ~200 lines from active context ## Agent Config Updates - CLAUDE.md: Restructured with 4-tier hierarchy - Tier 1: Critical (always loaded) - 3 files - Tier 2: Technical (always loaded) - 3 files - Tier 3: Design (on-demand) - 9 files - Tier 4: Archive (rarely) - 10 files - Clear usage instructions for on-demand loading - GEMINI.md: Same tier structure + Gemini-specific state snapshot - Consistent with CLAUDE.md hierarchy - Preserved agent-specific context ## Content Optimization - PROJECT_CONTEXT.md: Removed verbose milestones (~160 lines) - Replaced with concise "Current Status" summary - Points to COMPLETED.md for history - TODO.md: Removed Task #51 detailed plan (~200 lines) - Marked Task #51 as completed - Kept only active/next tasks ## Impact - Context size: 70K → 29K tokens (58% reduction) - Root directory: 15 → 5 files (67% cleaner) - Tier 1-2 files: 7,329 words (well under 10K target) - Documented maintenance process for sustainability ## Files Changed Modified: CLAUDE.md, GEMINI.md, PROJECT_CONTEXT.md, TODO.md New: doc/COMPLETED.md, doc/CONTEXT_MAINTENANCE.md Moved: 10 technical docs from root to doc/ --- TODO.md | 384 +--------------------------------------------------------------- 1 file changed, 4 insertions(+), 380 deletions(-) (limited to 'TODO.md') diff --git a/TODO.md b/TODO.md index 83f6d35..000e619 100644 --- a/TODO.md +++ b/TODO.md @@ -2,178 +2,7 @@ This file tracks prioritized tasks with detailed attack plans. -## Recently Completed (February 7, 2026) - -- [x] **Audio Peak Measurement & Test Coverage Improvements** (February 7, 2026) - - [x] **Real-Time Peak Fix**: Fixed critical audio-visual sync bug where visual effects triggered ~400ms before audio was heard - - Root cause: Peak measured at ring buffer write time (synth_render) instead of playback time (audio callback) - - Solution: Added `get_realtime_peak()` to AudioBackend interface, implemented in MiniaudioBackend audio_callback - - Used exponential averaging: instant attack, 0.7 decay rate (1-second fade time) - - [x] **Peak Decay Optimization**: Fixed "test_demo just flashing" issue - - Old: 0.95 decay = 5.76 second fade (screen stayed white) - - New: 0.7 decay = 1.15 second fade (proper flash with smooth decay) - - [x] **SilentBackend Creation**: Test-only backend for audio.cc testing without hardware - - Created src/audio/backend/silent_backend.{h,cc} - - 7 comprehensive tests: lifecycle, peak control, tracking, playback time, buffer management - - Significantly improved audio.cc test coverage - - [x] **Backend Reorganization**: Moved all backends to src/audio/backend/ subdirectory - - Cleaner code organization, updated all includes and CMake paths - - [x] **Dead Code Removal**: Removed unused `register_spec_asset()` function - - **Result**: All 28 tests passing, perfect audio-visual sync, improved test coverage - -## Recently Completed (February 6, 2026) - -- [x] **Critical Shader Bug Fixes & Test Infrastructure** (February 6, 2026) - - [x] **Shader Validation Errors**: Fixed three critical WGSL bugs causing demo64k and test_3d_render crashes: - - Removed dead code using non-existent `inverse()` function in renderer_3d.wgsl - - Fixed `get_normal_basic()` signature mismatch in sdf_utils.wgsl and lighting.wgsl (obj_type: f32 → obj_params: vec4) - - Fixed scene_query_linear.wgsl incorrectly declaring binding 2 (BVH buffer) - was identical to BVH version due to copy-paste error - - [x] **Root Cause**: Linear shader mode expected no binding 2, but shader declared it, causing pipeline/shader mismatch - - [x] **New Test Coverage**: Created `test_shader_compilation.cc` that compiles all production shaders through WebGPU, tests both BVH and Linear composition modes, validates WGSL syntax/bindings/types - - [x] **Test Gap Analysis**: Existing test_shader_assets only checked keywords, not actual compilation. New test would have caught all three bugs. - - **Result**: demo64k runs without WebGPU errors, test_3d_render no longer crashes, 22/23 tests pass (FftTest unrelated), comprehensive regression prevention - -- [x] **Task C: Build System Optimization** (February 6, 2026) - - [x] **Header Split**: Refactored `asset_manager.h` into `asset_manager_dcl.h` (forward declarations), `asset_manager.h` (core API), and `asset_manager_utils.h` (typed helpers for TextureAsset/MeshAsset). - - [x] **Asset Dependency Tracking**: Added file-level dependencies for all assets (.wgsl shaders, .spec audio, .obj meshes). CMake now tracks 42 demo assets + 17 test assets individually. - - [x] **Performance Impact**: Editing TextureAsset/MeshAsset helpers: 4.82s → 2.01s (58% faster). Editing shaders now triggers correct rebuild (was broken before - stale code bug fixed). - - [x] **Developer Workflow**: No more manual `touch demo_assets.txt` workaround needed. Edit any asset file and rebuild works correctly. - - **Result**: Critical correctness bug fixed (shader changes were not triggering rebuilds). Build system now has proper dependency tracking for all source and asset files. - -## Recently Completed (February 5, 2026) - -- [x] **Audio Lifecycle Refactor (Task #56)**: - - [x] **Phase 1: Design & Prototype**: Created `AudioEngine` class and `SpectrogramResourceManager` to manage audio subsystem initialization and resource loading with lazy loading strategy. - - [x] **Phase 2: Test Migration**: Migrated all tracker-related tests (`test_tracker.cc`, `test_tracker_timing.cc`, `test_variable_tempo.cc`, `test_wav_dump.cc`) to use AudioEngine instead of direct synth/tracker initialization. - - [x] **Phase 3: Production Integration**: Updated `main.cc` to use AudioEngine, eliminating initialization order fragility in production code. Fixed pre-existing demo crash (procedural texture loading). - - [x] **Phase 4: Cleanup & Documentation**: Removed backwards compatibility (synth_init() from audio_init()), updated HOWTO.md and CONTRIBUTING.md with AudioEngine usage patterns and best practices. - - **Result**: Initialization order dependency eliminated. All 20 tests pass. Binary size impact <500 bytes. Demo runs successfully. - -- [x] **Physics & Collision (Task #49)**: - - [x] **CPU-Side SDF Library**: Implemented `sdSphere`, `sdBox`, `sdTorus`, `sdPlane` in `src/3d/sdf_cpu.h` using `mini_math.h`. Added `calc_normal` for numerical gradients. - - [x] **BVH Construction**: Implemented `BVHNode` and `BVHBuilder` in `src/3d/bvh.h/cc`. Optimized broad-phase collision queries with `BVH::Query`. - - [x] **Physics System**: Created `PhysicsSystem` in `src/3d/physics.h/cc` implementing semi-implicit Euler integration, broad-phase BVH culling, and narrow-phase SDF proxy probing. - - [x] **Integration & Visualization**: Added `velocity`, `mass`, `is_static` to `Object3D`. Integrated physics loop into `test_3d_render.cc` and added BVH wireframe visualization to `VisualDebug`. - -- [x] **Audio Playback Debugging & Core Audio Optimization**: - - [x] **Core Audio Timing Fix**: Resolved stop-and-go audio glitches caused by timing mismatch. Core Audio optimized for 44.1kHz (10ms periods), but our 32kHz system expected uniform ~13.78ms callbacks, causing resampling jitter. Fix: Added `allowNominalSampleRateChange = TRUE` to force OS-level 32kHz native and `performanceProfile = conservative` for 4096-frame buffers (128ms). Result: Stable ~128ms callbacks, <1ms jitter, zero underruns. - - [x] **Ring Buffer Capacity**: Increased from 200ms to 400ms (25,600 samples) to handle tempo scaling headroom. Added comprehensive bounds checking with abort() on violations. - - [x] **Tempo-Scaled Buffer Fill**: Fixed critical bug where buffer pre-fill didn't scale dt by tempo (`audio_render_ahead(g_music_time, dt * g_tempo_scale)`). Buffer now maintains 400ms fullness during 2.0x acceleration. - - [x] **Extensive Diagnostics**: Added high-resolution timing tracking (clock_gettime), callback interval measurement, buffer level monitoring, underrun detection. All under conditional compilation for future debugging. - -- [x] **NOTE_ Parsing Fix & Sample Caching**: - - [x] **Parser Bug Fix**: Fixed `is_note_name()` checking only first letter (A-G), causing ASSET_KICK_1 → A0 (27.5 Hz) false positives. Required "NOTE_" prefix to distinguish notes from assets. Updated music.track to use NOTE_E2, NOTE_G4 format. - - [x] **Resource Exhaustion Discovery**: Found every event created NEW spectrogram (14 unique samples → 228 registrations). MAX_SPECTROGRAMS=16 insufficient, causing spectrogram_id=-1 errors. - - [x] **Comprehensive Caching**: Implemented cache in `tracker_init()` pre-registering all samples. Assets: loaded once from AssetManager. Generated notes: created once, stored in persistent pool. All cached synth_ids reused. - - [x] **Memory Reduction**: MAX_SPECTROGRAMS reduced from 256 (temporary workaround) to 32 (2.3x headroom over 14 actual). 88% memory savings vs uncached approach. - - [x] **Resource Analysis Tool**: Enhanced `tracker_compiler` to report required/recommended pool sizes, cache potential, memory usage. Analysis showed 152/228 required without caching, 14 with caching. - -- [x] **Debug Logging Infrastructure**: - - [x] **Central Debug Header**: Created `src/util/debug.h` with 7 category macros (DEBUG_LOG_AUDIO, DEBUG_LOG_RING_BUFFER, DEBUG_LOG_TRACKER, DEBUG_LOG_SYNTH, DEBUG_LOG_3D, DEBUG_LOG_ASSETS, DEBUG_LOG_GPU). - - [x] **CMake Integration**: Added `DEMO_ENABLE_DEBUG_LOGS` option defining `DEBUG_LOG_ALL` to enable all categories. Individual categories can be enabled selectively. - - [x] **Source Code Conversion**: Updated miniaudio_backend.cc (timing, device config), ring_buffer.cc (underruns), tracker.cc (validation), synth.cc (parameter checks) to use category macros. - - [x] **Zero Runtime Cost**: Default build: macros compile to `((void)0)`. Debug build: comprehensive logging preserved for troubleshooting. - - [x] **Pre-Commit Policy**: Updated CONTRIBUTING.md requiring debug build verification before significant commits to ensure diagnostic code remains maintainable. - - [x] **Verification**: Both default and debug builds compile without errors. Audio playback works correctly in both modes. - -- [x] **Event-Based Tracker for Tempo Scaling**: - - [x] **Problem Identified**: Notes within patterns didn't accelerate with tempo changes. Pattern events were pre-composited into single spectrograms at fixed positions. - - [x] **Refactored Architecture**: Changed from pattern compositing to individual event triggering. Each TrackerEvent now triggers as separate voice. - - [x] **Dynamic Beat Calculation**: `elapsed_beats = (music_time - start_time) / beat_duration` allows notes to respect tempo scaling. - - [x] **ActivePattern Tracking**: Added structure to track pattern_id, start_music_time, and next_event_idx for each active pattern instance. - - [x] **Removed Compositing Logic**: Deleted paste_spectrogram approach that baked events at fixed frame offsets. - - [x] **Full Tempo Scaling**: At 2.0x tempo, both pattern triggering AND note spacing play 2x faster. At 0.5x tempo, both play 2x slower. - - [x] **Testing**: Updated test_tracker.cc to verify individual event triggers at specific beat times. All 17 tests pass. - - [x] **WAV Verification**: Confirmed with WAV dump showing 61.24s music time in 60s physical time during tempo transitions. - -- [x] **WAV Dump Backend for Debugging**: - - [x] **Implementation**: Created WavDumpBackend implementing AudioBackend interface to render audio offline to .wav files. - - [x] **Command-Line Option**: Added `--dump_wav output.wav` flag to enable offline rendering instead of live playback. - - [x] **Stereo Bug Fix**: Fixed critical mono/stereo mismatch. Synth outputs STEREO (interleaved L/R) but initial implementation wrote MONO. - - [x] **Correct Allocation**: Changed to allocate `frames * 2` samples and write stereo format (num_channels = 2). - - [x] **Format Matching**: WAV header now correctly specifies 16-bit PCM, stereo, 32kHz (matches live audio exactly). - - [x] **Regression Test**: Added test_wav_dump.cc with critical assertion `assert(header.num_channels == 2)` to prevent future mismatches. - - [x] **Tempo Simulation**: WAV dump backend simulates tempo scaling matching main.cc logic for accurate offline rendering. - - [x] **All Tests Pass**: 17/17 tests pass including WAV format verification. - -- [x] **Variable Tempo System**: - - [x] **Music Time Abstraction**: Implemented unified music time in `main.cc` that advances at `tempo_scale` rate, decoupling from physical time. - - [x] **Tempo Control**: Added `g_tempo_scale` (default 1.0) allowing future dynamic tempo changes without pitch shifting. - - [x] **Reset Tricks**: Comprehensive tests verify 2x speed-up and 2x slow-down reset techniques work correctly. - - [x] **Test Suite**: Created `test_variable_tempo.cc` with 6 test scenarios: basic scaling, speed-up/slow-down resets, pattern density swap, continuous acceleration, oscillating tempo. - - [x] **Perfect Verification**: All tests pass, confirming music_time advances correctly at variable rates (e.g., 2.0x tempo → 2x faster triggering). - - [x] **Zero Pitch Shift**: Spectrograms unchanged, only trigger timing affected (as designed). - - [x] **Documentation**: Created `ANALYSIS_VARIABLE_TEMPO_V2.md` explaining simplified trigger-timing approach. - -- [x] **Task #51.3 & #51.4: Tracker Test Suite & Build Integration**: - - [x] **Comprehensive Test Suite**: Created `test_tracker_timing.cc` with 7 test scenarios using MockAudioBackend. - - [x] **Simultaneous Trigger Verification**: Confirmed multiple patterns at same time trigger with **0.000ms delta** (perfect sync). - - [x] **Test Coverage**: Basic recording, progressive triggering, simultaneous triggers, monotonicity, seek/fast-forward, timestamp clustering, render integration. - - [x] **Real Music Data**: Tests use generated tracker music data for realistic validation. - - [x] **Build Integration**: Added to CMake with proper dependencies on generated music data. - - [x] **All Tests Pass**: 15/15 tests passing (100% success rate). - -- [x] **Task #51.2: Mock Audio Backend**: - - [x] **Event Recording**: Created `VoiceTriggerEvent` structure to capture timestamp, spectrogram_id, volume, and pan. - - [x] **MockAudioBackend Class**: Implemented test-only backend with event recording and time tracking capabilities. - - [x] **Time Management**: Added `advance_time()`, `set_time()`, and `get_current_time()` for deterministic testing. - - [x] **Frame Rendering Hook**: Implemented `on_frames_rendered()` to automatically update time based on audio frames (32kHz). - - [x] **Synth Integration**: Verified mock backend correctly captures voice triggers from synth engine. - - [x] **Comprehensive Tests**: Created `test_mock_backend.cc` with 6 test scenarios covering all mock functionality. - - [x] **Build Integration**: Added mock backend to test builds, all 14 tests pass. - -- [x] **Task #51.1: Audio Backend Abstraction**: - - [x] **Interface Created**: Defined `AudioBackend` interface in `src/audio/audio_backend.h` with hooks for voice triggering and frame rendering. - - [x] **Production Backend**: Moved miniaudio implementation from `audio.cc` to `MiniaudioBackend` class, maintaining backward compatibility. - - [x] **Audio Refactoring**: Updated `audio.cc` to use backend abstraction with automatic fallback to `MiniaudioBackend`. - - [x] **Event Hooks**: Added time tracking to `synth.cc` with `on_voice_triggered()` callbacks (guarded by `!STRIP_ALL`). - - [x] **Verification Test**: Created `test_audio_backend.cc` to verify backend injection and event recording work correctly. - - [x] **Build Integration**: Updated CMakeLists.txt to include new backend files and link audio tests properly with util/procedural dependencies. - - [x] **Zero Size Impact**: All test infrastructure under `#if !defined(STRIP_ALL)`, production path unchanged. - -- [x] **Task #50: WGSL Modularization**: - - [x] **Recursive Composition**: Updated `ShaderComposer` to support recursive `#include "snippet_name"` directives with cycle detection. - - [x] **Granular SDF Library**: Extracted `math/sdf_shapes.wgsl`, `math/sdf_utils.wgsl`, `render/shadows.wgsl`, `render/scene_query.wgsl`, and `render/lighting_utils.wgsl`. - - [x] **Pipeline Update**: Refactored `Renderer3D` and `renderer_3d.wgsl` to use the new modular system, reducing C++-side dependency management. - - [x] **Platform Fix**: Resolved `WGPUShaderSourceWGSL` usage on macOS to ensure compatibility with composed shader strings. - -- [x] **Task #48: Improve Audio Coverage**: - - [x] **New Tests**: Added `test_dct` (100% coverage for transforms) and `test_audio_gen` (94% coverage for procedural audio). - - [x] **Enhanced Tests**: Updated `test_synth` to cover rendering loop, double-buffering, and resource exhaustion. - - [x] **Coverage Boost**: Increased `src/audio/` coverage from ~42% to 93%. -- [x] **Task #47: Improve Asset Manager Coverage**: - - [x] **New Tests**: Added tests for unknown procedural functions, generation failures, and edge cases in `src/tests/test_assets.cc`. - - [x] **Tooling Update**: Downgraded `asset_packer` validation error to warning to allow testing invalid assets. - - [x] **Coverage Boost**: Increased `src/util/asset_manager.cc` coverage from 71% to 88%. -- [x] **Task #46: Enhance Coverage Script**: Updated `scripts/gen_coverage_report.sh` to accept an optional directory argument for targeted coverage reports (e.g., `src/procedural`). -- [x] **Task #45: Improve Procedural Generation Coverage**: - - [x] **Unit Tests:** Implemented comprehensive tests for `gen_perlin`, `make_periodic`, and default parameter handling in `src/tests/test_procedural.cc`. - - [x] **Coverage Boost:** Increased `src/procedural/generator.cc` coverage from 38% to 96%. -- [x] **Task #44: Developer Tooling (Coverage)**: - - [x] **Implement Code Coverage:** Added `DEMO_ENABLE_COVERAGE` CMake option and created `scripts/gen_coverage_report.sh` to generate HTML coverage reports using `lcov` on macOS. - - [x] **Documentation:** Updated `doc/HOWTO.md` with usage instructions. -- [x] **Skybox & Two-pass Rendering Stability**: - - [x] **Fixed Two-pass Rendering:** Implemented mandatory clear operations for color and depth when the skybox is absent, preventing black screens and depth validation errors. - - [x] **Implemented Rotating Skybox:** Added `inv_view_proj` to `GlobalUniforms` and updated the skybox shader to perform world-space ray unprojection (`inv_view_proj`), enabling correct rotation with the camera. - - [x] **Enhanced Procedural Noise:** Implemented a multi-octave Value Noise generator for higher-quality skybox textures. - - [x] **Scene Integrity:** Restored proper object indexing and removed redundant geometry, ensuring the floor grid and objects render correctly. - -- [x] **Task #57: Interactive Timeline Editor (Phase 1 Complete)** 🎉 - - [x] **Core Parser & Renderer**: Implemented demo.seq parser with BPM, beat notation, priority modifiers. Gantt-style timeline rendering with dynamic sequence/effect positioning. - - [x] **Drag & Drop**: Sequences and effects draggable along timeline with proper offset calculation. Fixed critical e.target vs e.currentTarget bug preventing erratic jumping. - - [x] **Resize Handles**: Left/right handles on selected effects. Allow negative relative times (effects extend before sequence start). - - [x] **Snap-to-Beat**: Checkbox toggle with beat markers. Automatic snapping when dragging in beat mode. - - [x] **Properties Panel**: Floating, collapsible panel with auto-apply (no Apply button). Properties update on input change. - - [x] **Stack-Order Priority**: Up/Down buttons to reorder effects within sequence. Stack position determines rendering priority (higher index = rendered later = on top). - - [x] **Priority Modifiers**: Toggle button for "Same as Above" (= modifier) vs "Increment" (+ modifier). Visual feedback in button text. - - [x] **Diagonal Scroll**: Mouse wheel navigation with 10% viewport slack. Smooth following to time-ordered sequence cascade. Flash animation on active sequence change. - - [x] **Dynamic Bounds**: Sequence visual bounds calculated from min/max effect times. Cumulative Y positioning prevents overlap. - - [x] **Waveform Visualization**: Load WAV files (via Web Audio API) and display waveform above timeline. Scales with zoom (pixels per second). Documented integration with `--dump_wav` flag. - - [x] **UI Polish**: Hoverable sequence names (large centered text, fades on hover). No scrollbars (hidden CSS). Clean, minimal interface. - - [x] **File I/O**: Load/save demo.seq files with proper serialization. BPM parsing and display. Re-order sequences by time. - - [x] **Delete & Add**: Delete sequences/effects. Add new sequences (at time 0, priority 0). - - **Result**: Fully functional timeline editor ready for production use. Phase 1.1 complete (basic editing, snap-to-beat, waveform). Phase 1.2 (Add Effect button) and Phase 2.5 (music.track visualization) documented in ROADMAP.md. - - **Files**: `tools/timeline_editor/index.html` (~1200 lines), `README.md`, `ROADMAP.md` (3 phases, 117-161 hour estimate). +**Note:** For a history of recently completed tasks, see `COMPLETED.md`. ## Critical Fixes @@ -287,11 +116,9 @@ This file tracks prioritized tasks with detailed attack plans. ## Priority 4: Developer Tooling & CI **Goal**: Improve developer workflows, code quality, and release processes. -- [ ] **Task #51: Tracker Timing Verification** - - [x] **Task #51.1: Audio Backend Abstraction**: Create an interface to separate audio output from synth logic, enabling testable backends. - - [x] **Task #51.2: Mock Audio Backend**: Implement a test backend that records voice trigger events with precise timestamps. - - [x] **Task #51.3: Tracker Test Suite**: Create `test_tracker.cc` to verify pattern triggering, timing accuracy, and synchronization. - - [x] **Task #51.4: Integration with Build**: Wire up tests to CMake and ensure they run in CI. +- [x] **Task #51: Tracker Timing Verification** ✅ COMPLETED + - Created robust audio testing infrastructure with mock backend abstraction + - All subtasks complete, moved to COMPLETED.md ## Phase 2: Size Optimization (Final Goal) @@ -451,207 +278,4 @@ This file tracks prioritized tasks with detailed attack plans. --- -## Task #51: Tracker Timing Verification - Detailed Attack Plan - -**Problem Statement**: The tracker and synthesizer have audio sync issues. There's no robust way to verify that tracker patterns trigger at the correct timestamps without running the full audio hardware stack. - -**Goal**: Implement a testable audio backend abstraction with event recording capabilities to verify tracker timing accuracy. - -### Task #51.1: Audio Backend Abstraction -**Objective**: Decouple audio output from synthesis logic to enable testing without hardware. - -**Implementation Steps**: -- [ ] **Create `src/audio/audio_backend.h`**: - - Define `AudioBackend` interface with pure virtual methods: - - `init()`: Initialize backend resources - - `start()`: Start audio playback/recording - - `shutdown()`: Clean up resources - - `on_voice_triggered(timestamp, spec_id, volume, pan)`: Hook for voice events - - Add `#if !defined(STRIP_ALL)` guards around test-only methods - -- [ ] **Create `src/audio/miniaudio_backend.h` and `.cc`**: - - Move current miniaudio implementation from `audio.cc` to `MiniaudioBackend` class - - Implement `AudioBackend` interface - - Keep production behavior identical (no regressions) - - This backend does NOT record events (production path) - -- [ ] **Refactor `src/audio/audio.cc`**: - - Add global `AudioBackend* g_audio_backend` pointer - - Add `void audio_set_backend(AudioBackend* backend)` function (under `!STRIP_ALL`) - - Default to `MiniaudioBackend` if no backend is set - - Replace direct miniaudio calls with backend interface calls - -- [ ] **Update `src/audio/synth.cc`**: - - Add external hook: `extern AudioBackend* g_audio_backend_for_events` - - In `synth_trigger_voice()`, call `backend->on_voice_triggered()` if backend exists - - Ensure hook is `#if !defined(STRIP_ALL)` guarded - -**Size Impact**: Zero (test code stripped in final build). - -**Validation**: Existing tests (`test_synth.cc`) must pass unchanged. - ---- - -### Task #51.2: Mock Audio Backend -**Objective**: Create a test-only backend that records all audio events with timestamps. - -**Implementation Steps**: -- [ ] **Create `src/audio/mock_audio_backend.h` and `.cc`** (under `#if !defined(STRIP_ALL)`): - - Define `struct VoiceTriggerEvent`: - ```cpp - struct VoiceTriggerEvent { - float timestamp_sec; - int spectrogram_id; - float volume; - float pan; - }; - ``` - - Implement `MockAudioBackend` class: - - Maintain `std::vector recorded_events` - - Override `on_voice_triggered()` to record events with current time - - Add `const std::vector& get_events() const` - - Add `void clear_events()` - - Add `void advance_time(float delta_sec)` to simulate time progression - - Implement `init()`, `start()`, `shutdown()` as no-ops - -- [ ] **Time Tracking**: - - Add `float current_time_sec` member to `MockAudioBackend` - - Increment `current_time_sec` in `advance_time()` - - Use `current_time_sec` as timestamp when recording events - -- [ ] **Synth Integration**: - - When `synth_render()` is called, calculate frames rendered - - Notify backend of time elapsed: `frames / sample_rate` - - Update mock's internal clock accordingly - -**Testing**: Create minimal unit test in `test_tracker.cc` to verify event recording works. - ---- - -### Task #51.3: Tracker Test Suite -**Objective**: Comprehensive tests for tracker pattern triggering and timing accuracy. - -**Implementation Steps**: -- [ ] **Create `src/tests/test_tracker.cc`**: - - - **Test 1: Single Pattern Trigger** - - Define a minimal `TrackerScore` with 1 pattern at `t=1.0s` - - Set up mock backend - - Call `tracker_update(0.5)` → verify no events - - Call `tracker_update(1.0)` → verify 1 event recorded - - Validate event timestamp matches expected trigger time - - - **Test 2: Multiple Pattern Triggers** - - Score with 3 patterns at `t=0.5s, 1.0s, 2.0s` - - Progressively call `tracker_update()` with increasing times - - Verify each pattern triggers exactly once at correct time - - - **Test 3: Event Timing Accuracy** - - Pattern with multiple events at different beat offsets - - Verify each event's timestamp matches: `pattern_start_time + (beat * beat_duration)` - - Use tolerance: `±1 frame` (1/32000 sec ≈ 31.25µs) - - - **Test 4: BPM Scaling** - - Same pattern tested at different BPMs (60, 120, 180) - - Verify beat-to-time conversion is accurate: `beat_sec = 60.0 / bpm` - - - **Test 5: Pattern Overlap** - - Two patterns with overlapping time ranges - - Verify both trigger correctly without interference - - - **Test 6: Asset vs Procedural Samples** - - Pattern using both asset-based spectrograms and procedural notes - - Verify both types render and trigger correctly - - - **Test 7: Seek/Fast-Forward Simulation** - - Simulate `audio_render_silent()` behavior - - Start at `t=0`, fast-forward to `t=10.0s` - - Verify all patterns in range [0, 10] triggered correctly - -- [ ] **Helper Functions**: - ```cpp - void assert_event_at_time(const std::vector& events, - float expected_time, float tolerance = 0.001f); - - void assert_event_count(const std::vector& events, - int expected_count); - - TrackerScore create_test_score(const std::vector& trigger_times, - float bpm = 120.0f); - ``` - -**Coverage Target**: 95%+ for `src/audio/tracker.cc`. - ---- - -### Task #51.4: Integration with Build -**Objective**: Wire up tests to CMake and ensure they run automatically. - -**Implementation Steps**: -- [ ] **Update `src/CMakeLists.txt`**: - - Add `mock_audio_backend.cc` to test-only sources (under `DEMO_BUILD_TESTS`) - - Link `test_tracker` executable with audio subsystem library - -- [ ] **Add test to CTest**: - ```cmake - if(DEMO_BUILD_TESTS) - add_executable(test_tracker tests/test_tracker.cc audio/mock_audio_backend.cc) - target_link_libraries(test_tracker PRIVATE audio_lib util_lib) - add_test(NAME TrackerTest COMMAND test_tracker) - endif() - ``` - -- [ ] **Verify in CI**: - - Run `cmake --build build && cd build && ctest` - - Ensure `test_tracker` runs and passes - - Check coverage report includes tracker.cc - -**Validation**: `ctest` output shows `TrackerTest: PASSED`. - ---- - -## Implementation Layout Summary - -### New Files -``` -src/audio/audio_backend.h # Interface definition -src/audio/miniaudio_backend.h # Production backend (header) -src/audio/miniaudio_backend.cc # Production backend (impl) -src/audio/mock_audio_backend.h # Test backend (header, !STRIP_ALL) -src/audio/mock_audio_backend.cc # Test backend (impl, !STRIP_ALL) -src/tests/test_tracker.cc # Comprehensive tracker tests -``` - -### Modified Files -``` -src/audio/audio.cc # Backend abstraction layer -src/audio/synth.cc # Add event hooks -src/CMakeLists.txt # Add new files and tests -``` - -### File Structure -``` -src/audio/ -├── audio_backend.h [NEW] Interface (50 lines) -├── miniaudio_backend.h [NEW] Header (30 lines) -├── miniaudio_backend.cc [NEW] Production impl (~100 lines, moved from audio.cc) -├── mock_audio_backend.h [NEW] Test header (60 lines) -├── mock_audio_backend.cc [NEW] Test impl (~120 lines) -├── audio.h [MODIFIED] Add backend setter -├── audio.cc [MODIFIED] Use backend abstraction (~30 lines changed) -├── synth.cc [MODIFIED] Add event hook (~10 lines) -└── tracker.cc [NO CHANGE] - -src/tests/ -└── test_tracker.cc [NEW] Test suite (~400 lines) -``` - -### Code Organization Principles -1. **Zero Size Impact**: All test infrastructure under `#if !defined(STRIP_ALL)` -2. **Backward Compatible**: Production path unchanged, existing tests pass -3. **Clean Separation**: Interface-based design, easy to add more backends later -4. **Testable**: Mock backend has minimal dependencies (no hardware/threads) - ---- - ## Future Goals \ No newline at end of file -- cgit v1.2.3