summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/CONTRIBUTING.md49
-rw-r--r--doc/HOWTO.md59
2 files changed, 108 insertions, 0 deletions
diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md
index 4bb894e..27391e4 100644
--- a/doc/CONTRIBUTING.md
+++ b/doc/CONTRIBUTING.md
@@ -253,3 +253,52 @@ Make sure everything is reflected in clang-format.
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.
+### Audio Subsystem Initialization
+
+The audio subsystem uses `AudioEngine` to manage initialization order and lifecycle.
+
+**In production code (`main.cc` or similar):**
+
+```cpp
+#include "audio/audio_engine.h"
+
+// 1. Initialize audio backend
+audio_init();
+
+// 2. Initialize audio engine (manages synth + tracker)
+static AudioEngine g_audio_engine;
+g_audio_engine.init();
+
+// 3. In main loop
+g_audio_engine.update(music_time);
+```
+
+**In tests:**
+
+```cpp
+#include "audio/audio_engine.h"
+
+void test_audio_feature() {
+ AudioEngine engine;
+ engine.init();
+
+ // Test logic here
+ engine.update(1.0f);
+
+ engine.shutdown(); // Always cleanup at end
+}
+```
+
+**Low-level usage (when AudioEngine is not needed):**
+
+For tests that only need synth or tracker (not both), you can still call `synth_init()` or `tracker_init()` directly. However, if you need both, always use `AudioEngine` to ensure correct initialization order.
+
+**Direct synth API calls are valid:**
+
+- `synth_register_spectrogram()` - Register spectrograms
+- `synth_trigger_voice()` - Trigger audio playback
+- `synth_get_output_peak()` - Get audio levels for visualization
+- `synth_render()` - Low-level rendering
+
+These are performance-critical APIs and should be called directly, not wrapped by AudioEngine.
+
diff --git a/doc/HOWTO.md b/doc/HOWTO.md
index e562679..5af3f05 100644
--- a/doc/HOWTO.md
+++ b/doc/HOWTO.md
@@ -6,6 +6,7 @@ This document describes the common commands for building and testing the project
* **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.
## Building
@@ -62,6 +63,64 @@ if you have the public ssh key authorized on the VPS, you can use
to clone the repo and work on it.
+## 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:**
+
+```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
+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)
+
+**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
+
+**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();
+}
+```
+
+For low-level synth-only tests, you can still call `synth_init()` directly.
+
## Debugging
### Seeking / Fast-Forward