AquaSynth/README.md

135 lines
5.5 KiB
Markdown
Raw Normal View History

2026-05-16 05:49:44 +01:00
# AquaSynth
2026-05-08 03:00:53 +01:00
2026-05-17 14:02:07 +01:00
<p align="center">
<img src="icon.png" alt="AquaSynth icon" width="260" />
2026-05-17 14:02:07 +01:00
</p>
C# patch authoring, analysis, and Faust toolchain for AquaSynth. It parses the
`.aqua` DSL into a serializable patch graph, emits Faust `.dsp`, and owns the
path from patch intent to generated DSP artifacts.
2026-05-08 03:00:53 +01:00
2026-05-16 05:49:44 +01:00
This repo is the C# bridge for AquaSynth/Vortice-land. Rust remains the reference
2026-05-08 03:00:53 +01:00
lab; this project is the tool that lets the engine script Faust without dragging
2026-05-16 05:49:44 +01:00
the AquaSynth-rs crate into the room by the ankle.
2026-05-08 03:00:53 +01:00
## Run
```powershell
dotnet test
```
DX7 reference-render tests use `dexed-py` when a Python with `dexed` and
2026-05-16 05:49:44 +01:00
`numpy` is available. Set `AQUASYNTH_DX7_PYTHON` to that interpreter to force a
specific runtime; otherwise the tests skip the render path and still parse the
vendored public-domain fixture.
2026-05-14 23:31:33 +01:00
ZynAddSubFX is pinned as a GPL test/development reference under
`external/zynaddsubfx`. Initialize it with:
```powershell
git submodule update --init --recursive
```
2026-05-16 05:49:44 +01:00
That source is a parity oracle only. AquaSynth does not ship Zyn code, link it
2026-05-17 19:17:59 +01:00
from published packages, or treat it as runtime machinery.
2026-05-14 23:31:33 +01:00
2026-05-13 00:19:02 +01:00
## Package Boundary
Downstream consumers should pin the NuGet packages from this repo, not use live
2026-05-17 19:17:59 +01:00
project references. Breaking synth-library work should happen here freely, then
consumers should intentionally update only after new package versions are packed
and tested.
2026-05-13 00:19:02 +01:00
```powershell
2026-05-17 19:17:59 +01:00
dotnet pack src\AquaSynth.Core\AquaSynth.Core.csproj -c Release
dotnet pack src\AquaSynth.Faust\AquaSynth.Faust.csproj -c Release
2026-05-13 00:19:02 +01:00
```
`AquaSynth.Core` owns patch meaning: model records, the `.aqua` parser,
authoring helpers, analysis/scoring tools, presets, and Faust source emission.
`AquaSynth.Faust` depends on Core and owns toolchain/rendering work: Faust CLI
validation, target-code generation, live patch compilation, native `libfaust`
loading, compile manifests, DSP factory lifetime, and offline/sample rendering.
2026-05-17 19:17:59 +01:00
2026-05-14 23:31:33 +01:00
The test suite verifies that development fixtures, Python render helpers,
external reference synth sources, and SysEx banks do not ship in
2026-05-17 19:17:59 +01:00
published packages.
2026-05-08 03:00:53 +01:00
## Shape
- `PatchScript.Parse(script)` lowers terse script into `SynthPatch`.
- `FaustEmitter.Emit(patch)` emits Faust source.
2026-05-17 19:17:59 +01:00
- `FaustCompiler.ValidateAsync(source)` compile-checks with Faust when present
from `AquaSynth.Faust`.
- `FaustCompiler.CompileAsync(source, options)` writes generated backend code
2026-05-17 19:17:59 +01:00
through an installed or resolved Faust compiler from `AquaSynth.Faust`.
2026-05-18 12:20:32 +01:00
- `FaustCompiler.CompileWebAssemblyScriptAsync(...)` and
`CompileWebAssemblyAsync(...)` emit browser-ready `.dsp`, `.wasm`, and Faust
JSON UI metadata artifacts.
- `AquaSynthPatchCompiler` from `AquaSynth.Faust` is the live host-facing
boundary for compiling `.aqua` scripts into hosted DSP factories.
- `AquaSynthNativeCompiler` remains the lower native `libfaust` compiler
machinery behind that boundary.
2026-05-12 22:10:02 +01:00
- `BuiltInScripts.ReferenceScripts()` carries readable SFXR, BFXR-flavored,
2026-05-12 22:38:24 +01:00
808, FM bell, wobble bass, and advanced layered patches. They are stable
references for testing and for judging whether the DSL can express useful
sound designs cleanly.
2026-05-08 10:34:07 +01:00
- `SfxrParams`, `PatchScriptScoring`, `AudioAnalyzer`, and `Presets` carry the
2026-05-16 05:49:44 +01:00
reusable AquaSynth-rs-side analysis, scoring, SFXR, and preset tools.
2026-05-08 03:00:53 +01:00
The authoring/test lane can compile Faust-generated C# for easy .NET rendering
and parity checks:
2026-05-08 03:00:53 +01:00
```csharp
2026-05-12 22:10:02 +01:00
var patch = PatchScript.Parse("""
voice
wave=saw
freq=55
gain=0.2
sustain=0.5
decay=0.2
""");
2026-05-08 03:00:53 +01:00
var export = FaustEmitter.Emit(patch, new FaustExportOptions("bass"));
await FaustCompiler.CompileAsync(
export.Source,
new FaustCompileOptions(FaustTargetLanguage.CSharp, "Generated/Bass.cs"));
```
2026-05-18 12:20:32 +01:00
The browser lane uses Faust's WebAssembly backend and keeps the same ownership:
AquaSynth emits the `.dsp`, `.wasm`, and JSON UI description; the host supplies
WebAudio scheduling and parameter binding.
```csharp
await FaustCompiler.CompileWebAssemblyScriptAsync(
"v w=sin f=880 g=.12 sustain=.04 decay=.2",
new FaustWebAssemblyCompileOptions("Generated/Web", "ui_select"));
```
The runtime lane is different. AquaSynth should own Faust toolchain selection,
compile cache identity, generated artifacts, parameter manifests, and dynamic
patch compilation outside the realtime path. Aquarium Engine should load and
host the finished artifact, bind controls, and schedule audio. Native Faust
targets are the preferred shipping path when the platform allows them; C# output
is convenient authoring machinery, not the ceiling.
`AquaSynthPatchCompiler` is the live runtime-facing version of that boundary: it
owns native `libfaust` loading policy, script parsing, Faust emission, compile
keys, DSP source artifacts, manifests, and compiled products. Engine callers
keep their device and scheduling code, and ask AquaSynth for compiled/renderable
synth products.
2026-05-17 15:03:30 +01:00
See [`docs/faust-toolchain-boundary.md`](docs/faust-toolchain-boundary.md).
2026-05-08 03:00:53 +01:00
## Status
2026-05-12 22:10:02 +01:00
The current slice covers the modular graph surface needed by the reference
2026-05-08 10:34:07 +01:00
scripts, SFXR atoms, script scoring, audio comparison, presets, Faust emission,
native Faust compilation/rendering, and installed Faust validation. Migration
coverage is tracked in
2026-05-08 10:21:32 +01:00
[`docs/migration-checklist.md`](docs/migration-checklist.md), because leaving
important things behind in the old repo would be a very efficient way to become
our own haunted house.
2026-05-12 22:53:22 +01:00
Reference-driven DSL growth is tracked in
[`docs/reference-synth-roadmap.md`](docs/reference-synth-roadmap.md). Agent
handoff state lives in [`state/spine.yaml`](state/spine.yaml).