930 lines
78 KiB
YAML
930 lines
78 KiB
YAML
project: AquaSynth
|
|
spine_version: 1
|
|
updated: 2026-05-26T22:20:00+01:00
|
|
|
|
prime_directive: >
|
|
Build coherent synth machinery. References exist to reveal missing structure,
|
|
not to justify piling parameters onto the current patch DSL.
|
|
|
|
current_objective: >
|
|
Build the utterance parity curriculum for AquaSynth speech: structured
|
|
utterance metadata lowers into a learned utterance embedding, then into a
|
|
learned synth-driver automation vector for the vocal tract, envelopes, LFOs,
|
|
filters, and spectral lanes. The immediate proof is a fast harness that
|
|
renders simple utterances against a compact speech synthesizer reference,
|
|
scores synth output versus ground truth, and exposes a useful loss landscape
|
|
for backpropagation. External synth digestion is background pressure until it
|
|
directly helps this speech harness.
|
|
|
|
current_mechanism:
|
|
parser: src/AquaSynth.Core/PatchScript.cs
|
|
model: src/AquaSynth.Core/Model.cs
|
|
faust_emitter: src/AquaSynth.Core/FaustExport.cs
|
|
faust_compiler: src/AquaSynth.Faust/FaustCompiler.cs
|
|
native_faust_runtime: src/AquaSynth.Faust/NativeFaustRuntime.cs
|
|
operator_graph_model: src/AquaSynth.Core/Model.cs
|
|
analysis: src/AquaSynth.Core/AudioAnalysis.cs
|
|
built_ins: src/AquaSynth.Core/BuiltInScripts.cs
|
|
patch_library: patches
|
|
dx7_references: src/AquaSynth.Core/Dx7SysEx.cs
|
|
dx7_reference_fixtures: tests/AquaSynth.Dsl.Tests/Fixtures/Dx7/PublicDomain
|
|
dx7_reference_renderer_tests: tests/AquaSynth.Dsl.Tests/Dx7ReferenceParityTests.cs
|
|
zyn_reference_source: external/zynaddsubfx
|
|
pink_trombone_reference_source: external/pink-trombone-mod
|
|
zyn_upstream_instrument_bank: external/zynaddsubfx/instruments
|
|
zyn_reference_build_script: tools/zyn-reference/build-zyn-reference.ps1
|
|
zyn_pad_reference_renderer: tools/zyn-reference/ZynPadReference.cpp
|
|
zyn_reference_reader: src/AquaSynth.Core/ZynInstrument.cs
|
|
zyn_project_fixtures: tests/AquaSynth.Dsl.Tests/Fixtures/ZynAddSubFX/ProjectAuthored
|
|
reference_rebuilds: src/AquaSynth.Core/ReferenceRebuilds.cs
|
|
tests: tests/AquaSynth.Dsl.Tests/PatchScriptTests.cs
|
|
doctrine: docs/audio-doctrine.md
|
|
dx7_calibration_plan: docs/dx7-calibration-plan.md
|
|
zyn_pressure_survey: docs/zynaddsubfx-pressure-survey.md
|
|
roadmap: docs/reference-synth-roadmap.md
|
|
utterance_parity_research: docs/utterance-parity-research.md
|
|
pink_trombone_parity: docs/pink-trombone-parity.md
|
|
pink_trombone_dsl_parity_plan: docs/pink-trombone-dsl-parity-plan.md
|
|
physical_voice_modeling_research: docs/physical-voice-modeling-research.md
|
|
physical_voice_modeling_packet: research/physical-voice-modeling
|
|
parameter_contracts: src/AquaSynth.Core/Model.cs
|
|
|
|
live_invariants:
|
|
- AquaSynth owns its patch graph; external synths are references, not runtime dependencies.
|
|
- Patch scripts lower into explicit graph records before Faust emission.
|
|
- Operator graphs own FM topology: operators, modulation edges, carriers, and feedback. Do not hide this authority inside Voice fields.
|
|
- Readable operator graph authoring uses `operator`, `route`, and `carrier` declarations; compact `ops=`/`edges=` is only scaffolding/interchange.
|
|
- Notes own frequency, gate duration, and host/MIDI source; envelopes own ADSR level shape. Do not put note duration or SFXR punch back into the general envelope model.
|
|
- Faust-managed MIDI polyphony is preferred: emit one voice graph with standard `freq`, `gain`, and `gate` controls plus `[midi:on][nvoices:n]` instead of inflating AquaSynth graphs for local allocation.
|
|
- Generated Faust should remain inspectable and deterministic.
|
|
- AquaSynth owns the Faust toolchain/product boundary: target selection, compile options, cache keys, generated artifact layout, parameter/bus manifests, diagnostics, provenance, native Faust factory lifetime, offline sample-buffer rendering, and dynamic patch compilation outside the realtime callback. Aquarium Engine hosts finished artifacts; it should not own patch-to-DSP compilation semantics.
|
|
- AquaSynth Faust output may be rendered through Faust-generated C# for candidate audio comparison; reference parity still needs a real external render or captured licensed fixture.
|
|
- Reference-patch correctness and synth parity tests live in AquaSynth, not AquaSynth.
|
|
- Exposed patch parameters are runtime controls, not compile-time constants.
|
|
- Parameter binding uses field-site references like `lpf=@/macro/brightness`; do not add target-routing semantics unless a later map proves a new authority is needed.
|
|
- Operator graph parameter binding also uses exact field-site paths under `/opgraphs/...`; do not add graph-wide macro routing.
|
|
- Operator feedback must render through Faust as delayed recursion, not as a direct cyclic self-reference.
|
|
- DX7 operator output level approximation belongs in reference import/rebuild helpers, not the generic DSL model.
|
|
- DX7 carrier output amplitude follows the measured `2^((outputLevel - 99) / 8)` curve; do not restore the old internal-level proxy.
|
|
- DX7 isolated two-operator modulation uses AquaSynth route index `6.275` for full-level modulators; do not apply that blindly to cascaded stacks.
|
|
- DX7 feedback lowers through `Dx7SysEx.OperatorFeedbackAmount`; feedback value 5 remains 0.19 for PRC, while feedback value 7 is much hotter at 2.2 to restore community-patch buzz. Do not restore PRC-local `feedback * constant` folklore.
|
|
- DX7 ratio-mode detune lowers through `Dx7SysEx.OperatorFrequencyRatio`; do not silently drop detune from operator graph scripts.
|
|
- DX7 voice transpose lowers through `Dx7SysEx.NoteFrequencyHz`; transpose 24 is neutral, 12 is one octave down. Do not hardcode `freq=261.6256` for imported voices.
|
|
- DX7 fixed-frequency operators lower through `Dx7SysEx.FixedOperatorFrequencyHz` as absolute Hz divided by the graph base frequency; do not treat fixed mode as a note ratio.
|
|
- DX7 ROM `COM` output compensation is not a carrier-balance authority in AquaSynth lowering; `OperatorOutputCompensation` returns unity and graph gain owns loudness recovery.
|
|
- DX7 operator key-scaling and rate-scaling lower against the effective played MIDI note after voice transpose; do not hardcode MIDI 60 inside imported operator level or envelope timing.
|
|
- DX7 route lowering is topology-aware: isolated direct branches use `OperatorModulationRouteIndex` (`6.275`); summed edges and direct edges feeding summed modulation use `SummedOperatorModulationRouteIndex` (`6.0`).
|
|
- `SummedOperatorModulationRouteIndex` is backed by the hard PRC target, a project-authored algorithm-8 stack probe, and split cascade/summed-pair probes; do not restore the older under-bright `1.6` scale.
|
|
- DX7 calibration must proceed through isolated rungs in `docs/dx7-calibration-plan.md`; do not keep tuning hard PRC-specific constants as a substitute for a level/index model.
|
|
- Staged operator envelopes own multi-target operator level contours through `env=rl rates=... levels=...`; do not force DX7-style contours back into the general ADSR voice envelope model.
|
|
- Staged operator envelopes may use per-segment curves through `curves=lin,exp,...`; this belongs to the rate/level contour authority, not to the standard ADSR envelope.
|
|
- DX7 rate/level envelopes may lower to staged operator envelopes or labeled ADSR approximations, but exact DX7 EG timing/gain calibration remains missing pressure.
|
|
- DX7 envelope trace evidence now lives in `Dx7SysEx.TraceEnvelope`, `Dx7SysEx.TraceInterpolatedEnvelope`, and `artifacts/parity/dx7-envelope-trace/egstep.csv`; Dexed-style audio uses block-interpolated applied gain, not the raw EG state alone.
|
|
- Do not add an `env=dx7` runtime surface until it matches Dexed plugin audio with the block-interpolated gain model, not only the raw trace helper.
|
|
- DX7 applied envelope lowering now lives in `Dx7SysEx.ApproximateAppliedRateLevelEnvelope`; it normalizes traced applied gain so operator output level remains a separate authority.
|
|
- Current DX7 analog1 algorithm-2 lowering caps non-carrier applied-envelope Level1 at 0.92 to avoid modulator peak blowout; treat this as pressure on exact DX7 EG/output modeling, not as permission to add broad peak clamps.
|
|
- `MELLOWSOLO` is a pressure artifact, not passing parity; its render window is 1.25s so the candidate release tail is not cut at the artifact boundary.
|
|
- Do not reduce summed route scale merely because an edge has three sources; a Mooger fan-in route experiment worsened evidence and was cut.
|
|
- Do not replace applied-envelope release with a naive traced threshold duration; it shortened releases too aggressively and broke broader DX7 parity.
|
|
- Recompile only for graph shape changes; vary declared parameters through the hosted DSP control API.
|
|
- Reference fixtures must preserve provenance, license status, source hash, and feature pressure.
|
|
- Public-domain reference fixtures, GPL Zyn instrument-bank fixtures, dexed-py helpers, and pinned ZynAddSubFX source are test/development material only; published NuGet packages must ship only AquaSynth.Core/AquaSynth.Faust surfaces.
|
|
- ZynAddSubFX import starts as feature extraction and then explicit, scoped rebuilds. Upstream GPL `.xiz` instruments may be used as test-only pressure/parity feedstock with provenance reports, while project-authored `.xiz` fixtures remain the clean baseline. The Zyn engine source and instrument bank are pinned under `external/zynaddsubfx` for parity oracles only, not AquaSynth runtime code.
|
|
- Named `layer` declarations own Zyn-style kit/layer identity: engine tag, optional key range metadata, default gain, and effect-send labels. They lower to ordinary voices for now; do not smuggle PAD/free-envelope/effect behavior into them.
|
|
- Additive `harmonics` declarations own authored ratio/gain partial banks under named layers. They lower to ordinary voices for now; do not pretend this covers Zyn ADDsynth phase, bandwidth, oscillator shaping, or free-envelope semantics.
|
|
- Normal voices may use staged `env=rl` rate/level envelopes. Notes still own gate timing; envelopes own level shape. This is not arbitrary Zyn free-envelope point editing.
|
|
- PAD `spectrum` declarations own authored partial clouds under named layers and split table root from playback pitch: `root` is source/base frequency, while `freq` is the note played by the spectral voice. They generate PADsynth-style FFT wavetables with frequency-domain spreading and deterministic random phase, then emit Faust table readers before ordinary voice treatment. Richer PAD table shaping uses neutral `pad_mode`, `pad_bandwidth`, `pad_bwscale`, `pad_profile`, and `pad_position` syntax. The parser may accept older `zyn_*` parity-artifact aliases, but generated/authored `.aqua` should not expose reference-synth names for general DSP intent. Do not pretend this covers every Zyn OscilGen modulation/waveshaping/filter/adaptive-harmonic path yet.
|
|
- Zyn OscilGen oscillator filters use one-based harmonic indices: first harmonic is `1`, not `0`. Preserve that index when translating filter types or spectral peaks move to the wrong partial.
|
|
- Zyn PAD analog high-pass filters are filter authority too: HP1/HP2 type, stages, and FILTER_ENVELOPE motion lower through `hpf_order` and `hpf_env=rl`, not ad hoc layer gain or brightness compensation.
|
|
- Zyn PAD state-variable filters (`category=2`) are filter authority: LP/HP (`type=0/1`) lower through `lpf`/`hpf`, and band/notch (`type=2/3`) lower through `bpf`/`notch`.
|
|
- Band-pass and notch are native AquaSynth filter authorities (`bpf`, `bpf_q`, `bpf_order`, `notch`, `notch_q`, `notch_order`), not Zyn-only compatibility. Zyn PAD analog/SV band-pass and notch filters lower into those fields; formants remain vowel/body color and PAD spectrum remains source-table construction.
|
|
- Zyn PAD selected table roots are not a global default in AquaSynth lowering. Keep sample-0 roots unless a source rule earns the selected root; currently OscilGen shift-base sources (`base_function=7`) may use the selected note table root because Organ Choir proved sample-0 roots leave the octave voice misaligned.
|
|
- Zyn OscilGen base-function modulation is source-table authority: apply it as phase modulation before base-function sampling, not as later oscillator modulation or filter/EQ compensation.
|
|
- Zyn adaptive harmonics remap the prepared oscillator spectrum at the PAD table root frequency before PAD bandwidth/profile spreading. Do not skip it for sources whose wind/body character depends on sparse remapped harmonics.
|
|
- Zyn coverage is now tracked as handled/counted/unknown buckets by `ZynInstrumentSurvey.CoverageDirectory`; do not treat broad parse counts as expressivity. Unknown PAD filter/waveshaper/OscilGen buckets and counted ADD/SUB/LFO/free-envelope/formant/effect buckets need parity workouts before they graduate into AquaSynth model changes.
|
|
- Voice `vowels=` owns authored formant-frame motion: each frame is a static formant bank and `vowel_hz` scans/blends the frames in Faust. Zyn `FORMANT_FILTER` vowel sequences may seed this surface, but Zyn's exact cutoff-position driver, formant slowness, and vowel clearness are still pressure, not hidden compatibility logic.
|
|
- Filter damping is first-class: `lpf_q`/`lpq` owns explicit low-pass Q when a reference synth exposes analog filter damping. Low-pass order remains slope authority even when Q is present; Faust lowering cascades resonant low-pass stages instead of replacing order with one generic resonant filter. Do not fake Q by secretly moving cutoff, slope, or layer gain.
|
|
- Structured `.aqua` stock lives under `patches/` as development source material. Every library patch must parse/export, and the patch library must stay out of the NuGet package unless intentionally promoted.
|
|
- Project-authored Dexed patches may be generated inside tests for calibration; do not ship them in the NuGet package or treat them as runtime dependencies.
|
|
- Harsh calibration probes belong in tests and ignored artifacts, not in the patch library unless they are musically useful stock.
|
|
- Listening WAV artifacts belong under ignored `artifacts/`; keep them out of NuGet and commits unless explicitly promoted as fixtures.
|
|
- Do not consume external synth targets that cannot be backed by parity tests. Parsing is inventory; reproducing behavior through terse, readable AquaSynth DSL is the proof.
|
|
- Audio metrics are evidence, not final judgment.
|
|
- Do not add a generic graph escape hatch until specific references force it.
|
|
- Do not hide missing graph structure behind unrelated voice fields.
|
|
- The speech lane is the active center: IPA parity, utterance embeddings, synth-driver automation, rendered loss, and compiled Faust control sweeps take priority over new DX7/Zyn digestion.
|
|
- Every learned speech arrow must stay inspectable: utterance metadata -> embedding, embedding plus phonetic features -> automation, automation -> rendered audio, rendered audio -> loss/gradient.
|
|
- Pink Trombone parity is structural waveguide pressure, not permission to add more formant proxy knobs. AquaSynth now has a `tract` DSL command that lowers into `Voice.Tract` with PT-shaped runtime controls and a Faust tract-voice proxy; it is still an ordinary voice treatment, not a separate graph owner and not an exact 44-cell/28-cell bidirectional waveguide.
|
|
- Physical voice modeling should generalize around continuous acoustic morphologies, acoustic port networks, source ports, branch/radiation ports, and wave-clock policies. A larynx, syrinx, or alien voice should differ by topology and source-port configuration, not by special-case modules. Faust `physmodels.lib`/`delays.lib` provide useful primitives (`pm.chain`, `pm.l2s`, `pm.waveguideFd*`, `de.fdelay*`, Thiran/allpass and Lagrange delays), but AquaSynth should still generate tract/branch scattering where live area controls and inspectable training parameters matter.
|
|
- The physical voice research packet now includes a practical implementation/researcher map (`research/physical-voice-modeling/PEOPLE.md`) and talk/transcript ledger (`research/physical-voice-modeling/talks/TALKS.md`). Birkholz/VocalTractLab pressures multi-level articulatory control and gestures; Story/TubeTalker pressures continuous parametric area functions and length/coupling; Smith pressures bidirectional delay-line scattering and fractional-delay waveguides; Fels/ArtiSynth pressures separation between biomechanics, acoustics, timeline controls, and diagnostics. These are reusable DSL semantics, not modules to clone.
|
|
- Physical voice implementation has started moving PT pressure into neutral acoustic owners: `AcousticPath`, `AcousticTerminal`, `AcousticConnection`, `AcousticSourcePort`, `AcousticBranch`, `AcousticRadiationPort`, `WaveClockPolicy`, and `AcousticPortNetwork`. Parser commands `path`, `terminal`, `connect`, `source_port`, `branch`, `radiation_port`, `wave_clock`, and `acoustic_network` now exist. Existing `tract_shape`, `glottis`, `tract_injection`, `nasal_branch`, and `tract` commands populate acoustic records as compatibility aliases while the current `Voice.Tract` Faust renderer still owns audio.
|
|
- `acoustic` / `acoustic_voice` can now render an `AcousticPortNetwork` through a compact Faust response proxy or, when typed terminals are present, a compiled bidirectional Faust segment graph. Graph lowering splits paths at terminal positions, aggregates co-located terminals into graph nodes, orders connection ports deterministically, scatters area-weighted/pressure/bypass connection groups, injects source terminals even at connected nodes, and sums radiation terminals. Segment delay follows physical segment length and the network `wave_clock` strategy through unit-grid, half-sample, linear fractional, Lagrange, or Thiran/allpass Faust delay primitives. Source, branch, radiation, terminal, and connection controls can bind through ordinary Aqua parameters into emitted Faust. PT-shaped `tract` authoring can opt into graph audio with `propagation=graph`; legacy `propagation=waveguide` remains the comparison baseline. Remaining pressure: deepen connection-law semantics and run log-mel parity against the graph renderer. Do not expand the proxy into a second fake synthesizer.
|
|
- Pink Trombone log-mel parity now writes both legacy waveguide and graph candidates. Latest graph evidence after source/radiation/side-branch/frication cuts: graph open/front cosine is 0.6202/0.6417, still slightly above the legacy waveguide lane at 0.6143/0.6349; nasal graph cosine improved to 0.5159 and RMS ratio dropped from 1.6914 to 1.4815; sibilant graph cosine remains weak at 0.2302; closure-release graph cosine stays positive at 0.1145 and beats the old negative waveguide baseline. The useful changes were LF-style glottal shaping with a modest harmonic pressure blend, graph radiation high-pass leakage by radiation kind, aperture-weighted high-passed `TurbulenceJet` source semantics, terminal-specific admittance in connection pressure, floored area-ratio pressure normalization for branch outputs, and generated frication ports using max(turbulence, burst) as pressure instead of burst alone. Raw per-port outgoing coupling, squared generated velum opening, lip/beak radiation gain, and un-gated turbulence noise were cut as compensators. Remaining pressure is oral RMS/energy normalization and better frication/transient behavior, not more static shape paperwork.
|
|
- PT expressive parity should decompose into reusable Aqua primitives before audio golf: `tract_shape` owns continuous diameter/area geometry over normalized position, physical length (`length_cm`), interpolation/resampling, derived reflection coefficients, and per-cell acoustic delay; `tract` may resample that geometry to a chosen compiled `sections` grid without making authoring sample count anatomy; `glottis` owns excitation controls; `tract_injection` owns positioned frication/burst controls and now distributes frication pressure into waveguide section updates; `nasal_branch` owns a second diameter/area tube; `tract_motion` owns control slew and obstruction threshold; `propagation=waveguide` lowers tract voices into a Faust-friendly `wg_loop ~ si.bus(...)` feedback component with compiled right/left traveling-wave state, live per-section diameter/area/reflection fields, obstruction-history burst pressure, and legacy substep clock intent. Waveguide tracts now default to an acoustic unit-delay grid from physical length at the current 44.1 kHz target, so a 17 cm oral tract emits about 22 sections instead of treating PT's 44 half-sample cells as anatomy; `VocalTract.IndexScale` maps runtime PT-index controls onto that emitted grid. PT's 44 oral and 28 nasal cells are reference discretization, not Aqua morphology authority. `PinkTromboneParityFixtures` defines fixed Aqua DSL workouts, `PinkTromboneReferenceRenderer` now ports the pinned MIT `chdh/pink-trombone-mod` DSP source (`external/pink-trombone-mod` at 359c2d3b42b10280404c1650dc601902112b4c90), and `AudioComparison` includes log-mel cosine similarity. Reference WAVs before `artifacts/parity/pink-trombone-utterances/20260526T211902375` came from the old fake renderer and are invalid. Do not resume Aqua log-mel golf until the source-ported PT utterance WAVs have been listened to and accepted as a sane oracle. Remaining low-level Aqua gap is fractional-delay waveguide lowering whose clock derives from physical length, propagation speed, and sample rate so runtime morphology motion does not require recompilation; closure/release timing is still badly wrong.
|
|
- If dotnet builds hang in this workspace, stop orphan dotnet workers and retry with `--disable-build-servers -p:UseSharedCompilation=false -p:BuildInParallel=false`; plain parallel/shared builds can stall without useful diagnostics.
|
|
- eSpeak NG is an early parity reference for timing, IPA coverage, and log-mel pressure, not an anatomy oracle or final target.
|
|
- Do not expand into prosody, emotional context, personality, or broad Weksa expressivity until the tiny IPA utterance harness can show useful loss movement.
|
|
- Speech training receipts must keep time as a witness: every request, render result, and checkpoint should record stage decision time, latency spent, latency budget, confidence, and artifact/model identifiers.
|
|
- CultMesh is the speech render/scoring transport and worker-orchestration layer, not distributed checkpoint authority. AquaSynth now has payload manifests, peer/lease admission receipts, worker assignment, result collection, and central checkpoint application. Workers may render, score, return gradients, artifacts, and timing receipts under a lease; the authority trainer or shard-primary applies gradients through `SpeechBackpropagationPipeline` and commits checkpoints through normal CultCache/CultMesh shard authority.
|
|
- Serious speech gradient descent may now start from Weksa's first emitted v0.1 seed batch at `E:\Projects\weksa\examples\speech-training\tiny-panphon-v0.1\batch.json`: 1024 semantic speech-text floats, variable-length PanPhon sequence evidence, 256 AquaSynth-owned phonetic realization embedding floats, 32 prosody/emphasis floats, 64 projected character-state floats, and a 64-float AquaSynth utterance embedding output.
|
|
- Do not use semantic text embeddings as a proxy for IPA or alien phonetic strings. Phonetic/IPA realization starts as PanPhon sequence evidence and is compressed by AquaSynth's phonetic sequence encoder.
|
|
|
|
reference_targets:
|
|
ipa_vocal_tract_weksa:
|
|
priority: 0
|
|
purpose: "Current speech-learning lane: utterance metadata to embedding to synth automation to tract/rendered loss."
|
|
sources:
|
|
- "docs/ipa-vocal-tract-roadmap.md"
|
|
- "docs/utterance-parity-research.md"
|
|
status: "Boundary contracts, packed neural networks, utterance encoder, phonetic sequence encoder, synth-driver mapper, chained backprop, optional eSpeak rendered fixtures, Faust finite-difference loss surface, compiled Faust speech-loss controls, distributed render request/result/checkpoint contracts, timing/confidence receipts, sound-claim cards, and a Weksa-emitted v0.1 tiny PanPhon batch exist. CultMesh speech training now has payload manifests, peer/lease admission receipts, worker assignment, result collection, and central checkpoint application; real network artifact transfer/process supervision remains CultMesh infrastructure. The active need is a loader/training pass that consumes Weksa's batch artifact and tests many controller weights as rendered speech output against simple ground truth."
|
|
first_slice:
|
|
- "Keep the utterance schema small and testable: segments, spans, duration/stress/boundary hints, speaker/morphology identity, pitch/loudness/rate/breath controls, and named context vectors."
|
|
- "Load Weksa's tiny PanPhon v0.1 batch artifact into AquaSynth training records before the next serious gradient descent run."
|
|
- "Use eSpeak NG fixtures for generated ground truth while remembering that formant parity is not anatomy parity."
|
|
- "Connect Stage 0/1 IPA and vowel tract-area fixtures to the compiled Faust loss surface before expanding consonants."
|
|
- "Use the CultMesh speech training step for compiled Faust render/scoring jobs: admit compatible workers under leases, collect `SpeechRenderResult` gradients/receipts, and apply centrally or by one shard-primary trainer. Do not let worker payload transport become optimizer authority."
|
|
dx7_dexed:
|
|
priority: 1
|
|
purpose: "Structured FM/operator graph pressure test."
|
|
source: "https://github.com/asb2m10/dexed"
|
|
status: "DX7 SysEx parser, public-domain SysEx fixture, dexed-py reference rendering, project-authored Dexed patch rendering, first thresholded rendered parity test for analog1.syx voice 13, hard PRC SYNTH1 probe with listening WAV artifacts, project-authored algorithm-8 summed-stack parity, renderable delayed operator feedback, DX7 effective operator-level approximation, measured carrier output amplitude, isolated route index, feedback table, ratio detune lowering, voice transpose lowering, fixed-frequency lowering, ROM COM compensation cut, operator key/rate scaling at the effective played note, staged operator envelopes, DX7 envelope tracing, algorithm topology extraction, envelope-to-ADSR approximation, two AquaSynth DSL rebuild attempts, first-class operator graph support, and AquaSynth candidate rendering through Faust-generated C# exist."
|
|
first_slice:
|
|
- "Add a harder public-domain DX7 parity target that audibly needs operator routing."
|
|
zynaddsubfx:
|
|
priority: 2
|
|
purpose: "Additive, subtractive, PAD, formant, kit, and layered-instrument pressure test."
|
|
source: "https://github.com/zynaddsubfx/zynaddsubfx"
|
|
status: "Initial ZynInstrumentReader reads plain or gzip-compressed .xiz XML from project-authored fixtures and classifies active ADD/SUB/PAD engines, enabled kit items, layering, envelopes, free envelopes, LFOs, filters, formants, and effects as ReferencePatch features. `ZynInstrumentSurvey.CoverageDirectory` now classifies observed Zyn features into handled/counted/unknown buckets and writes `artifacts/parity/zyn-upstream-bank-survey/coverage.md` from the upstream GPL bank. First AquaSynth rebuilds exist for additive lead, PAD texture, and vocal/formant layer and now use named `layer` declarations. Additive rebuilds can use `harmonics` banks attached to layers, PAD rebuilds can use `spectrum` PADsynth-style FFT wavetable banks attached to layers, and PAD/vocal rebuilds use staged voice `env=rl` envelopes through layer defaults. Voices can now use `vowels=` formant frames plus `vowel_hz`; `ZynInstrumentReader.RebuildFirstFormantMotionAsAquaSynthScript` seeds that surface from Zyn `FORMANT_FILTER` vowel sequences for Wide Bass-style workouts while keeping exact Zyn position-driver/smoothing as named missing features. `ZynInstrumentReader.RebuildFirstPadAsAquaSynthScript` now emits per-preset PAD `.aqua` rebuilds for enabled PAD kit items with OSCIL harmonic expansion, oracle-reported table base frequency, PAD detune, Zyn PAD profile/bandwidth/position semantics, static/filter-envelope low-pass mapping, low-pass note tracking, explicit low-pass Q, logarithmic Zyn envelope times, and calibrated PAD output gain. ZynAddSubFX source is pinned under `external/zynaddsubfx` at 3ab608c432996ba4d582176572c0b0f82328c825 for test-only parity work, and `tools/zyn-reference/build-zyn-reference.ps1` now builds an ignored patched source copy with MSYS2/MinGW, proves `PadNoteTest`, and builds `ZynPadReference`, including a test-only `harmonics` mode for dumping normalized OscilGen amplitudes before PAD generation, plus `ZynVoiceReference` for ADD note reference renders. The optional PAD reports emit note and source-table WAV/listening artifacts. The optional formant batch renders Wide Bass, Ghost Ensemble, and Ghost Choir under `artifacts/parity/zyn-upstream-formant-fixtures`; initial scores are 0.280990, 0.312813, and 0.363644, which makes the next workout real rather than flattering. Latest accepted upstream PAD pressure has DoublePadBass close enough by ear with log-mel 0.247748 / score 0.650029 after Q/order cascade, while Ghost Ensemble improves to log-mel 0.369402 / score 0.57229. The remaining Ghost gap is no longer first-32 OscilGen harmonic extraction; oracle harmonic dumps match those ratios. The upstream GPL instrument bank is initialized at `external/zynaddsubfx/instruments` commit c5c912131b31df5fdf372d2f06a25aaf2375837f; survey tests parse 1318/1318 .xiz files, write a pressure report and coverage map, and render a five-patch upstream PAD listening batch under ignored artifacts."
|
|
first_slice:
|
|
- "Use the Zyn PAD oracle report to isolate source-table, playback/gain, envelope, and fixture-mapping mismatch before further Zyn DSL golf."
|
|
- "Use Wide Bass formant-frame output as the foothold before attempting exact Zyn formant cutoff-position driving."
|
|
- "Additive harmonic banks, PAD spectral clouds, staged voice envelopes, and vowel-frame motion now exist; prove any next syntax across more than one target with parity, not parser-only fixtures."
|
|
- "Do not add all remaining pressures at once."
|
|
faust:
|
|
priority: 3
|
|
purpose: "General DSP graph topology pressure test."
|
|
sources:
|
|
- "https://github.com/grame-cncm/faust"
|
|
- "https://faustlibraries.grame.fr/"
|
|
first_slice:
|
|
- "Add ExternalFaustReference catalog entries."
|
|
- "Compile selected official examples as external references."
|
|
- "Use failures to decide whether AquaSynth needs a lower-level graph DSL."
|
|
surge_xt:
|
|
priority: 4
|
|
purpose: "Modern hybrid synth and modulation matrix pressure test."
|
|
source: "https://github.com/surge-synthesizer/surge"
|
|
first_slice:
|
|
- "Inspect factory patch format and license/provenance."
|
|
- "Build feature extractor before translation."
|
|
cardinal:
|
|
priority: 5
|
|
purpose: "Modular graph and cable/rate semantics pressure test."
|
|
source: "https://github.com/DISTRHO/Cardinal"
|
|
first_slice:
|
|
- "Defer until a lower-level graph layer exists."
|
|
|
|
next_agent_start_here:
|
|
recommended_first_task: >
|
|
Continue the utterance parity harness. Start from
|
|
`docs/ipa-vocal-tract-roadmap.md`,
|
|
`docs/utterance-parity-research.md`,
|
|
`src/AquaSynth.Core/SpeechBackpropagationPipeline.cs`,
|
|
`src/AquaSynth.Core/UtteranceEmbeddingLearning.cs`,
|
|
`src/AquaSynth.Core/VocalTractLearning.cs`,
|
|
`src/AquaSynth.Faust/FaustRenderedSpeechLossSurface.cs`, and the optional
|
|
eSpeak tests. The goal is fast rendered speech parity for tiny IPA-adjacent
|
|
utterances: generate ground truth, sweep controller outputs through compiled
|
|
Faust controls, score log-mel/timing/envelope loss, and backpropagate into
|
|
the utterance encoder plus synth driver. Do not resume broad Zyn/DX7 work
|
|
unless it directly improves this harness.
|
|
must_read:
|
|
- AGENTS.md
|
|
- docs/audio-doctrine.md
|
|
- docs/reference-synth-roadmap.md
|
|
- docs/ipa-vocal-tract-roadmap.md
|
|
- docs/utterance-parity-research.md
|
|
- state/spine.yaml
|
|
- state/memory.json
|
|
- state/evidence.jsonl
|
|
verification:
|
|
- "dotnet test AquaSynth.sln --no-restore"
|
|
|
|
completed_slices:
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Fixed Organ Choir's violin-vs-wind source-table mismatch by mapping Zyn
|
|
OscilGen base-function phase modulation and adaptive harmonics. Kit1's
|
|
`base_function=7` source also has `base_function_modulation=1` and
|
|
`adaptive_harmonics=1`; ignoring them produced a smooth bowed-string
|
|
harmonic ramp. The importer now phase-warps the base function before DFT
|
|
and remaps the prepared oscillator spectrum at the selected PAD table
|
|
root. Kit1 table energy now lands near the Zyn body/air balance
|
|
(400-800 Hz 0.2713 vs 0.2780; 8-16 kHz 0.1471 vs 0.1355), and Organ
|
|
improves to log-mel 0.471483 / score 0.541933 without changing accepted
|
|
DoublePadBass, Ghost, or Soft Pad.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 107 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Mapped Organ Choir's remaining PAD voice-alignment issue to two real Zyn
|
|
authorities instead of a gain shove: kit0 uses analog HP2 with six-pole
|
|
high-pass order and FILTER_ENVELOPE cutoff motion, while kit1 uses
|
|
OscilGen `base_function=7` and needs the selected note table root. The
|
|
survey now records sample-0 and selected PAD table roots, but the
|
|
translator only chooses the selected root for shift-base OscilGen sources;
|
|
global selected roots were tested and regressed accepted DoublePadBass.
|
|
Latest Organ candidate is led by the 523 Hz choir voice, with 261 Hz body
|
|
at about -1.29 dB versus Zyn's -2.23 dB. Soft Pad, Ghost, and
|
|
DoublePadBass remain on the accepted sample-0 root path.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 107 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Fixed Zyn OscilGen oscillator-filter harmonic indexing after user listening
|
|
accepted Ghost, DoublePadBass, and Soft Pad but still heard sin2x
|
|
over-emphasizing the wrong high harmonic. Zyn filter functions receive
|
|
one-based harmonic numbers, so AquaSynth's zero-based translation moved
|
|
sin2x's type-13 spike from h2 to h3. Preserving the Zyn index makes the
|
|
generated sin2x table h2-dominant, improves centroid ratio from
|
|
`1.227953` to `0.998145`, and moves log-mel from `0.491437` to
|
|
`0.479782`. Organ Choir remains slightly tinny by ear and sin2x is still
|
|
louder/concentrated, so the next pressure is output/profile shape rather
|
|
than the wrong overtone index.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 106 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Added generated Zyn PAD output calibration after user listening found the
|
|
shape right but Zyn still peaking much louder. This is a patch-level
|
|
calibration for Zyn PAD rebuilds (`patch gain=1.6`), not a table
|
|
normalization or core DSL change. It corrects a batch-wide note-output
|
|
level deficit after table/filter/envelope semantics were mapped: latest
|
|
DoublePadBass candidate WAV peak is `0.979` against the clipped Zyn
|
|
reference WAV peak `1.0`, log-mel stays `0.211671`, envelope distance
|
|
improves to `0.226563`, RMS ratio to `0.818669`, and score to `0.631168`.
|
|
The rest of the current PAD batch stays in a plausible RMS range
|
|
(`0.94..1.24` except DoublePadBass at `0.82`).
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 104 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Corrected Zyn PAD envelope timing after user listening reported that
|
|
DoublePadBass hit hard enough but the attack was too soft and blared.
|
|
The importer had been using linear `dt/127`; Zyn's old envelope time curve
|
|
is `(2^(dt/127*12)-1)/100`, so DoublePadBass kit0 attack `10` should be
|
|
about `0.00925s`, not `0.07874s`. The PAD gain ceiling is relaxed to
|
|
`3.0` so loud PADs are no longer amputated, but the raw Zyn `4x` volume
|
|
multiplier remains cut because it overdrives the whole fixture batch.
|
|
DoublePadBass improved to log-mel `0.211646`, envelope distance
|
|
`0.462822`, RMS ratio `0.511669`, score `0.450507`.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 104 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Added a general low-pass rate/level envelope surface and mapped Zyn PAD
|
|
`FILTER_ENVELOPE` into it after user listening identified that
|
|
DoublePadBass had the right tone but not Zyn's harder opening hit.
|
|
`RateLevelEnvelope` now carries an optional start level, Faust emits
|
|
`rl4_env_from`, and voices can specify `lpf_env=rl` with `lpf_start`,
|
|
`lpf_rates`, `lpf_levels`, and optional `lpf_curves`. The Zyn importer
|
|
converts ADSR-filter envelope values into cutoff offsets from the static
|
|
Zyn cutoff, preserving the immediate open-filter transient. DoublePadBass
|
|
improved from log-mel `0.259298` / envelope distance `0.631427` to
|
|
`0.241993` / `0.554658`; remaining pressure is mostly level/RMS.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 104 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Mapped two missing Zyn PAD authorities exposed by DoublePadBass listening:
|
|
analog low-pass slope and PAD frequency detune. AquaSynth now has a general
|
|
`lpf_order` field which emits Faust `fi.lowpass(order, ...)`; Zyn analog
|
|
`LP2` filters lower to `lpf_order=2` and include Zyn stage count. The Zyn
|
|
PAD importer also applies Zyn `getdetune` semantics to
|
|
`FREQUENCY_PARAMETERS`, so DoublePadBass `coarse_detune=15360` wraps to
|
|
one octave down and generated `spectrum` playback moves from `261.6256`
|
|
to `130.8128`. DoublePadBass log-mel moved from `0.334546` after static
|
|
cutoff mapping to `0.259298`; the remaining gap is mostly envelope/RMS,
|
|
not wrong pitch or high-band balance.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 103 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Mapped static Zyn PAD global low-pass filters into generated Aqua layers
|
|
after user listening identified DoublePadBass as over-emphasizing kit0's
|
|
high buzz while the reference character comes from kit1's low rumble.
|
|
The importer now reads nested `FILTER` params under
|
|
`FILTER_PARAMETERS` and uses Zyn's old filter cutoff curve
|
|
`2^((Pfreq / 64 - 1) * 5 + log2(1000))`; kit0's `freq=12` lowers to
|
|
`lpf=0.003325`, while kit1's `freq=61` lowers to `lpf=0.047225`. The
|
|
louder gain-cap experiment stayed cut. Filter envelopes and LFOs remain
|
|
explicit missing pressure.
|
|
verification: "dotnet test tests\\AquaSynth.Dsl.Tests\\AquaSynth.Dsl.Tests.csproj --no-restore --filter FullyQualifiedName~ZynReferenceParityTests: 4 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Addressed the two user-identified Zyn PAD offenders separately. Ghost
|
|
Ensemble was collapsing toward Soft Pad because the direct-harmonic gate
|
|
ignored its live `base_function=4` power oscillator when no downstream
|
|
oscillator stage was enabled; power-base multi-harmonic sources now run
|
|
through the sampled OscilGen path, giving Ghost its own 32-partial source.
|
|
DoublePadBass was not being treated as the actual preset: it is
|
|
`kit_mode=1` with two enabled PAD kit items. The upstream parity path now
|
|
sums enabled PAD kit-note references, gathers per-kit table roots, and
|
|
rebuilds enabled PAD kit layers into one Aqua script. A louder gain-cap
|
|
experiment worsened DoublePadBass and was cut.
|
|
verification: "dotnet test tests\\AquaSynth.Dsl.Tests\\AquaSynth.Dsl.Tests.csproj --no-restore --filter FullyQualifiedName~ZynReferenceParityTests: 4 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Reworked the first Zyn OscilGen approximation into a sampled stage-order
|
|
path for PAD presets with live oscillator processing: base waveform,
|
|
optional oscillator filter/waveshaper order, modulation, harmonic shift,
|
|
and spectrum adjustment before extracting partials. Direct harmonic PAD
|
|
presets now stay on the simple readable path capped at 32 partials
|
|
instead of exploding into base-function-only frequency combs. This
|
|
improves the processed `sin2x pad` target versus the previous subset
|
|
while keeping the pass honest: DoublePadBass and Organ Choir Pad2 still
|
|
miss badly, so Zyn PAD parity remains open pressure.
|
|
verification: "dotnet test tests\\AquaSynth.Dsl.Tests\\AquaSynth.Dsl.Tests.csproj --no-restore --filter FullyQualifiedName~ZynReferenceParityTests: 4 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Promoted explicit Zyn PAD table semantics into the AquaSynth model and
|
|
parser. `SpectralBank` now carries `PadSpectrumProfile`; patch scripts can
|
|
express Zyn PAD mode, bandwidth, bandwidth scale, harmonic profile, and
|
|
harmonic-position warp through readable `zyn_*` fields, and
|
|
`PadSynthWaveform` lowers those banks with Zyn-style profile/bandwidth
|
|
math while preserving the old generic `spectrum` path. Zyn PAD rebuilds
|
|
now emit those fields, use Zyn's exponential PAD volume curve, and expand
|
|
a first OscilGen base-function/spectrum-adjust subset into partials. The
|
|
OscilGen subset is mixed evidence rather than solved parity: Soft Pad and
|
|
Organ Choir Pad2 improve, while sin2x, DoublePadBass, and Ghost Ensemble
|
|
regress, so the next cut must either complete more OscilGen semantics or
|
|
gate the approximation to the cases it owns.
|
|
verification: "dotnet test tests\\AquaSynth.Dsl.Tests\\AquaSynth.Dsl.Tests.csproj --no-restore --filter \"FullyQualifiedName~ZynInstrumentTests|FullyQualifiedName~ZynReferenceParityTests\": 13 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Initialized the upstream GPL ZynAddSubFX instrument bank submodule and
|
|
made it explicit test-only feedstock. Added an optional survey test that
|
|
parses 1318 `.xiz` instruments and writes
|
|
`artifacts/parity/zyn-upstream-bank-survey/report.txt`, plus an optional
|
|
oracle render batch for five upstream PAD instruments under
|
|
`artifacts/parity/zyn-upstream-pad-fixtures/`. Zyn PAD artifacts now use
|
|
per-synth timestamped folders with reference WAVs, table WAVs,
|
|
`candidate.aqua`, and `report.txt`; upstream GPL runs now render
|
|
per-preset first-pass PAD rebuilds as `candidate-aquasynth.wav`, with
|
|
reports naming which Zyn PAD semantics are still missing. The
|
|
batch includes `Pads/0002-sin2x pad.xiz`, `Pads/0065-Soft Pad.xiz`,
|
|
`Dual/0008-Organ Choir Pad2.xiz`, `Laba170bank/0098-DoublePadBass.xiz`,
|
|
and `Companion/0121-Ghost Ensemble.xiz`.
|
|
verification: "dotnet test AquaSynth.sln --no-restore --filter FullyQualifiedName~ZynReferenceParityTests: 4 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Added more project-authored PAD fixtures and a Zyn-only PAD fixture
|
|
survey. `pad-pure.xiz` captures the default pure PAD path, and
|
|
`pad-harmonic.xiz` adds explicit OSCIL harmonics. The survey writes Zyn
|
|
note/table WAVs and metrics under `artifacts/parity/zyn-pad-fixtures`.
|
|
First result: `pad-pure` and the old `pad-texture` render identically
|
|
through the oracle, so the `pad-texture` filter/category XML was not live
|
|
pressure; `pad-harmonic` changes both table and note output and is the
|
|
next useful PAD rung.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 98 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Removed the detuned impression in the Zyn PAD rebuild by collapsing the
|
|
same-note low/high PAD voices into one coherent spectral table and trimming
|
|
patch gain after user listening found the previous version close but too
|
|
loud. Latest report: log-mel 0.35669, envelope 0.347572, RMS ratio
|
|
1.001704, centroid ratio 1.004072, score 0.6211. This preserves the
|
|
pitch/root split and avoids treating voice stacking as PAD richness.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 97 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Fixed the octave-low Zyn PAD rebuild by splitting spectral table root
|
|
from playback frequency. `spectrum root=...` now owns the source/base
|
|
frequency used for wavetable playback scaling, while `freq=...` remains
|
|
the note frequency on the spectral voice. The project-authored PAD rebuild
|
|
now uses Zyn's reported table base frequency 77.7813 and plays 261.6256.
|
|
Removing gratuitous spread/vibrato reduced the drone the user heard.
|
|
Latest report: log-mel 0.353365, envelope 0.348752, RMS ratio 0.97283,
|
|
centroid ratio 0.999243, score 0.612832.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 97 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
De-beed the project-authored Zyn PAD rebuild after listening identified
|
|
AquaSynth as a noisy swarm while Zyn sounded like a pure blown wineglass.
|
|
Cut the unearned `air` noise layer, drive, and soft clipping from the PAD
|
|
rebuild; added interpolated Faust wavetable reads for spectral banks; and
|
|
raised spectral PAD tables to Zyn's 131072-frame sample size. The optional
|
|
Zyn PAD report now also writes the source table WAV
|
|
`pad-texture-zyn-table0.wav`. Latest report: log-mel 0.405313, envelope
|
|
0.35139, RMS ratio 1.008516, centroid ratio 1.083082, score 0.487325.
|
|
This is a real improvement from 0.236117 but not passing; remaining
|
|
pressure is exact source profile/table generation and Zyn amplitude
|
|
semantics.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 96 passed"
|
|
- date: 2026-05-15
|
|
summary: >
|
|
Added `ZynPadReference`, a test-only executable copied into the ignored
|
|
Zyn artifact source and built by `build-zyn-reference.ps1`. It loads a
|
|
`.xiz`, enters a chosen kit item's `PAD_SYNTH_PARAMETERS`, uses Zyn's own
|
|
`PADnoteParameters`/`PADnote` path, and writes either generated PAD table
|
|
samples or rendered note audio as raw float32. Added an optional C# parity
|
|
harness that runs the renderer when the artifact executable exists and
|
|
writes Zyn/AquaSynth WAVs plus a report under
|
|
`artifacts/parity/zyn-pad-reference`. First report: log-mel 0.552296,
|
|
envelope 0.774501, RMS ratio 0.234763, centroid ratio 1.025735, score
|
|
0.236117, so the harness works and current AquaSynth `spectrum` is not yet
|
|
a close PAD emulation.
|
|
verification: "powershell -NoProfile -ExecutionPolicy Bypass -File tools\\zyn-reference\\build-zyn-reference.ps1; dotnet test AquaSynth.sln --no-restore: 96 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Built the pinned ZynAddSubFX source as a test-only MSYS2/MinGW parity
|
|
oracle without dirtying the checked-in submodule. The build script copies
|
|
`external/zynaddsubfx` to ignored `artifacts/zyn-source-msys`, applies a
|
|
repo-owned compatibility patch for the stale `Part` constructor call,
|
|
configures GUI/plugins off with tests on and `Werror=OFF`, builds
|
|
`PadNoteTest`, and runs the CTest target. The next rung is a small
|
|
reference renderer/wrapper that emits PAD audio or tables for AquaSynth
|
|
`spectrum` parity.
|
|
verification: "powershell -NoProfile -ExecutionPolicy Bypass -File tools\\zyn-reference\\build-zyn-reference.ps1: PadNoteTest passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Pinned ZynAddSubFX source as a GPL test/development reference under
|
|
`external/zynaddsubfx` at 3ab608c432996ba4d582176572c0b0f82328c825.
|
|
Added guard tests proving the source, license, PAD implementation files,
|
|
and commit are present, and tightened the package-boundary test so
|
|
`external/`, C++ sources, and headers do not ship in
|
|
published AquaSynth packages. This establishes Zyn as a parity oracle, not
|
|
AquaSynth implementation.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 95 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added PAD spectral-cloud syntax for named layers. `spectrum
|
|
layer=pad_low root=130.8128 spread=.012 partials=1:.07,1.5:.052`
|
|
records authored PAD partial intent as `SpectralBank`, then generates a
|
|
PADsynth-style table with frequency-domain harmonic spreading,
|
|
deterministic random phase, one inverse FFT, and Faust waveform/rdtable
|
|
playback before ordinary voice treatment. The Zyn PAD texture rebuild now
|
|
uses two spectral banks under `pad_low` and `pad_high`; full Zyn PAD
|
|
profile/randomness/pitch-zone behavior remains missing pressure.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 94 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Promoted staged rate/level envelopes from operator graphs to normal
|
|
voices and layer defaults. Voice parsing now accepts `env=rl
|
|
rates=... levels=... curves=... gate=...`, stores the staged contour on
|
|
`Voice.RateLevelEnvelope`, and Faust emission uses `rl4_env` for those
|
|
voices. The Zyn PAD texture and vocal-layer rebuilds now use staged
|
|
envelopes through named layers, proving the surface beyond a single
|
|
fixture while leaving arbitrary Zyn free-envelope point curves as missing
|
|
pressure.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 91 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added additive harmonic-bank syntax for named layers. `harmonics
|
|
layer=body root=220 partials=1:.16,2:.075` records authored ratio/gain
|
|
partial banks in the model, then lowers them to ordinary voices for
|
|
inspectable Faust output. The Zyn additive lead rebuild now uses two
|
|
banks under `body` and `shine`, while the catalog marks harmonic-bank
|
|
support as matched and keeps Zyn ADDsynth phase/bandwidth/oscillator
|
|
detail as missing pressure.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 90 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added the first Zyn-driven language-golf abstraction: `layer`.
|
|
Layer declarations own name, engine tag, optional MIDI key range metadata,
|
|
default gain, and effect-send labels while lowering to ordinary AquaSynth
|
|
voices. The three Zyn-style rebuilds now use named layers, proving the
|
|
abstraction generalizes across additive, PAD-texture, and vocal/formant
|
|
targets without adding fixture-specific shortcuts or hidden PAD/effect
|
|
behavior.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 88 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Hardened the Zyn reader against the real upstream instrument bank and
|
|
added `ZynInstrumentSurvey`. The reader now tolerates leading whitespace
|
|
before XML declarations and counts actual `FILTER`/`FORMANT_FILTER`
|
|
blocks instead of internal formant/vowel nodes. A non-vendored scan of
|
|
`zynaddsubfx/instruments` commit `e9f64a9` parsed 1358/1358 `.xiz`
|
|
files. The top pressure target is `olivers-100/0032-Drum Kit.xiz`, with
|
|
16 enabled kit items, mixed ADD/SUB/PAD engines, 106 envelopes, 25 free
|
|
envelopes, 73 LFOs, 37 filters, and 3 formant filters. The survey points
|
|
to named kit/layer routing as the next owner abstraction before syntax
|
|
golf.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 86 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added first Zyn-style AquaSynth rebuilds for the project-authored additive
|
|
lead, PAD texture, and vocal/formant layer fixtures. The rebuild catalog
|
|
now records matched and missing features for each target, while tests
|
|
parse/export the scripts and verify matched feature claims against source
|
|
fixture features where names overlap. The first concrete Zyn pressure is:
|
|
additive harmonic-bank syntax, PAD/spectral source generation, free
|
|
envelopes for normal voices, named kit/layer routing with per-layer effect
|
|
sends, and richer formant/vowel morphing.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 83 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Started the ZynAddSubFX phase after closing the current DX7 community
|
|
batch. Added `ZynInstrumentReader` for `.xiz`-shaped XML, including
|
|
gzip-compressed XML support, and project-authored Zyn fixtures for an
|
|
additive lead, PAD texture, and vocal/formant layer. The classifier emits
|
|
neutral `ReferencePatch` features for active ADD/SUB/PAD engines, enabled
|
|
kit items, layering, envelopes, free envelopes, LFOs, filters, formants,
|
|
and effects. Upstream Zyn bank files were inspected but not vendored
|
|
because preset provenance was not explicit enough for this first slice.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 81 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Reframed the latest community listening as envelope pressure rather than
|
|
harmonic pressure. `{ Mooger }` needs a more aggressive attack contour;
|
|
`RES SYNTH1` still has a phase-like attack-modulation issue even though
|
|
oscillator sync is enabled; `MELLOWSOLO` needed its pressure artifact to
|
|
capture the release tail. Extended only `MELLOWSOLO` from a 1.0s render
|
|
to 1.25s, improving pressure log-mel to 0.3472474 and score to 0.5722256.
|
|
Tested and cut a global traced-release-duration change because it broke
|
|
PRC, `Piano Bass`, `RES SYNTH1`, and `ANLGSYN 1`.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 76 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added scoped modulator peak headroom after listening found `ANLGSYN 1`
|
|
and `RES SYNTH1` blowing out into a drone at the modulator peak while
|
|
`Piano Bass` was spot on. The DX7 probe lowering now caps only
|
|
algorithm-2 non-carrier applied-envelope Level1 at 0.92. Latest focused
|
|
metrics: `RES SYNTH1` score 0.8140223, log-mel 0.12369786, envelope
|
|
0.06489321; `Piano Bass` unchanged at score 0.7910121, log-mel
|
|
0.13413505; `ANLGSYN 1` score 0.6980632, log-mel 0.19461302, sustained
|
|
high-band still above gate; `MELLOWSOLO` score 0.55206907, log-mel
|
|
0.42906323. Tested and cut a three-source summed-route headroom rule for
|
|
`{ Mooger }`; it worsened Mooger metrics and did not isolate the overtone
|
|
issue.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter Dx7... focused pass: 28 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Lowered DX7 operator key-scaling and rate-scaling against the effective
|
|
played MIDI note after voice transpose. `Dx7SysEx.OperatorRateScaling`
|
|
now feeds the block-interpolated applied envelope trace, and the DX7
|
|
probe no longer computes operator levels at hardcoded MIDI 60. This
|
|
improves `RES SYNTH1` attack/log-mel and `Piano Bass` harmonic metrics;
|
|
`Piano Bass` graph gain rebalances to 0.72. Added a `MELLOWSOLO`
|
|
pressure artifact test because it remains the clearest harmonic mismatch
|
|
and should not be promoted as passing stock. A trial that made envelope
|
|
tracing depend on operator output level was cut because it worsened
|
|
`MELLOWSOLO` and `ANLGSYN 1`.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter Dx7... focused pass: 28 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Removed DX7 ROM COM carrier compensation after listening found the
|
|
no-compensation community renders had closer harmonics and were mainly
|
|
too quiet. `OperatorOutputCompensation` now returns unity; graph gain owns
|
|
loudness recovery. Passing community graph gains are now `{ Mooger }`
|
|
0.75, `Piano Bass` 0.90, and `RES SYNTH1` 0.75. `RES SYNTH1` joined the
|
|
passing community gate with score 0.7277295, log-mel 0.1461968, envelope
|
|
0.10764466, RMS 0.941083. `DX1 LEAD B` and `MELLOWSOLO` sound closer by
|
|
ear under no-COM/gain-restored lowering but still fail numeric gates, so
|
|
they remain pressure targets.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 74 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Fixed the remaining `ANLGSYN 1` drift after listening found the
|
|
conditional output-clip candidate still lost buzz halfway through the
|
|
note. `Dx7SysEx.ApproximateAppliedRateLevelEnvelope` now accepts a
|
|
sustain floor, and max-feedback source operators use a 0.9 floor in the
|
|
DX7 probe lowering so the feedback loop stays driven after the attack.
|
|
`ANLGSYN 1` now also gates a sustained 2.5-5 kHz band-energy ratio so
|
|
the old drifting version cannot pass global metrics alone. `Piano Bass`
|
|
graph gain moved to 0.30, bringing its RMS ratio to 0.9909909. Latest
|
|
`ANLGSYN 1`: score 0.7245976, log-mel 0.18460114, envelope 0.119950555,
|
|
zero-crossing 0.97149533.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 74 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Tightened the `ANLGSYN 1` parity rung after listening caught the remaining
|
|
`deeooh` failure: the hotter feedback attack was close, but sustained
|
|
high-band buzz collapsed midway through the note. The DX7 probe lowering
|
|
now enables AquaSynth's existing output soft clip only for max-feedback
|
|
voices with a self-feedback topology. PRC remains `soft_clip=false`.
|
|
Latest `ANLGSYN 1`: score 0.70946133, log-mel 0.18456098, envelope
|
|
0.10628832, RMS ratio 0.9816304, zero-crossing 0.8657629. Latest PRC:
|
|
score 0.7546429, log-mel 0.13874851, envelope 0.067291394.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 73 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Retuned DX7 max-feedback lowering after listening found `ANLGSYN 1` still
|
|
sounded like `woooh` instead of Dexed's buzzier `deeeh`. Route-index
|
|
sweeps did not help; increasing only DX7 feedback value 7 from 0.66 to
|
|
2.2 restored high-band energy while leaving feedback value 5, and
|
|
therefore PRC's feedback amount, unchanged. For `ANLGSYN 1`, log-mel
|
|
improves from 0.19427659 to 0.17553389 and centroid ratio from 0.9182808
|
|
to 0.9519112. Band evidence: 1.2-2.5 kHz candidate/reference energy
|
|
rises from 0.8% to 65.6%, and 2.5-5 kHz from near zero to 32.1%.
|
|
Envelope/RMS are still imperfect, so this is a timbre correction rather
|
|
than the final word on ANLGSYN.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 73 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Fixed DX7 fixed-frequency operator lowering after listening caught
|
|
`ANLGSYN 1` losing its buzzing modulation and collapsing into the wrong
|
|
drone. `Dx7SysEx.FixedOperatorFrequencyHz` now follows Dexed's fixed-mode
|
|
log-frequency formula, and `OperatorFrequencyRatio` lowers fixed
|
|
operators as absolute Hz divided by the graph base frequency. In
|
|
`ANLGSYN 1`, fixed carriers op1/op3 now lower to ratios 0.007615 and
|
|
0.009227 instead of the old fake 0.5. Added a focused parity test for
|
|
`ANLGSYN 1`; latest metrics improve to log-mel 0.19427659, envelope
|
|
0.14924917, zero-crossing 0.94662774, centroid 0.9182808, score
|
|
0.659334.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 73 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Fixed DX7 voice transpose lowering after listening caught `Piano Bass`
|
|
rendering an octave too high. Added `Dx7SysEx.NoteFrequencyHz`, where
|
|
transpose 24 is neutral and transpose 12 lowers MIDI note 60 to
|
|
130.8128 Hz. `Dx7VoiceProbeScript` now uses the voice transpose for graph
|
|
frequency and detune note basis. Narrowed the community parity gate to
|
|
the two defensible voices, `{ Mooger }` and `Piano Bass`; `ANLGSYN 1`,
|
|
`RES SYNTH1`, `DX1 LEAD B`, and `MELLOWSOLO` remain pressure, not passing
|
|
parity. Fixed `Piano Bass` improves to log-mel 0.16180529, envelope
|
|
0.13544041, zero-crossing 0.905511, and score 0.64267576.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 71 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added a rendered public-domain community DX7 parity test against four
|
|
actual `analog1.syx` voices from Musical Artifacts artifact 152:
|
|
`ANLGSYN 1`, `{ Mooger }`, `Piano Bass`, and `RES SYNTH1`. The test
|
|
renders Dexed references, lowers the same voices through the current
|
|
AquaSynth DX7 operator-graph path, writes listening WAV/report artifacts
|
|
under `artifacts/parity/dx7-community-analog1/`, and gates broad parity
|
|
at log-mel <= 0.3, envelope <= 0.16, score >= 0.5. First survey also
|
|
tried `DX1 LEAD B` and `MELLOWSOLO`; they remain pressure because
|
|
log-mel/zero-crossing mismatch is too large for the broad gate.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 70 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added split project-authored DX7 algorithm-8 parity probes for the
|
|
cascaded `6 -> 5 -> 3` branch and summed `4 + 5 -> 3` branch. The tests
|
|
render Dexed references, render AquaSynth operator-graph candidates, write
|
|
listening WAV/report artifacts under `artifacts/parity/dx7-project-authored/`,
|
|
and gate log-mel at <= 0.06. Latest real-Dexed run: combined stack
|
|
log-mel 0.04029555/score 0.8664546, summed pair 0.042429477/0.870778,
|
|
cascade 0.03811625/0.9157809. The split probes remain test/artifact
|
|
material rather than patch-library stock because they are calibration
|
|
signals, not usable sounds.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore: 69 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added a structured development patch library under `patches/` with a
|
|
machine-readable `library.yaml`, README, and `.aqua` files exported from
|
|
existing stock/reference catalogs plus the calibrated PRC SYNTH1 parity
|
|
candidate. Added tests so every library `.aqua` parses and exports Faust,
|
|
while package-boundary tests assert `patches/` and `.aqua` files do not
|
|
ship in the AquaSynth.Dsl NuGet package.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 67 passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Increased `Dx7SysEx.SummedOperatorModulationRouteIndex` from 1.6 to 6.0
|
|
after listening identified missing harsh stacked-modulation brightness.
|
|
The stronger scale improves PRC log-mel to 0.13874426, envelope distance
|
|
to 0.067291506, centroid ratio to 1.1156512, and score to 0.7546445 with
|
|
RMS ratio 0.9912135. The independent project-authored algorithm-8
|
|
summed-stack test now uses graph gain 0.218 and tighter log-mel/RMS gates.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter \"PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled|ProjectAuthoredDx7AlgorithmEightSummedStackMeetsParityWhenInstalled\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added `Dx7SysEx.ApproximateAppliedRateLevelEnvelope` and used it in the
|
|
hard PRC SYNTH1 probe. The helper traces Dexed-style block-interpolated
|
|
applied EG gain, normalizes it against AquaSynth operator-output scaling,
|
|
and emits curved `env=rl` syntax. PRC log-mel improved from 0.24476814 to
|
|
0.21931955 and envelope distance from 0.43700194 to 0.10271241, with RMS
|
|
ratio near unity. A follow-up fixed the peak picker for slower rising
|
|
envelopes after listening exposed op2's false late swell; PRC now reaches
|
|
log-mel 0.17186502, envelope distance 0.13057204, zero-crossing ratio
|
|
0.7815517, and score 0.6501268.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter \"PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled|ProjectAuthoredDx7AlgorithmEightSummedStackMeetsParityWhenInstalled|ApproximatesDx7AppliedEnvelopeAsCurvedRateLevelEnvelope\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added per-segment curves to staged operator envelopes. `env=rl` remains
|
|
the same rate/level contour surface, but can now express linear or
|
|
exponential segments with deliberate levels above unity. The DX7 envelope
|
|
trace artifact includes a curved AquaSynth candidate that is much closer
|
|
to Dexed's block-interpolated applied gain than the old linear contour.
|
|
verification: "dotnet test AquaSynth.sln --no-restore --filter \"OperatorGraphSyntaxParsesReadableRateLevelEnvelope|OperatorGraphSyntaxParsesCurvedRateLevelEnvelope|ProjectAuthoredDx7EnvelopeTraceWritesComparisonArtifact\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added `Dx7SysEx.TraceInterpolatedEnvelope` and extended the DX7 envelope
|
|
trace artifact with raw and applied gain columns. Dexed-style operator
|
|
rendering samples the EG once per 64-sample block and interpolates the
|
|
applied gain across the block, so matching the raw EG state alone is not
|
|
enough for audio parity.
|
|
verification: "dotnet test AquaSynth.sln --no-restore --filter \"TracesDx7EnvelopeAppliedBlockInterpolatedGain|TracesDx7EnvelopeInternalGainShape|ProjectAuthoredDx7EnvelopeTraceWritesComparisonArtifact\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added `Dx7SysEx.TraceEnvelope` and an envelope trace comparison artifact.
|
|
The trace shows DX7 EG behavior that current `env=rl` cannot express:
|
|
an initial gain spike above 1 followed by millisecond-scale collapse to a
|
|
tiny sustain. A first `env=dx7` runtime lowering attempt was cut because
|
|
matching the local trace did not match Dexed plugin audio.
|
|
verification: "dotnet test AquaSynth.sln --no-restore --filter \"ProjectAuthoredDx7EnvelopeTraceWritesComparisonArtifact|TracesDx7EnvelopeInternalGainShape\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added test-only project-authored Dexed patch rendering and an independent
|
|
algorithm-8 summed-stack parity test. This backs topology-aware summed
|
|
route lowering outside the public-domain PRC hard target. An attempted
|
|
exponential DX7 EG level curve was tested and cut: it improved some
|
|
envelope metrics but failed PRC log-mel, so EG levels remain linear until
|
|
isolated envelope parity can pass without harming PRC.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter \"ProjectAuthoredDx7AlgorithmEightSummedStackMeetsParityWhenInstalled|PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled|Dx7SysExTests\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Moved the remaining PRC cascaded-route scalar into
|
|
`Dx7SysEx.OperatorRouteIndex(topology, edge)`. Isolated direct branches
|
|
use the two-op route scale 6.275; summed edges and direct edges feeding a
|
|
summed branch use the summed/cascaded route scale 1.6. The PRC probe no
|
|
longer owns a private route-index function.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter \"Dx7SysExTests|PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added DX7 ratio-mode detune and algorithm output compensation to central
|
|
lowering. `Dx7SysEx.OperatorFrequencyRatio` preserves detune in operator
|
|
graph ratios, and `Dx7SysEx.OperatorOutputCompensation` maps ROM `COM`
|
|
output counts relative to the algorithm-32 six-output amplitude baseline.
|
|
The PRC probe no longer carries a manual carrier-level scale table; its
|
|
remaining cascaded-route value is fenced as a hard-target probe scar.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter \"Dx7SysExTests|PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Completed the DX7 feedback calibration rung. Isolated feedback sweeps fit
|
|
AquaSynth feedback amounts `0, .01, .02, .05, .10, .19, .38, .66` for DX7
|
|
feedback values 0-7. `Dx7SysEx.OperatorFeedbackAmount` now owns that
|
|
table, and the PRC probe no longer uses a local `feedback * constant`.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter \"CalibratesDx7FeedbackToAquaSynthFeedbackAmount|PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Completed the isolated two-operator modulation-index rung. Dexed sweeps
|
|
fit full-level modulation at about 12.55 radians, which maps to AquaSynth
|
|
route index 6.275 under the current Faust phase formula. The PRC probe
|
|
applies that calibrated route only to the isolated `op2 -> op1` branch;
|
|
applying it to the cascaded stack made metrics worse, leaving algorithm
|
|
output compensation as explicit pressure.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled: passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Added `docs/dx7-calibration-plan.md` and completed the first calibration
|
|
rung. A project-authored Dexed single-carrier output-level sweep showed
|
|
carrier amplitude follows `2^((outputLevel - 99) / 8)`. `Dx7SysEx` now
|
|
exposes `OperatorOutputAmplitude` and `ApproximateOperatorLevel` uses that
|
|
measured curve instead of the old internal-level proxy. The PRC log-mel
|
|
gate is temporarily 0.26 while the next rung calibrates modulation index.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter \"Dx7SysExTests|PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled\": passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Reoriented the hard DX7 `PRC SYNTH1` probe around log-mel distance after
|
|
listening confirmed aggregate score was rewarding the wrong thing.
|
|
Spectral diagnosis showed the reference's low body around 131 Hz and
|
|
dominant 393 Hz partial; the candidate now uses the DX7 note basis and
|
|
scaled high modulators to reach log-mel 0.25093183, with remaining
|
|
zero-crossing/centroid mismatch left as explicit pressure.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled: passed"
|
|
- date: 2026-05-14
|
|
summary: >
|
|
Tightened the hard DX7 `PRC SYNTH1` probe to require score >= 0.60 and
|
|
improved the candidate to 0.6057491. The useful calibration cuts were
|
|
removing AquaSynth soft clipping, setting the graph base frequency to 392,
|
|
and boosting the op3 carrier branch for algorithm-8 output/body balance.
|
|
Global detune and per-edge route damping were tested and cut because they
|
|
made the metrics worse.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled: passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added a hard DX7 `PRC SYNTH1` rendered parity probe that emits listening
|
|
WAV artifacts under ignored `artifacts/parity/dx7-prc-synth1` when
|
|
dexed-py and Faust are available. The AquaSynth candidate uses readable
|
|
operator graph syntax and staged `env=rl` envelopes, asserts a modest
|
|
hard-target score floor, and currently scores 0.4581856 with duration
|
|
close to the Dexed reference but remaining gain/timbre mismatch.
|
|
verification: "AQUASYNTH_DX7_PYTHON=<bundled python> dotnet test AquaSynth.sln --no-restore --filter PublicDomainDx7PrcSynth1WritesListeningWavsWhenInstalled: passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added staged operator envelopes for operator graphs through
|
|
`env=rl rates=... levels=...`, backed by a `RateLevelEnvelope` model,
|
|
parser support, Faust `rl4_env(...)` rendering, and DX7 helper output
|
|
from four-rate/four-level operator EG data. Direct DX7 rate/level
|
|
lowering on `PRC SYNTH1` only reached ~0.316 in quick probes, so the DSL
|
|
surface exists but DX7 EG timing/gain calibration remains the next
|
|
pressure.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 53 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added `Dx7OperatorLevelApproximation`, which maps DX7 operator output
|
|
level plus key/velocity scaling into normal AquaSynth operator levels for
|
|
reference rebuild work. Retried `PRC SYNTH1`; static level mapping alone
|
|
did not produce parity, and envelope tweaks only reached ~0.42 score. The
|
|
next pressure is DX7-style operator envelope/gain evolution.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 50 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Probed the harder `analog1.syx` voice 17 (`PRC SYNTH1`) and found the
|
|
routed candidate failed badly instead of being thresholdable. The useful
|
|
cut was feedback: operator feedback now emits as Faust delayed recursion
|
|
instead of a direct cyclic self-reference, and a render test covers it.
|
|
Exact DX7 feedback scaling and EG behavior remain pressure.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 49 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added the first thresholded rendered DX7 parity rebuild for
|
|
`analog1.syx` voice 13, `MC-MM 5-3`. The candidate is a terse AquaSynth
|
|
sine-like behavioral match and the test compares dexed-py reference audio
|
|
against Faust-rendered AquaSynth audio using score, log-mel, envelope,
|
|
duration, RMS, zero-crossing, and centroid thresholds. It does not claim
|
|
exact DX7 operator execution.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 48 passed; focused dexed-py parity test passed with bundled Python"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added a public-domain DX7 SysEx fixture from Musical Artifacts artifact
|
|
152, provenance metadata, and a test-only dexed-py renderer. The render
|
|
test uses `AQUASYNTH_DX7_PYTHON` when set and otherwise stays optional.
|
|
Added a package-boundary test that packs `AquaSynth.Dsl` and asserts
|
|
fixtures, SysEx banks, and Python helpers do not ship in the NuGet package.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 47 passed; dexed-py render test passed with bundled Python"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added `FaustCompiler.RenderAsync`, which compiles AquaSynth Faust source to
|
|
Faust-generated C#, runs it in a temp .NET project, and returns mono float
|
|
samples. The first render test checks non-silent generated audio and feeds
|
|
the buffer through `AudioAnalyzer`; DX7 audio parity remains blocked on a
|
|
chosen reference renderer or captured fixture.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 44 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added `Dx7EnvelopeApproximation`, a labeled helper that lowers DX7
|
|
four-rate/four-level envelopes to AquaSynth ADSR plus gate duration.
|
|
Reference rebuilds now distinguish approximated envelope lowering from
|
|
still-missing exact DX7 EG execution.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 43 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added field-site parameter binding for readable operator graphs. Graph
|
|
gain/note fields, operator ratio/level/feedback/envelope fields, and route
|
|
index fields now bind through exact `/opgraphs/...` paths, and Faust
|
|
emission substitutes those bound expressions in operator graph output.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 42 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added a patch-level Playback contract and `instrument` authoring surface
|
|
for Faust-managed MIDI mono/polyphony. `instrument midi=true polyphony=8`
|
|
emits `[midi:on][nvoices:8]` and standard `freq`, `gain`, and `gate`
|
|
controls instead of AquaSynth-owned voice allocation.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 41 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Standardized the live envelope model as ADSR and added explicit Note
|
|
records for frequency, one-shot gate duration, and host/MIDI source.
|
|
SFXR sustain now maps to note gate duration; SFXR punch maps to lower
|
|
ADSR sustain level plus voice gain compensation as compatibility import
|
|
behavior. Generated Faust can emit one-shot ADSR envelopes or host
|
|
gate/frequency controls.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 40 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added readable operator graph authoring syntax with `operator`, `route`,
|
|
and `carrier` declarations, plus `env=ad:attack:decay` and
|
|
`env=adsr:attack:decay:sustain:release` forms. Converted the DX7
|
|
algorithm-8 rebuild away from compact number soup.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 36 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added first-class OperatorGraph support with operators, modulation edges,
|
|
carriers, operator feedback, parser syntax, and Faust emission mixed with
|
|
normal voices. Updated the DX7 algorithm-8 rebuild to use the operator
|
|
graph; remaining pressure is exact DX7 feedback-register timing and
|
|
rate/level envelopes.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 35 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added ReferenceRebuild catalog entries and two DX7-style AquaSynth DSL
|
|
rebuilds. Algorithm 32 maps cleanly to six additive voices; algorithm 8
|
|
exposes missing operator graph concepts including explicit modulation
|
|
edges, summed modulators, and operator-local self-feedback.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 34 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added DX7 algorithm topology metadata for algorithms 1-32 from the
|
|
reverse-engineered OPS algorithm ROM table. Topology exposes carrier
|
|
operators, modulation edges, feedback-register writers, self-feedback
|
|
operators, delayed-feedback targets, raw ROM steps, and ReferencePatch
|
|
feature pressure.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 31 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added DX7 SysEx records and parsing for 155-byte voice edit buffers,
|
|
128-byte packed voices, and 4104-byte packed 32-voice banks. Extracted
|
|
operators, envelopes, algorithm, feedback, oscillator sync, LFO,
|
|
transpose, voice name, checksum validation, and ReferencePatch features.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 28 passed"
|
|
- date: 2026-05-13
|
|
summary: >
|
|
Added PatchParameter and ReferencePatch contracts, `param` script parsing,
|
|
duplicate path validation, and Faust hslider emission for declared
|
|
controls. Parameter binding uses field-site references such as
|
|
`lpf=@/macro/brightness`; the emitter substitutes the parameter only at
|
|
the exact bound field site and warns for unbound parameters.
|
|
verification: "dotnet test AquaSynth.sln --no-restore: 23 passed"
|
|
|
|
cut_line:
|
|
- "Cut any importer that cannot state source provenance and license."
|
|
- "Cut weak tests that only prove parser leniency."
|
|
- "Cut voice-field sprawl when a target needs topology."
|
|
- "Cut any design that requires recompiling a patch to move an exposed musical parameter."
|
|
- "Split a lower-level graph DSL if Faust/Cardinal-style references make the voice DSL lie."
|
|
|