AquaSynth/state/memory.json
2026-05-13 19:10:07 +01:00

81 lines
5.7 KiB
JSON

{
"project": "AquariumSynthCSharp",
"mission": "Own Aquarium Synth patch authoring, analysis, preset mapping, and Faust generation in C# for the Aquarium/Vortice engine path.",
"current_boundary": {
"leave_in_rust": [
"Rust sample renderer",
"PatchPlayer runtime",
"realtime AudioUnit bridge",
"experimental Rust DSL compiler branch"
],
"own_here": [
"patch graph model",
"operator graph model",
"renderable delayed operator feedback",
"patch parameter contracts",
"reference patch contracts",
"test-only public-domain DX7 fixtures",
"test-only dexed-py reference renderer",
"thresholded DX7 rendered parity test",
"reference rebuild catalog",
"DX7 SysEx structural parsing",
"DX7 algorithm topology metadata",
"DX7 effective operator-level approximation",
"DX7 envelope-to-ADSR approximation",
"standard ADSR envelope model",
"note frequency/gate model",
"Faust-managed playback/polyphony contract",
"patch script parser",
"SFXR atoms and parameter mapping",
"analysis/comparison metrics",
"Faust-generated C# candidate rendering",
"script scoring",
"preset catalogs",
"Faust emission and compiler wrapper"
]
},
"taste": [
"Patch scripts should be terse but lower into explicit, inspectable graph data.",
"Compiler abstractions should remove repeated musical structure, not hide DSP behavior.",
"Generated Faust should be boring enough to diff and debug.",
"Realtime-facing work must assume allocation, locks, file I/O, console I/O, and OS calls are hostile."
],
"doctrine_refs": [
"docs/audio-doctrine.md",
"docs/migration-checklist.md",
"docs/reference-synth-roadmap.md",
"state/spine.yaml"
],
"reference_strategy": {
"purpose": "Use external synths and DSP corpora as parity pressure for Aquarium's patch DSL and Faust emitter: the DSL must reproduce behavior in terse, readable Aquarium syntax, not clone foreign internals.",
"priority_order": [
"DX7/Dexed SysEx for FM operator topology",
"ZynAddSubFX instruments for additive, subtractive, PAD, formant, and layered patches",
"Faust examples/libraries for general DSP graph topology",
"Surge XT for modern hybrid synth modulation",
"Cardinal/VCV-style patches for modular cable/rate semantics"
],
"rule": "Add DSL abstractions only when reference rebuilds prove the missing invariant. Do not consume references that cannot be backed by parity tests; parsing alone is inventory, not evidence of expressivity."
},
"dx7_reference_path": {
"status": "DX7 SysEx parser extracts voice edit buffers, packed voices, packed 32-voice banks, six operators, envelopes, algorithm, feedback, oscillator sync, LFO, transpose, voice name, checksum validation, ReferencePatch features, algorithm topology from the reverse-engineered OPS algorithm ROM table, envelope-to-ADSR approximations, effective operator-level approximations, two Aquarium DSL rebuild attempts, first-class OperatorGraph support, public-domain SysEx fixture coverage, dexed-py reference rendering, Aquarium candidate rendering through Faust-generated C#, one thresholded rendered parity test for analog1.syx voice 13, and renderable delayed operator feedback.",
"lesson": "Algorithm 32's additive six-carrier shape maps cleanly to six Aquarium voices. Algorithm 8 justified OperatorGraph: operators, modulation edges, carriers, and feedback belong to a graph authority, not Voice fields. The first rendered parity rung is behavioral and sine-like, not exact DX7 operator execution. A harder algorithm-8 target exposed that feedback must be delayed recursion in Faust, not a direct cyclic self-reference. Static DX7 output-level approximation helps import/rebuild math but does not solve hard parity alone; PRC SYNTH1 still points at DX7-style operator envelope/gain evolution. Readable authoring uses operator/route/carrier declarations; compact ops/edges tuples are scaffolding only.",
"next": "Choose whether to add a DX7-style four-rate/four-level operator envelope surface or a reference-rebuild-only gain-envelope approximation before attempting the next hard parity threshold; exact DX7 feedback scaling remains separate pressure."
},
"note_and_envelope_model": {
"rule": "Notes own frequency, gate duration, and host/MIDI source. Envelopes own ADSR level shape.",
"sfxr_mapping": "SFXR sustain is note gate duration. SFXR punch maps to lower ADSR sustain level plus voice gain compensation so the implicit attack peak stays at 1 and the held level sits below it.",
"faust_surface": "One-shot patches use generated ADSR over patch age and note gate duration. MIDI mono/poly patches emit Faust's standard freq/gain/gate controls and [midi:on][nvoices:n] metadata so Faust architectures own note allocation."
},
"runtime_parameters": {
"rule": "Patch parameters are runtime controls, not compile-time constants.",
"faust_surface": "Faust UI controls expose parameter zones that hosts can update with setParamValue/getParamValue-style APIs.",
"aquarium_requirement": "Aquarium DSL patches declare stable exposed parameters with path/default/min/max/step metadata so callers can vary sound without recompiling.",
"binding_rule": "Parameter binding uses field-site references such as `lpf=@/macro/brightness` and `/opgraphs/0/operators/2/level`; the field owns meaning and the parameter owns the runtime value. Avoid target-routing semantics unless a new graph authority is deliberately mapped."
},
"last_verified": {
"command": "dotnet test AquariumSynthCSharp.slnx --no-restore",
"result": "50 passed",
"commit": "pending DX7 operator level approximation"
}
}