summaryrefslogtreecommitdiff
path: root/doc/HOWTO.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/HOWTO.md')
-rw-r--r--doc/HOWTO.md468
1 files changed, 109 insertions, 359 deletions
diff --git a/doc/HOWTO.md b/doc/HOWTO.md
index 55580ba..967b554 100644
--- a/doc/HOWTO.md
+++ b/doc/HOWTO.md
@@ -1,468 +1,218 @@
# How To
-This document describes the common commands for building and testing the project.
-
-## Features
-
-* **Real-time Audio Synthesis**: The demo features a multi-voice synthesizer that generates audio in real-time from spectrograms.
-* **Dynamic Sound Updates**: Spectrograms can be updated dynamically and safely during runtime for evolving soundscapes.
-* **Unified Audio Engine**: The `AudioEngine` class manages audio subsystem initialization, ensuring correct setup order and eliminating initialization fragility.
+Common commands for building and testing.
## Building
### Debug Build
-
-To run the demo in fullscreen mode, use the `--fullscreen` command-line option:
-
```bash
cmake -S . -B build
-cmake --build build
-./build/demo64k --fullscreen
+cmake --build build -j4
+./build/demo64k
```
-To run in a specific resolution, use the `--resolution` option:
-```bash
-./build/demo64k --resolution 1024x768
-```
+Options:
+- `--fullscreen`: Run in fullscreen
+- `--resolution WxH`: Set window size (e.g., 1024x768)
+- `--seek TIME`: Jump to timestamp (debug builds only)
-Keyboard Controls:
-* `Esc`: Exit the demo.
-* `F`: Toggle fullscreen mode.
+Keyboard: `Esc` (exit), `F` (toggle fullscreen)
### Size-Optimized Build
-
```bash
cmake -S . -B build -DDEMO_SIZE_OPT=ON
-cmake --build build
+cmake --build build -j4
```
-### Final / Strip Build
-
-To produce the smallest possible binary (stripping all unnecessary code like command-line parsing and debug info), use the `DEMO_STRIP_ALL` option:
-
+### Strip Build (64k Target)
```bash
cmake -S . -B build -DDEMO_STRIP_ALL=ON
-cmake --build build
+cmake --build build -j4
```
-In this mode, the demo will always start in fullscreen.
-
-### Final-Final Build (Maximum Stripping)
-
-For the absolute smallest binary (removing ALL error checking), use the `DEMO_FINAL_STRIP` option:
+Always starts in fullscreen. Full error checking enabled.
+### Final Build (Maximum Stripping)
```bash
-# Method 1: CMake target (from normal build directory)
-cd build
-make final
-
-# Method 2: Convenience script (creates build_final/ directory)
./scripts/build_final.sh
-
-# Method 3: Manual CMake configuration
+# or
cmake -S . -B build_final -DDEMO_FINAL_STRIP=ON
-cmake --build build_final
+cmake --build build_final -j4
```
+⚠️ Removes ALL error checking. Use only for final release.
-**⚠️ WARNING:** FINAL_STRIP removes ALL error checking (bounds checks, null checks, assertions). This saves ~500-600 bytes but means crashes will have no error messages. Use ONLY for final release builds, never for development or testing.
-
-**Build Mode Hierarchy:**
-- **Debug**: Full error checking + debug features
-- **STRIP_ALL**: Full error checking, no debug features (~64k target)
-- **FINAL_STRIP**: No error checking, no debug features (absolute minimum size)
-
-### Developer Build (All Options)
-
-To enable all features at once (tests, tools, size optimizations, and stripping) for a comprehensive check:
+**Build Hierarchy:**
+- Debug: Full checks + debug features
+- STRIP_ALL: Full checks, no debug (~64k target)
+- FINAL_STRIP: No checks, no debug (absolute minimum)
+### Developer Build
```bash
cmake -S . -B build -DDEMO_ALL_OPTIONS=ON
-cmake --build build
+cmake --build build -j4
```
+Enables tests, tools, size optimizations.
-### Build System Notes
+## Build System
-**Incremental Builds**: The build system tracks all source files (.cc, .h) and asset files (.wgsl shaders, .spec audio, .obj meshes) as dependencies. Editing any file will trigger the necessary rebuilds automatically.
+**Dependency Tracking**: CMake tracks 42 demo + 17 test assets. Editing shaders/audio auto-triggers rebuild.
-**Asset Dependency Tracking**: CMake tracks 42 demo assets and 17 test assets individually. Changing a shader file (e.g., `assets/final/shaders/renderer_3d.wgsl`) automatically regenerates the asset bundle and recompiles dependent files. No manual workarounds needed.
-
-**Header Organization**: The `asset_manager` system is split into three headers for faster incremental builds:
-- `asset_manager_dcl.h`: Forward declarations (use in headers)
+**Header Organization**:
+- `asset_manager_dcl.h`: Forward declarations
- `asset_manager.h`: Core API (GetAsset/DropAsset)
-- `asset_manager_utils.h`: Typed helpers (TextureAsset/MeshAsset)
-
-Include only what you need to minimize rebuild times.
-
-## git cloning
-
-if you have the public ssh key authorized on the VPS, you can use
-
-`git clone ssh://git@51.38.51.127/~/demo.git`
+- `asset_manager_utils.h`: Typed helpers
-to clone the repo and work on it.
+## Git Clone
+```bash
+git clone ssh://git@51.38.51.127/~/demo.git
+```
## Audio System
-### AudioEngine
-
-The audio subsystem uses `AudioEngine` to manage initialization and lifecycle. This ensures correct setup order and eliminates initialization fragility.
-
-**Usage in production code:**
-
+### AudioEngine API
```cpp
#include "audio/audio_engine.h"
-// Initialize audio backend (miniaudio)
audio_init();
-
-// Initialize audio engine (manages synth + tracker)
static AudioEngine g_audio_engine;
g_audio_engine.init();
-// In main loop: update with music time
+// Main loop
g_audio_engine.update(music_time);
-// Cleanup
g_audio_engine.shutdown();
audio_shutdown();
```
-**What to use AudioEngine for:**
-- Initialization: `engine.init()` replaces separate `synth_init()` + `tracker_init()` calls
-- Updates: `engine.update(music_time)` replaces `tracker_update()`
-- Cleanup: `engine.shutdown()` ensures proper teardown
-- Seeking: `engine.seek(time)` for timeline navigation (debug builds only)
+**Methods:**
+- `init()`: Initialize synth + tracker
+- `update(music_time)`: Update music state
+- `shutdown()`: Cleanup
+- `seek(time)`: Jump to timestamp (debug only)
-**Direct synth API usage:**
-For performance-critical or low-level operations, direct synth API calls are valid:
-- `synth_register_spectrogram()` - Register audio samples
-- `synth_trigger_voice()` - Trigger sound playback
-- `synth_get_output_peak()` - Get audio peak for visualization
-- `synth_render()` - Low-level audio rendering
+**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
**Testing:**
-Tests should use `AudioEngine` for initialization:
-
```cpp
-#include "audio/audio_engine.h"
-
-void test_example() {
- AudioEngine engine;
- engine.init();
-
- // Test code here
- engine.update(1.0f);
-
- engine.shutdown();
-}
+AudioEngine engine;
+engine.init();
+engine.update(1.0f);
+engine.shutdown();
```
-For low-level synth-only tests, you can still call `synth_init()` directly.
-
## Auxiliary Texture Masking
-The project supports inter-effect texture sharing via the auxiliary texture registry. This allows effects to generate textures (masks, shadow maps, etc.) and make them available to other effects within the same frame.
-
-**Common use case:** Screen-space partitioning where different scenes render to complementary regions.
-
+Share textures between effects:
```cpp
-class MaskGeneratorEffect : public Effect {
- void init(MainSequence* demo) override {
- demo_ = demo;
- // Register a named auxiliary texture
- demo->register_auxiliary_texture("my_mask", width_, height_);
- }
-
- void compute(WGPUCommandEncoder encoder, ...) override {
- // Generate mask to auxiliary texture
- WGPUTextureView mask_view = demo_->get_auxiliary_view("my_mask");
- // ... render mask
- }
-
- void render(WGPURenderPassEncoder pass, ...) override {
- // Use mask in scene rendering
- WGPUTextureView mask_view = demo_->get_auxiliary_view("my_mask");
- // ... render scene with mask
- }
-};
-
-class MaskUserEffect : public Effect {
- void render(WGPURenderPassEncoder pass, ...) override {
- // Reuse mask from MaskGeneratorEffect
- WGPUTextureView mask_view = demo_->get_auxiliary_view("my_mask");
- // ... render scene with inverted mask
- }
-};
-```
-
-See `doc/MASKING_SYSTEM.md` for detailed architecture and examples.
-
-## Debugging
-
-### Seeking / Fast-Forward
-In non-stripped builds, you can jump to any timestamp in the demo. This will simulate all audio logic and GPU physics (compute shaders) frame-by-frame from the start until the target time, then begin real-time playback.
+// Generator effect
+demo->register_auxiliary_texture("mask_name", width, height);
+WGPUTextureView view = demo_->get_auxiliary_view("mask_name");
-```bash
-./build/demo64k --seek 15.5
+// Consumer effect
+WGPUTextureView view = demo_->get_auxiliary_view("mask_name");
```
+See `doc/MASKING_SYSTEM.md` for details.
-## Demo Choreography
-
-### Sequence Compiler
-The demo timeline is managed via a textual description in `assets/demo.seq`. This file is transpiled into C++ code during the build process.
+## Demo Timeline
-**Format:**
+Edit `assets/demo.seq`:
```text
-# Starts a new sequence layer (global_start, priority)
SEQUENCE 0.0 0
- # Adds an effect to the sequence (ClassName, local_start, local_end, priority, [constructor_args...])
EFFECT HeptagonEffect 0.0 60.0 0
```
+Rebuild to update timeline.
-To update the demo's timing or layering, simply edit `assets/demo.seq` and rebuild.
-
-## Tools
-
-If you are on macOS and want to test the Windows build:
-
-1. Build it: `./scripts/build_win.sh`
-2. Run it: `./scripts/run_win.sh`
-
-Note: WebGPU support in Wine requires a Vulkan-capable backend (like MoltenVK on macOS).
-Note2: make sure you run the script `./scripts/fetch_win_deps.sh` before, to install Win64 dependencies.
-
-### Testing
-
-**Commit Policy**: Always run tests before committing. Refer to `CONTRIBUTING.md` for details.
-
-To build and run the tests, you need to enable the `DEMO_BUILD_TESTS` option in CMake. Refer to the "Developer Build (All Options)" section for the easiest way to enable this.
-
-Available test suites:
-* `HammingWindowTest`: Verifies the properties of the Hamming window function.
-* `MathUtilsTest`: Verifies basic math utilities.
-* `SynthEngineTest`: Verifies the core functionality of the audio synthesizer.
-* `SpectoolEndToEndTest`: Performs an end-to-end test of the `spectool` by generating a WAV file, analyzing it, and verifying the output.
-* `SequenceSystemTest`: Tests the logic of the sequence and effect system (activation, timing, priority), but **not** actual GPU rendering output, as this requires extensive mocking.
+## Testing
+**Run all tests:**
```bash
cmake -S . -B build -DDEMO_BUILD_TESTS=ON
-cmake --build build
-cd build
-ctest
-cd ..
+cmake --build build -j4
+cd build && ctest
```
-### Code Coverage (macOS only)
-
-To generate an HTML code coverage report for the project:
-
-1. **Install lcov:**
- ```bash
- brew install lcov
- ```
-
-2. **Run the coverage script:**
- ```bash
- ./scripts/gen_coverage_report.sh [optional_target_dir]
- ```
- This script will configure the build with `-DDEMO_ENABLE_COVERAGE=ON`, run the tests, and generate a report in `build_coverage/coverage_report/`. It will then attempt to open the report in your browser.
-
- **Examples:**
- * Full project report:
- ```bash
- ./scripts/gen_coverage_report.sh
- ```
- * Report for `src/procedural` only:
- ```bash
- ./scripts/gen_coverage_report.sh src/procedural
- ```
-
-## Tools
-
-### Updating Submodules
-
-To ensure all `third_party/` submodules are updated to the latest "Tip of Tree" (ToT) from their respective remote repositories and to resolve any local diffs, follow these steps:
-
-1. **Enter the submodule directory** (e.g., `third_party/wgpu-native`):
- ```bash
- cd third_party/wgpu-native
- ```
-
-2. **Fetch the latest changes from the remote**:
- ```bash
- git fetch
- ```
-
-3. **Identify the default branch** (e.g., `main`, `master`, `trunk`). You can see remote branches with `git branch -r`. For `wgpu-native`, the main development branch is typically `trunk`.
-
-4. **Checkout the default branch and hard reset to its remote state** (this discards any local changes and ensures a clean ToT):
- ```bash
- git checkout trunk
- git reset --hard origin/trunk
- ```
- (Replace `trunk` with the correct branch name if different for other submodules.)
-
-5. **Return to the superproject's root directory**:
- ```bash
- cd ../..
- ```
-
-6. **Update the superproject's record of the submodule**: This stages the change in the superproject's `.git` index, updating the commit hash for the submodule.
- ```bash
- git add third_party/wgpu-native
- ```
-
-7. **Commit the submodule update** in the superproject:
- ```bash
- git commit -m "chore: Update third_party/wgpu-native submodule"
- ```
- (Adjust the commit message as appropriate for other submodules.)
-
-Repeat these steps for any other submodules in `third_party/` that need updating.
-
-### Spectrogram Tool (`spectool`)
-
-A command-line tool for analyzing WAV and MP3 files into spectrograms and playing them back.
-
-#### Building the Tool
-
-To build `spectool`, you need to enable the `DEMO_BUILD_TOOLS` option in CMake.
+**Key tests:**
+- `HammingWindowTest`: Window function properties
+- `MathUtilsTest`: Math utilities
+- `SynthEngineTest`: Audio synthesis
+- `SequenceSystemTest`: Timeline logic
+## Code Coverage (macOS)
```bash
-cmake -S . -B build -DDEMO_BUILD_TOOLS=ON
-cmake --build build
+brew install lcov
+./scripts/gen_coverage_report.sh [target_dir]
```
-The executable will be located at `build/spectool`.
-
-#### Usage
-**Analyze an audio file:**
-```bash
-./build/spectool analyze path/to/input.wav path/to/output.spec
-# or
-./build/spectool analyze path/to/input.mp3 path/to/output.spec
-```
+## Tools
-**Play a spectrogram file:**
+### Windows Cross-Compilation
```bash
-./build/spectool play path/to/input.spec
+./scripts/fetch_win_deps.sh
+./scripts/build_win.sh
+./scripts/run_win.sh
```
-### Spectrogram Viewer (`specview`)
-
-A command-line tool for visualizing spectrogram files in ASCII art.
-
-#### Building the Tool
-
-`specview` is built along with `spectool` when enabling `DEMO_BUILD_TOOLS`.
-
+### spectool (Audio Analysis)
```bash
cmake -S . -B build -DDEMO_BUILD_TOOLS=ON
-cmake --build build
-```
-The executable will be located at `build/specview`.
+cmake --build build -j4
-#### Usage
+# Analyze
+./build/spectool analyze input.wav output.spec
-**View a spectrogram file:**
-```bash
-./build/specview path/to/input.spec
+# Play
+./build/spectool play input.spec
```
-### Audio Analysis & Playback Tool (`specplay`)
-
-A diagnostic tool for analyzing and playing .spec spectrogram files and .wav audio files. Useful for debugging audio issues, detecting clipping, and comparing spectrograms to source audio.
-
-#### Building the Tool
-
-`specplay` is built along with other tools when enabling `DEMO_BUILD_TOOLS`.
-
+### specview (Visualization)
```bash
-cmake -S . -B build -DDEMO_BUILD_TOOLS=ON
-cmake --build build
+./build/specview input.spec
```
-The executable will be located at `build/specplay`.
-
-#### Usage
-**Play and analyze a .spec file:**
+### specplay (Diagnostic)
```bash
-./build/specplay path/to/input.spec
+./build/specplay input.spec
+# or
+./build/specplay input.wav
```
+Output: Peak, RMS, clipping detection.
-**Play and analyze a .wav file:**
+### Submodule Updates
```bash
-./build/specplay path/to/input.wav
+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"
```
-#### Output Example
-```
-Loading .spec: version=1, dct_size=512, frames=68
-PCM stats: Peak=0.403, RMS=0.058
-Playing 1.09 seconds... Press Ctrl+C to stop.
-[CLIP at sample 1234: 1.523] # Only shown if clipping detected
-Playback complete.
-```
-
-#### Use Cases
-- **Detect clipping**: Peak > 1.0 indicates samples will clip
-- **Compare loudness**: RMS shows average energy (loudness)
-- **Verify spectrograms**: Ensure .spec matches source .wav
-- **Debug distortion**: Quickly test individual samples
-
-See `tools/specplay_README.md` for detailed documentation and future enhancement ideas.
-
-### Asset Management System
-
-This system allows embedding binary assets directly into the demo executable.
-
-#### Defining Assets
+## Asset Management
-Assets are defined in `assets/final/demo_assets.txt` (for the demo) and `assets/final/test_assets_list.txt` (for tests). Each line specifies:
-* `ASSET_NAME`: The identifier for the asset in C++ (e.g., `KICK_1`).
-* `filename.ext`: The path to the asset file (relative to `assets/final/`).
-* `NONE`: Compression type (currently only `NONE` is supported).
-* `"Description"`: An optional description.
-
-Example `assets/final/demo_assets.txt` entry:
+### Define Assets
+Edit `assets/final/demo_assets.txt`:
```
-KICK_1, kick1.spec, NONE, "A drum kick sample"
+KICK_1, kick1.spec, NONE, "Drum kick"
```
-#### Re-generating Assets
-
-To re-analyze source audio files (WAV/MP3) into spectrograms and update the embedded assets in the source tree, use the provided script:
-
+### Regenerate
```bash
./scripts/gen_assets.sh
```
+Converts WAV → .spec, packs into C++ arrays.
-This script:
-1. Ensures `spectool` and `asset_packer` are built.
-2. Converts source audio files in `assets/wav/` to `.spec` files in `assets/final/`.
-3. Runs `asset_packer` to update `src/assets.h` and `src/assets_data.cc`.
-
-#### Building with Assets
-
-The build system automatically runs `asset_packer` whenever the asset lists are modified. The generated files are located in the build directory (`build/src/`).
-
-To build the demo with the latest assets:
-
-```bash
-cmake -S . -B build
-cmake --build build
-```
-
-#### Accessing Assets in Code
-
-Include `assets.h` and use the `GetAsset` function:
-
+### Use Assets
```cpp
#include "assets.h"
-// ...
-size_t asset_size;
-const uint8_t* my_asset = GetAsset(AssetId::ASSET_SAMPLE_142, &asset_size);
-// ...
-// For lazy decompression (scaffolding only):
-// DropAsset(AssetId::ASSET_SAMPLE_142, my_asset);
+size_t size;
+const uint8_t* data = GetAsset(AssetId::KICK_1, &size);
+// Use data...
+// DropAsset(AssetId::KICK_1, data); // For compressed assets only
```
+
+Build system auto-runs `asset_packer` when asset lists change.