summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-02 12:19:10 +0100
committerskal <pascal.massimino@gmail.com>2026-02-02 12:19:10 +0100
commitdc47af28f09705d28e9975867d7fad9a395f9163 (patch)
tree5ae97b21542d2824c9c9d422ed1b4a25331fa1a2 /doc
parenta5b27673c29ca39b6b35bb0f5c4be224d7b41b5a (diff)
refactor(build): Centralize generated files and clean up project layout
- Task A: Centralized all generated code (assets, timeline) into a single directory to create a single source of truth. - Task A: Isolated test asset generation into a temporary build directory, preventing pollution of the main source tree. - Task B: Vertically compacted all C/C++ source files by removing superfluous newlines. - Task C: Created a top-level README.md with project overview and file descriptions. - Task D: Moved non-essential documentation into a directory to reduce root-level clutter.
Diffstat (limited to 'doc')
-rw-r--r--doc/ASSET_SYSTEM.md57
-rw-r--r--doc/BUILD.md29
-rw-r--r--doc/CONTRIBUTING.md189
-rw-r--r--doc/FETCH_DEPS.md68
-rw-r--r--doc/HOWTO.md225
-rw-r--r--doc/PROCEDURAL.md24
-rw-r--r--doc/SPEC_EDITOR.md44
7 files changed, 636 insertions, 0 deletions
diff --git a/doc/ASSET_SYSTEM.md b/doc/ASSET_SYSTEM.md
new file mode 100644
index 0000000..250be07
--- /dev/null
+++ b/doc/ASSET_SYSTEM.md
@@ -0,0 +1,57 @@
+# compact asset system for the 64k demo
+
+This file describe the features of a compact asset system used in the demo.
+
+The idea is the following:
+
+# run-time asset retrieval:
+ All assets are const byte arrays. We need a 'const uint8_t* GetAsset(uint16 asset_id)'
+ The asset ID is defined in a 'assets.h' header, generated during the final
+ compile by our own assembling tool. assets.h needs to be re-generated
+ infrequently.
+
+# assembling the assets:
+
+## description file 'assets.txt'
+ All assets are just files in the assets/final/ directory
+ This directory needs a assets.txt text file to describe the asset files.
+ Each line of the assets.txt file contain, comma-separated:
+ * the name of the asset (that will be used by the #define in assets.h),
+ * the name of the file associated
+ * the compression to use for this asset (default NONE. More options later)
+ * and optionally the type of assets.
+
+## example For instance, a line in assets.txt will read:
+
+SAMPLE_142, sample_142.spec, NONE, "this is a drum kick sample"
+
+This instructs the final assembled file assets.h to have a code line:
+ #define ASSET_SAMPLE_142 6323
+
+(6323 is just an associated id)
+
+(or an enum instead of #define's)
+
+so that we can call
+```
+#include "asset.h"
+const uint8_t* mysample = GetAsset(ASSET_SAMPLE_142);
+...etc
+```
+
+(if we use enums, GetAssert() signature needs to be changed)
+
+### Lazy decompression
+to save memory some assets can be decompressed 'at retrieval time' but kept
+compressed in memory until then.
+This means that we need a 'void DropAsset(uint16 asset_id, const uint8* asset)'
+method to handle memory disallocation depending on the asset type.
+
+### assembling tool
+
+we need a simple tool that:
+ * takes the assets.txt file and parse it
+ * generates the assets.h file with asset enums
+ * generates the assets_data.cc file with all the data
+ * put these in the source tree
+ * this process needs a script for automation
diff --git a/doc/BUILD.md b/doc/BUILD.md
new file mode 100644
index 0000000..3a581b1
--- /dev/null
+++ b/doc/BUILD.md
@@ -0,0 +1,29 @@
+# Build Instructions
+
+Debug build:
+cmake -S . -B build
+cmake --build build
+
+Size-optimized build:
+cmake -S . -B build -DDEMO_SIZE_OPT=ON
+cmake --build build
+
+## Windows Cross-Compilation (from macOS)
+
+Requires `mingw-w64` and `wine-stable` (for testing).
+
+1. Fetch Windows binaries:
+ ```bash
+ ./scripts/fetch_win_deps.sh
+ ```
+
+2. Build for Windows:
+ ```bash
+ ./scripts/build_win.sh
+ ```
+ This will produce `build_win/demo64k_packed.exe`.
+
+3. Run with Wine:
+ ```bash
+ ./scripts/run_win.sh
+ ```
diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md
new file mode 100644
index 0000000..7ae2e52
--- /dev/null
+++ b/doc/CONTRIBUTING.md
@@ -0,0 +1,189 @@
+# Contributing Guidelines
+
+This document outlines the conventions to follow when contributing to this project.
+
+## Commit Policy
+
+### Verify Build and Tests Before Committing
+
+Before preparing or proposing a commit, you **must** perform the following verifications to prevent regressions:
+
+1. **MacOS / Linux (Native)**:
+ * Build the project (debug or release).
+ * Run the entire test suite (`ctest`).
+ * Ensure all tests pass.
+
+2. **Windows (Cross-Compilation)**:
+ * If `mingw-w64` is installed on your system, you **must** also verify the Windows build.
+ * Run `./scripts/build_win.sh`.
+ * Ensure the build succeeds and produces the `demo64k_packed.exe` binary.
+ * Check the size report to ensure no unexpected bloat.
+
+Refer to the "Testing" and "Windows Cross-Compilation" sections in `HOWTO.md` for detailed instructions.
+
+### Format Code Before Committing
+
+All code **must** be formatted using `clang-format` before committing. This ensures a consistent coding style across the entire codebase.
+
+To format your code, run the following command from the project root:
+```bash
+clang-format -i $(git ls-files | grep -E '\.(h|cc)$' | grep -vE '^(assets|archive|third_party)/')
+```
+
+Refer to the `.clang-format` file in the project root for the specific style rules.
+
+### Ensure Newline at End of File
+
+All source files (`.h`, `.cc`, `.cpp`, etc.) must end with a newline character. This prevents "No newline at end of file" errors from linters and ensures consistent file handling.
+
+### Source File Headers
+
+Every source file (`.h`, `.cc`) must begin with a concise 3-line comment header describing its purpose.
+
+Example:
+```cpp
+// This file is part of the 64k demo project.
+// It implements the core audio synthesis engine.
+// This is not a user-facing header, but an internal one.
+```
+
+### Function and method comments
+
+Functions and methods, especially if they are internal non user-facing,
+should at least have a 1-line comment describing what they do or their
+how/when they should be called. Except if they are just 1-line function
+or very very short, obvious ones.
+
+### '#endif' directive
+
+The closing #endif directive must recall the corresponding opening #ifdef
+clause they are closing
+
+Example:
+```cpp
+#ifdef MY_TAG
+...some code
+#endif /* MY TAG */
+```
+
+We must also prefer '#if defined(MY_QUITE_LONG_TAG)' over '#ifdef MY_QUITE_LONG_TAG'
+especially if there's a risk of having later something like:
+```cpp
+#if defined(MY_TAG_1) && !defined(MY_TAG_2)
+```
+
+### use and abuse 'const' directives
+
+Especially for local variable, use 'const' qualification as much as
+possible.
+
+As an example, don't use:
+```cpp
+StructA variable_name = StructA(...);
+```
+
+but prefer instead:
+```cpp
+const StructA variable_name = StructA(...);
+```
+
+if variable_name is not mutated afterward.
+
+Also: pass parameter as "const ref" as much as possible
+(```const Struct& param``` instead of pointers or non-const refs)
+
+### put spaces around code and operators (cosmetics)
+
+Don't compact the code to much horizontally, and prefer adding extra
+spaces around code and operators.
+
+Example:
+```cpp
+const bool v = my_variable && (my_function() / 3. > (1. / x));
+const y = function_call(3, x, 2.);
+for (int x = 0; x < 24; ++x) { ... }
+```
+
+instead of
+```cpp
+const bool v=my_variable&&my_function()/3.>(1./x);
+const y = function_call(3,x,2);
+for(int x=0;x<24;++x){ ... }
+```
+
+### prefer prefixed incrementation over suffixed
+
+Use pre-incrementation:
+```cpp
+++x
+```
+
+instead of post-incrementation:
+
+```cpp
+x++
+```
+
+### use extra () for boolean operations
+
+Even if they are not strictly needed due to operator precedence rules,
+prefer adding extra ()'s around tests for clarity, with parcimony.
+
+### c++ cast
+
+don't use reinterpret_cast<>, static_cast<> or const_cast<>.
+
+### pointer declaration
+
+prefer ```const T* name``` to ```const T *name```.
+
+### 'auto' type
+
+Don't use 'auto' as type, unless for complex iterators or very complex
+types.
+
+### don't use trailing whitespaces
+
+don't.
+
+### no missing \newline at the end of file
+
+make sure each file has a final \n newline.
+
+### c++ keyword indentation:
+
+The keyword 'public', 'protected', 'private' should be intended 1 character
+less than the methods.
+
+Example:
+```cpp
+ private:
+ int field_;
+```
+
+instead of:
+```cpp
+private:
+ int field_;
+```
+
+### vertical space
+
+keep the code compact vertically. That includes shader code, too.
+Use only one statement per line.
+
+### finally
+
+Make sure everything is reflected in clang-format.
+
+## Development Protocols
+
+### Adding a New Visual Effect
+
+1. **Implement**: Create or update a class in `src/gpu/demo_effects.cc` (and declare in `demo_effects.h`) that inherits from `Effect`.
+ - Implement `init()` for one-time resource setup (e.g., using the asset system).
+ - Implement `compute()` if you need GPU-side physics or state updates.
+ - Implement `render()` to record WebGPU draw commands.
+2. **Register**: Add an `EFFECT` entry to `assets/demo.seq` specifying the class name, start/end times, and any constructor arguments.
+3. **Verify**: Build with `DEMO_ALL_OPTIONS=ON` and use `--seek` to test your effect at its specific timestamp.
+
diff --git a/doc/FETCH_DEPS.md b/doc/FETCH_DEPS.md
new file mode 100644
index 0000000..ce62db2
--- /dev/null
+++ b/doc/FETCH_DEPS.md
@@ -0,0 +1,68 @@
+# Fetching Third-Party Dependencies
+
+This project intentionally does NOT vendor large third-party libraries.
+
+Currently required:
+
+## miniaudio
+
+Single-header audio library.
+
+Source:
+https://github.com/mackron/miniaudio
+
+Required file:
+- miniaudio.h
+
+Expected location:
+third_party/miniaudio.h
+
+### Automatic fetch
+
+Use one of the provided scripts:
+- scripts/project_init.sh
+- scripts/project_init.bat
+
+### Manual fetch
+
+Download miniaudio.h from:
+https://raw.githubusercontent.com/mackron/miniaudio/master/miniaudio.h
+
+and place it into:
+third_party/miniaudio.h
+
+## wgpu-native
+
+WebGPU implementation via wgpu-native.
+
+### Installation
+
+**macOS:**
+```bash
+brew install wgpu-native
+```
+
+**Other platforms:**
+Please install `wgpu-native` such that `libwgpu_native` (static or shared) is in your library path and headers are in your include path (under `webgpu/`).
+
+## glfw3webgpu
+
+Helper library for creating WebGPU surfaces from GLFW windows.
+
+### Automatic fetch
+
+Use one of the provided scripts:
+- scripts/project_init.sh
+- scripts/project_init.bat
+
+These scripts will download `glfw3webgpu.h` and `glfw3webgpu.c` into `third_party/glfw3webgpu`.
+
+## UPX
+
+Executable packer for binary compression (Linux/Windows only).
+On macOS, the build script defaults to `strip` and `gzexe` due to UPX compatibility issues.
+
+### Installation
+
+**Linux/Windows:**
+Download the appropriate release from https://github.com/upx/upx/releases and ensure the `upx` executable is in your PATH.
diff --git a/doc/HOWTO.md b/doc/HOWTO.md
new file mode 100644
index 0000000..e97380e
--- /dev/null
+++ b/doc/HOWTO.md
@@ -0,0 +1,225 @@
+# 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.
+
+## 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
+```
+
+To run in a specific resolution, use the `--resolution` option:
+```bash
+./build/demo64k --resolution 1024x768
+```
+
+Keyboard Controls:
+* `Esc`: Exit the demo.
+* `F`: Toggle fullscreen mode.
+
+### Size-Optimized Build
+
+```bash
+cmake -S . -B build -DDEMO_SIZE_OPT=ON
+cmake --build build
+```
+
+### 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:
+
+```bash
+cmake -S . -B build -DDEMO_STRIP_ALL=ON
+cmake --build build
+```
+In this mode, the demo will always start in fullscreen.
+
+### Developer Build (All Options)
+
+To enable all features at once (tests, tools, size optimizations, and stripping) for a comprehensive check:
+
+```bash
+cmake -S . -B build -DDEMO_ALL_OPTIONS=ON
+cmake --build build
+```
+
+## 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`
+
+to clone the repo and work on it.
+
+## 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.
+
+```bash
+./build/demo64k --seek 15.5
+```
+
+## 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.
+
+**Format:**
+```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
+```
+
+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.
+
+```bash
+cmake -S . -B build -DDEMO_BUILD_TESTS=ON
+cmake --build build
+cd build
+ctest
+cd ..
+```
+
+## Tools
+
+### 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.
+
+```bash
+cmake -S . -B build -DDEMO_BUILD_TOOLS=ON
+cmake --build build
+```
+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
+```
+
+**Play a spectrogram file:**
+```bash
+./build/spectool play path/to/input.spec
+```
+
+### 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`.
+
+```bash
+cmake -S . -B build -DDEMO_BUILD_TOOLS=ON
+cmake --build build
+```
+The executable will be located at `build/specview`.
+
+#### Usage
+
+**View a spectrogram file:**
+```bash
+./build/specview path/to/input.spec
+```
+
+### Asset Management System
+
+This system allows embedding binary assets directly into the demo executable.
+
+#### Defining Assets
+
+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:
+```
+KICK_1, kick1.spec, NONE, "A drum kick sample"
+```
+
+#### 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:
+
+```bash
+./scripts/gen_assets.sh
+```
+
+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:
+
+```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);
+```
diff --git a/doc/PROCEDURAL.md b/doc/PROCEDURAL.md
new file mode 100644
index 0000000..c6bf688
--- /dev/null
+++ b/doc/PROCEDURAL.md
@@ -0,0 +1,24 @@
+# Procedural textures
+
+## the idea
+We need a way to produce textures procedurally.
+These texture can be generated on the CPU or the
+GPU with a shader and the proper rendering target,
+and then sent back to main memory.
+
+## What textures?
+
+The procedure can be use to pre-calc env maps
+and lighting maps, or textures (fractals, fonts, etc.)
+
+## how
+
+This could be integrated in the asset system as
+a special "compression" case (instead of "NONE", you
+have "PROC(the_function_name_to_call)" as compression
+type).
+
+## code
+
+let's have a proper 'src/procedural' sub-directory
+with all the code related to procedural textures.
diff --git a/doc/SPEC_EDITOR.md b/doc/SPEC_EDITOR.md
new file mode 100644
index 0000000..cde0cdd
--- /dev/null
+++ b/doc/SPEC_EDITOR.md
@@ -0,0 +1,44 @@
+# spectrogram editing tool in a browser
+
+The sub-project is about have an editing tool in a browser
+that will allow generating, editing, compacting .spec files
+
+## the idea
+
+We want a web page (html+javascript) capable of:
+ * loading a .wav file and showing the spectrogram (IDCT_SIZE=512)
+ * compacting this spectrogram if needed
+ * generating the .spec file
+ * allowing some editing on the spectrogram
+ * and most importantly: allowing the compression of this spectrogram using elementary bricks like bezier-curves (with a large stroke width /
+ brushes), rectangle, noise addition, etc.
+
+These tools must be available in the web editor (in javascript) as well as
+in c++ equivalent too.
+
+The idea is the compress the .wav spectrogram using elementary bricks and
+simple representation (as well as being dynamic) during the demo: we
+generate the audio on the fly by 'drawing' the spectrograms and passing them
+to the synth
+
+## the work
+
+Analyze the requirement for the HTML tool. It must remain simple and easy to
+use. Don't over-engineer it.
+Still, the tool must have a decent load/save offer, to:
+ * load the .wav
+ * save the .spec
+ * save/export the descriptive compressed version in vectorial form (like the SVG format, in fact)
+ * be able to load this vectorial form
+
+Then we need a reader for the vectorial form in c++ to use in the demo.
+We also need to elementary tools / bricks to: draw a line / bezier curve /
+rectangle, ellipse, etc. in frequency domain, to generate the spectrogram on
+the flight.
+We also need controllable random noise generation to add some 'texture' to
+the spectrogram.
+
+## the files
+the HTML/JS tool should be under tools/editor
+the c++ code should be added to the library under src/audio/
+