Development
MINERVA Space Echo is open source (AGPL-3.0) and lives at github.com/CrumpLab/MinervaSpaceEcho. The staged design is in plan.md.
Layout
| Path | Contents |
|---|---|
engine/ |
The model: plain C++20 with no framework dependency (features, retrieval, trace store, tape, spectral, presets, memory files). |
plugin/ |
The JUCE wrapper (AU, VST3, Standalone) and editor. |
tools/ |
mse-render and mse-testgen. |
tests/ |
Catch2 unit tests for the engine. |
presets/ |
factory/ and examples/ presets, built into the plug-in. |
manual/ |
This site (Quarto). |
scripts/ |
Example renders and macOS packaging. |
Building and testing
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir buildOptions: MSE_BUILD_PLUGIN, MSE_BUILD_TOOLS, MSE_BUILD_TESTS (all on), MSE_COPY_PLUGIN_AFTER_BUILD (off). Use -DMSE_BUILD_PLUGIN=OFF for a fast engine-only build without JUCE. The plug-in also builds on Linux (VST3 and Standalone), which is how CI runs pluginval and renders the editor screenshots.
The tests cover, among other things: exact tape-delay equivalence at capacity 1, retrieval maths, every memory policy, live cueing, heads, tape character, the spectral engine, import, presets, host edge cases (odd and oversized blocks, sample-rate changes, tempo changes, NaN input) and a click test that moves every continuous parameter during a steady tone. They also run clean under AddressSanitizer and UndefinedBehaviorSanitizer:
cmake -S . -B build-asan -DMSE_BUILD_PLUGIN=OFF \
-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -O1"
cmake --build build-asan && ctest --test-dir build-asanReal-time design
The audio thread never allocates, locks or waits:
- Memory is preallocated (Memory Budget). Changing capacity, loading or importing builds a new store on the message thread, and the audio thread adopts it by swapping buffers at the start of a block.
- UI actions reach the audio thread through a lock-free queue; the memory view the editor draws is published through a triple buffer about 30 times a second.
- The rolling search is spread across blocks with a fixed work budget.
- Parameters glide per sample where a jump would click.
Continuous integration
.github/workflows/build.yml builds and tests on Linux and macOS on every push, runs pluginval (and auval on macOS), renders the example presets and editor snapshots, and packages a universal macOS installer and zip. Pushing a v* tag creates a GitHub release; see docs/RELEASING.md, which also covers Developer ID signing and notarization.
This manual
The manual is a Quarto website in manual/. The parameter and preset references, the listening page and the changelog are generated from the source by manual/_scripts/generate.py before each render, so they can’t drift; every parameter must have a description in manual/_scripts/param_docs.py, or the build stops.
cd manual
python3 _scripts/generate.py # once, before the first render in a fresh clone
quarto preview # live preview in a browser
quarto render # build into manual/_site(Quarto resolves the generated includes before its pre-render step runs, so they must exist before the first render; after that, every render regenerates them.)
.github/workflows/docs.yml renders the listening examples to MP3, builds the site and publishes it to GitHub Pages from the default branch.