AquaSynth/state/memory.json
2026-05-14 15:10:30 +01:00

97 lines
8.4 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",
"test-only project-authored Dexed patch renderer",
"ignored listening WAV parity artifacts",
"structured development .aqua patch library",
"thresholded DX7 rendered parity test",
"reference rebuild catalog",
"DX7 SysEx structural parsing",
"DX7 algorithm topology metadata",
"DX7 effective operator-level approximation",
"DX7 measured carrier output amplitude curve",
"DX7 isolated modulation-index route scale",
"DX7 summed/cascaded modulation route scale",
"DX7 calibrated feedback amount table",
"DX7 ratio detune lowering",
"DX7 ROM COM output compensation",
"DX7 topology-aware route lowering",
"DX7 envelope trace helper",
"DX7 block-interpolated envelope applied-gain trace helper",
"DX7 applied-envelope curved lowering",
"staged operator envelope DSL",
"curved staged operator envelope segments",
"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/dx7-calibration-plan.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, measured carrier output amplitude, isolated two-op modulation route scale, summed/cascaded route scale, calibrated feedback amount table, ratio detune lowering, ROM COM output compensation, topology-aware route lowering, staged operator envelopes with per-segment curves, raw and block-interpolated DX7 envelope tracing, applied-envelope curved lowering, two Aquarium DSL rebuild attempts, first-class OperatorGraph support, public-domain SysEx fixture coverage, dexed-py reference rendering, project-authored Dexed patch rendering, Aquarium candidate rendering through Faust-generated C#, one thresholded rendered parity test for analog1.syx voice 13, a hard PRC SYNTH1 parity probe with listening WAV artifacts and log-mel <= 0.18, project-authored algorithm-8 summed-stack/cascade/summed-pair parity, broad rendered community parity for four analog1.syx voices, 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 helped import/rebuild math but was mathematically wrong for carrier amplitude. A single-carrier Dexed sweep shows carrier amplitude follows 2^((outputLevel - 99) / 8). Isolated two-op DX7 FM maps full-level modulation to Aquarium route index 6.275; summed/cascaded algorithm-8 branches now use 6.0 after PRC listening, a project-authored combined stack probe, and split cascade/summed-pair probes showed lower values were under-bright. Feedback lowers through a fitted table instead of PRC-local constants. Ratio-mode detune belongs in operator frequency lowering. ROM COM values carry output-count compensation; because the amplitude curve was fitted against algorithm 32, DX7 carriers scale by 6/(COM+1). Project-authored Dexed patch rendering now gives lawful calibration targets. Reusing the operator output curve for EG levels was tested and cut because it failed hard-target log-mel. Direct envelope tracing shows current linear `env=rl` cannot express DX7 EG spike/drop behavior. Dexed-style audio samples EG once per 64-sample block and interpolates applied gain, so raw EG parity alone is not audio parity. Staged operator envelopes now support linear/exponential segments and supranormal levels. `ApproximateAppliedRateLevelEnvelope` uses that surface and now picks the first near-peak before gate so slower rising modulators hit early instead of swelling late. PRC log-mel is down to 0.13874426 with RMS at unity; broader analog1.syx community voices pass broad log-mel/envelope gates but expose high zero-crossing mismatch, especially on analog synth and piano-bass timbres.",
"next": "Use the now-validated algorithm-8 route scale as fixed input while isolating remaining PRC high-air/timbre mismatch and community-voice zero-crossing mismatch, then expand to broader public-domain banks."
},
"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": "AQUARIUM_DX7_PYTHON=<bundled python> dotnet test AquariumSynthCSharp.slnx --no-restore",
"result": "70 passed; four actual public-domain analog1.syx community voices pass broad rendered parity and write listening artifacts",
"commit": "pending community DX7 voices"
}
}