AquaSynth/state/memory.json
2026-05-14 13:31:15 +01:00

94 lines
7.8 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",
"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 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",
"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, 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, 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.255, project-authored algorithm-8 summed-stack parity, 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, while summed/cascaded algorithm-8 branches need a lower topology-aware route scale. Feedback now 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, which lets the DSL approximate that contour without a DX7-only syntax escape.",
"next": "Use the curved staged-envelope surface plus `Dx7SysEx.TraceEnvelope`, `Dx7SysEx.TraceInterpolatedEnvelope`, and `artifacts/parity/dx7-envelope-trace/egstep.csv` to calibrate a DX7 lowering that improves rendered PRC log-mel before adding any more public envelope syntax."
},
"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": "65 passed; staged envelope curves parse/render and DX7 trace artifact includes raw/applied/curved gain",
"commit": "pending DX7 interpolated envelope trace"
}
}