970 lines
107 KiB
YAML
970 lines
107 KiB
YAML
project: AquaSynth
|
|
spine_version: 1
|
|
updated: 2026-06-15T01:02:24+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: >
|
|
Rebuild vocal acoustics around a compact primitive machine before more
|
|
utterance golf: PT-shaped tract scripts adapt into continuous AreaFunction
|
|
morphology, WaveguidePath propagation, SourcePort excitation,
|
|
ConstrictionContact pressure/release, BranchPort coupling, RadiationLoad
|
|
boundary output, ProbeTimeline telemetry, and VocalNetwork ownership. Baby
|
|
words remain downstream witnesses after primitive flow is observable.
|
|
|
|
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
|
|
aquasynth_daemon_service: src/AquaSynth.Faust/AquaSynthDaemonService.cs
|
|
aquasynth_daemon_tool: tools/AquaSynthDaemon
|
|
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
|
|
primitive_vocal_timeline: src/AquaSynth.Core/ProbeTimelineReport.cs
|
|
primitive_timeline_fact_extractor: src/AquaSynth.Core/PrimitiveTimelineFactExtractor.cs
|
|
primitive_vocal_reference_report: src/AquaSynth.Core/PrimitiveReferenceReport.cs
|
|
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
|
|
acoustic_graph_dsp_audit: docs/acoustic-graph-dsp-audit.md
|
|
acoustic_graph_missing_pieces_audit: docs/acoustic-graph-missing-pieces-audit.md
|
|
acoustic_graph_proprioception: docs/acoustic-graph-proprioception.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.
|
|
- AquaSynthDaemonService owns compile/render/stream/live-session execution for patch.compile, instrument.sample, bounded instrument.stream automation, instrument.open, instrument.control, instrument.block, and instrument.close. It delegates DSP to AquaSynth.Faust, writes compile/session/render/stream/live/live-session-state/operator .cc witnesses under the configured .aquasynth store, writes .f32/.wav sample artifacts, keeps native streaming patch instances for live sessions, rewrites retained aquasynth.live_instrument_session.v1 state for open/closed status, current controls, next sequence, and last command/receipt ids, releases live sessions without deleting reusable compiled patch witnesses, and emits CultMesh-compatible audio/control stream descriptors plus per-block packet receipts. AquaSynthCultNetDaemon owns the local CultNet command-observation boundary: typed command documents enter the CultNet database, the daemon serializes execution through AquaSynthDaemonService, and typed receipt/provider documents come back out. JSON-lines modes are only operator/xeno edges; they must not become second audio/session authorities.
|
|
- AquaSynthDingsHost is the single per-user playback owner: one named shared-mode WASAPI session, one mixer, one Aqua daemon child, and the live Windows session master volume/mute authority. AquaSynthDingsMcp instances are typed named-pipe bridges only and contain no audio output or fallback mixer. Event IDs own the Minimal Dings motif; curated instrument IDs own agent timbre; AquaSynthDaemon remains the synthesis authority. The shared AquaSynth.Dings contract owns catalog and MessagePack command/receipt types. Research provenance and timing policy live in docs/research/auditory-notifications/README.md.
|
|
- Patch scripts lower into explicit graph records before Faust emission.
|
|
- Song-snippet parity is scene-audio pressure, not redistributed fixture data. The worker may derive local tempo/register/scale hints from private clips, but agents must express live rhythm and pitch motion through owned AquaSynth controls until native sequencing sugar has an explicit DSL/lowering owner.
|
|
- 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 primitive-vocal pressure, not permission to add more formant proxy knobs or revive the old waveguide lane. AquaSynth has a `tract` DSL command with PT-shaped runtime controls, but default vocal acoustics now lower through `VocalNetwork`; `Voice.Tract` is authoring sugar, not a second audio authority.
|
|
- 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 moved 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` exist. Existing `tract_shape`, `glottis`, `tract_injection`, `nasal_branch`, and `tract` commands populate acoustic records as authoring aliases; the legacy `Voice.Tract` resonator/waveguide renderers are removed.
|
|
- `acoustic` / `acoustic_voice` render an `AcousticPortNetwork` only through the compiled bidirectional Faust segment graph. Graph lowering splits paths at terminal positions, aggregates co-located terminals into graph nodes, orders connection ports deterministically, scatters same-path two-port area discontinuities, scatters arbitrary non-bypass connection groups through one passive N-port area law, 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 routes through `propagation=graph`; legacy propagation values now fail fast instead of producing proxy audio.
|
|
- Pink Trombone log-mel parity now writes graph candidates only. Generated tract graphs mirror live `/pink/...` tract bindings into acoustic source, terminal, radiation, and path-area fields. Graph generation stopped baking first-frame tongue/constriction/lip morphology into the path; `AcousticPath.AreaControl` now turns tongue/constriction/lip controls into live area expressions at graph sample points. Velum owns nasal branch entrance diameter, which lowers through a squared parameter-binding transform into side-port admittance; generated nasal connections keep full connection coupling, and the nasal terminal carries the side-port admittance limit. The first nasal tube sample is no longer allowed to decide the velum opening. Lip opening owns path area and radiation aperture, not terminal area scaling. Graph radiation now uses aperture as a boundary impedance owner: lip/beak opening blends boundary reflection from near-closed termination to declared open-end reflection, names per-port boundary flow (`incoming - outgoing`), and weights output by bounded local terminal admittance rather than a fixed 4x output scalar. Latest static graph evidence after radiation admittance normalization is under `artifacts/parity/pink-trombone-logmel/20260527T170548495`: open/front/nasal/ma/sibilant/closure cosine 0.6675/0.7216/0.7251/0.7098/0.4862/0.6513; latest utterance evidence under `artifacts/parity/pink-trombone-utterance-logmel/20260527T170618466`: mama/papa/thrombosis cosine 0.7428/0.7830/0.5442 with rmsRatio 2.7955/2.4594/2.7397 and articulation 0.1288/0.1226/0.1151. The output is less absurdly loud, but articulation and speech-band motion are still the live failure.
|
|
- `docs/acoustic-graph-flow-audit.md` compares Aqua's graph to Birkholz/VTL, Story/TubeTalker, Smith waveguides, ArtiSynth, and PT/SndKit. The graph records can name the research-backed architecture, but current Faust lowering still lacks fully shaped graph-native closure pressure storage. The kept physical fixes move nasal coupling from global connection damping into transformed side-port admittance and use one Kelly-Lochbaum/PT-style traveling-wave convention for ordinary two-port area discontinuities and three-port branch junctions. The previous pressure-continuity rewrite was wrong for the graph's wave variables and produced the phone-vibration failure. Radiation now has named flow/admittance probes and local terminal-admittance weighting, reducing over-radiation without restoring the old damper. The graph clock for generated tract graphs is continuous fractional delay so adding terminals does not silently lengthen the morphology. Node source/incident-pressure debug probes expose source-layer failures; a raw release-reservoir boost was tested and cut after the KL fix made it overdrive papa. Latest utterance artifact `artifacts/parity/pink-trombone-utterance-logmel/20260527T223931573` has papa at cosine 0.8828/RMS 1.0186 while thrombosis still fails from silence/articulation. Next cut is source impedance/constriction filtering for release energy, not global gain or PT-shaped modules.
|
|
- PT utterance metrics now include cross-utterance separability because log-mel parity alone hid the user's actual listening failure. Artifact `artifacts/parity/pink-trombone-utterance-logmel/20260527T225833392` shows `mama/papa` candidate collapse: reference log-mel similarity 0.3791 versus candidate 0.6069, with candidate envelope similarity 0.8885. Interior source terminals no longer decide topology or node area/reflection; they attach to existing graph nodes and inject energy, while non-source terminals own geometry. Keep this source/topology cut even if other broken layers get louder.
|
|
- Generated lip radiation terminals no longer bake first-frame lip opening into terminal `area_scale`; lip opening owns live path area plus radiation aperture. This removes a stale initial-state authority where words starting with closed lips kept closed-lip admittance. Static PT graph artifact `artifacts/parity/pink-trombone-logmel/20260527T231611586` passes, while utterance artifact `artifacts/parity/pink-trombone-utterance-logmel/20260527T231056242` still fails `mama/papa` collapse and silent `thrombosis`. Next work remains source/reservoir/radiation coupling, not restoring terminal-scale double gates.
|
|
- Graph voice repair pass on 2026-05-28 fixed four model-level ownership leaks: glottal excitation is source-normalized with local `tanh`; segment propagation loss is area-dependent so closures absorb instead of ringing forever; generated nasal side-port area maps velum diameter squared directly instead of through the old hidden 0.15 damper; generated tract lips use live path-end geometry as the aperture owner and no longer double-gate radiation opening/boundary flow. Utterance artifact `artifacts/parity/pink-trombone-utterance-logmel/20260528T070759312` passes smoke and no longer collapses `mama/papa` (`referenceLogMel=0.3791`, `candidateLogMel=0.3651`); `thrombosis` improves to cosine 0.4366 but remains weak/quiet. Static artifact `artifacts/parity/pink-trombone-logmel/20260528T071240442` passes with `closure-release` demoted to sealed-static evidence (`peak=0.000005`). Next pressure is true graph-native closure reservoir/release through the scattering path.
|
|
- `docs/acoustic-graph-dsp-audit.md` is the current Jenga audit for graph voice DSP. It says the path graph, typed terminals, KL/PT two-port scatter, source/topology separation, velum side-port area, generated lip geometry ownership, area-dependent segment loss, and utterance separability should stay. The first audit cut replaced the generic connection fallback pressure/admittance blend and PT-shaped three-port branch recognizer with one passive N-port area-scattering law for all non-bypass connection groups; emitted Faust no longer contains `graph_connection_pressure_*` for graph connections. The second audit cut moved graph radiation color/admittance into one named local primitive with emitted `graph_radiation_reference_area_*`, `graph_radiation_differentiation_*`, `graph_radiation_highpass_*`, `graph_radiation_admittance_*`, and `graph_radiation_flow_*` signals instead of inline `30/70` and `area + 1.0` expressions. The third audit cut hoisted graph turbulence/release into named per-source `_closure`, `_release`, `_reservoir`, `_reservoir_drive`, `_pressure_drive`, `_release_pressure`, `_noise_gate`, `_release_gate`, `_sustained`, `_burst_noise`, and `_release_pulse` locals. Reservoir charging now uses directed upstream-minus-downstream pressure for ordinary two-port path nodes and positive local incident pressure as fallback; latest artifacts `artifacts/parity/pink-trombone-utterance-logmel/20260528T115452268` and `artifacts/parity/pink-trombone-logmel/20260528T115719882` still show no metric movement. This points away from source-local reservoir charging and toward missing contact-aware closure state that participates in scattering/flow. Remaining suspect owners are unowned segment loss constant, still-empirical radiation/source constants, nearest-node source attachment, and missing contact-aware closure state.
|
|
- Graph source lowering now names per-node incident pressure and node-local source sums inside the recursive graph loop. Generated tract injection source banks now use cell-centered positions and `1 / sections` index scaling, so turbulence/release energy is born inside tube cells rather than directly on graph/radiation nodes. Latest source-position artifact under `artifacts/parity/pink-trombone-utterance-logmel/20260527T172949293`: mama/papa/thrombosis cosine 0.6654/0.7746/0.5522, rmsRatio 3.0010/2.5712/2.4943, articulation 0.1444/0.1177/0.1193. Static closure-release RMS improved to 1.0078 under `artifacts/parity/pink-trombone-logmel/20260527T172843945`, but papa articulation worsened; keep the cell-centered source placement because it is the correct graph-level source geometry, not because metrics liked it.
|
|
- Source ports now have an explicit `impedance`/`load` control and graph lowering uses node incident pressure to make glottal, labial/syrinx, reed, click, synthetic, and turbulence sources load-aware. Generated tract area terminals are `Junction` geometry owners again; generated `voices_0_contact_*` terminals are a sparse contact overlay capped at four interior sections, with named graph-owned `graph_contact_*_closure`, `_reservoir`, and `_release` signals so closure pressure storage is no longer either every area sample or only a turbulence-source trick. Eight generated contacts plus inline occlusion overflowed the native debug Faust compile; four sparse contacts pass the opt-in thrombosis graph probe. `patches/advanced/bird-syrinx.aqua` is the first checked-in differentiable syrinx patch: paired labial source ports, bronchial paths, a tracheal path, an area-scattering merge, and beak radiation, all through `AcousticPortNetwork`.
|
|
- Historical graph compaction pressure: before the primitive cut, generated PT-style `tract` lowering capped oral area terminals at 10, moving injection source ports at 8, and contacts at 4 to keep Faust alive. That path is no longer the default vocal owner; keep the lesson, not the generator.
|
|
- Moving tract injection placement now uses a raised-cosine kernel over the compact source bank instead of a hard triangular source-position weight. Keep this direction: smoother continuous heuristics over fewer generated ports, not more discrete source terminals. Artifact `artifacts/parity/pink-trombone-utterance-logmel/20260529T140038717` still fails articulation but improves thrombosis active ratio/silence/speech-band slightly without increasing graph size.
|
|
- Generated lip radiation opening must mirror live tract lip opening. The path-end geometry and radiation aperture are one mouth owner, not separate truths. Artifact `artifacts/parity/pink-trombone-utterance-logmel/20260529T141822464` improves papa's plosive failure sharply (RMS 0.8369, motor-band ratio 0.0555), but mama still sounds vowel-poor and thrombosis is still mostly absent; next pressure is vowel body/radiation color and fricative continuity.
|
|
- Proprioception correction says baby words are downstream witnesses, not the rebuild owner. The live cut is to collapse generated graph-vocal lowering into a small set of instrumented physical primitives, compare primitive/sample-flow behavior against VTL, ArtiSynth, Story/TubeTalker, Smith/Faust, and PT/SndKit, then return to utterances once the tract body is observable. `docs/acoustic-graph-proprioception.md` owns this cut line.
|
|
- First primitive vocal teardown cut is live. `tract`, `glottis`, `tract_injection`, and `nasal_branch` now adapt PT fixtures into `AreaFunction`, `WaveguidePath`, `SourcePort`, `ConstrictionContact`, `BranchPort`, `RadiationLoad`, `ProbeTimeline`, and `VocalNetwork` records instead of emitting generated `voices_0_area_*`, `voices_0_contact_*`, or `voices_0_inj_*` acoustic banks. The obsolete `EnsureTractAcousticNetwork` generator is deleted. Faust lowering for `Voice.VocalNetwork` emits compact primitive path/source/contact/branch/radiation locals using `de.fdelay*` delay families and debug probes under `/debug/...`; `ProbeTimelineReport` writes deterministic primitive CSV samples. Next pressure is passivity/energy timeline samples plus PT/SndKit timeline comparison, not intelligibility tuning.
|
|
- Primitive path telemetry now reports `incoming_wave`, `outgoing_wave`, `energy_in`, `energy_out`, and `passivity_ratio` in both Faust debug probes and `ProbeTimelineReport`; contact telemetry includes resistance. `PrimitiveReferenceReport.ComparePinkTrombone` compares static primitive area sections, length, reflection count, delay estimate, branch admittance, contact state, and radiation fields against local PT/SndKit fixture controls without adding a native reference dependency. Next pressure is per-block comparison against PT/SndKit internals, not static control matching alone.
|
|
- `PinkTromboneReferenceRenderer.RenderTimeline` now exposes PT internal oral/nasal path, branch, contact, and radiation samples from the renderer's own diameter/wave/reflection/transient arrays. `PrimitiveReferenceReport.ComparePinkTromboneTimeline` role-normalizes Aqua primitive samples against PT timeline samples for path/branch/contact/radiation signals. This is the first local reference-internal comparison surface for the primitive rebuild; next pressure is fixture-suite artifact reporting and then tightening laws where the timeline drift points.
|
|
- `PinkTrombonePrimitiveTimelineComparisonWritesArtifacts` writes per-fixture Aqua primitive timelines, PT internal timelines, comparison CSVs, and a summary under `artifacts/parity/primitive-vocal-timeline/<timestamp>`. This makes primitive drift inspectable across the PT fixture suite without native Faust or external VTL/ArtiSynth dependencies. Use these artifacts to choose the next physical-law correction.
|
|
- First comparison-driven primitive law correction: `SourcePort` owns `FlowScale` (default `.02`) so pressure/tension/opening no longer emit hidden unit-scale waves; `RadiationLoad.Reflection` owns reflection directly and aperture no longer rewrites that coefficient; `ProbeTimelineReport` radiation flow now uses path outgoing wave like Faust instead of reporting `aperture / impedance`. Artifact `artifacts/parity/primitive-vocal-timeline/20260529T155613895` drops fixture-suite mean absolute timeline error from roughly `1.2-1.3` to `0.15-0.27`. Remaining large drift is branch/contact dynamics, which needs an owner decision about gesture slew versus primitive-local smoothing.
|
|
- Gesture motion ownership is now separate from acoustic primitives. `ControlSurface` exposes normalized runtime controls for primitive fields, and `ControlSpline` owns future-time linear/hold/Bezier gesture motion over those surfaces. Faust lowering emits surface and spline point controls, maps effective normalized values back to physical primitive fields, and keeps old `@/param` bindings as compatibility base controls. `tract_motion` adapts velopharynx opening into a branch spline. A generated contact-opening spline was tested and cut because PT timeline evidence showed it invented an open-then-close transient; contact closure must come from articulator/area ownership. Focused verification: `PatchScriptTests` pass 90/90 and primitive timeline artifact `artifacts/parity/primitive-vocal-timeline/20260529T185955965` keeps `closure-release` at mean absolute error `0.155925`.
|
|
- Public gesture authoring API is now explicit. `ControlSurfaceCatalog.FromPatch(patch)` exposes normalized surface metadata for hosts; `ControlSplineTimeline` lets clients edit future points and emit `ControlValuesAt(t)` as ordinary surface-control dictionaries. Native Faust compiled patches carry `ControlSurfaces` and expose `ControlValuesAt(timeline,t)` to filter semantic timeline values to controls exported by the optimized DSP. This is the runtime path for user-authored gestures without recompilation. Verification: `PatchScriptTests` pass 91/91 and `NativeFaustRuntimeTests` pass 5/5.
|
|
- First IPA/anatomy sugar is live. `phoneme_gesture` accepts known IPA symbols or explicit descriptors such as `descriptor=voiceless_labial-velar_fricative`, maps place/manner/voicing onto primary anatomical surfaces, and emits ordinary `ControlSpline`s. It is deterministic seed material for local reference-data golf, not exact articulatory truth. Patches may still use normal FM/AM/modulators/envelopes/filters around the anatomical control stream. Verification: `PatchScriptTests` pass 92/92.
|
|
- IPA training scoring contract is documented. Reports must keep `gesture_score`, `clean_vocal_score`, and `full_parity_score` separate. Gesture score measures descriptor-to-surface coverage, motion direction, spline contour/timing, primitive timeline consequences, and optional external articulation landmarks. Full parity patches may use FM/AM/modulators/envelopes/filters, auxiliary animated voices, and recording-condition helpers, but those helpers cannot count as articulation evidence unless gesture and clean-vocal scores move coherently.
|
|
- `IpaGestureExperiment.WriteRound` is the first frozen batch harness for IPA hypothesis work. It writes `manifest.yaml`, candidate `.aqua` scripts, primitive `ProbeTimelineReport` CSVs, gesture-layer `metrics.csv`, and per-candidate `evidence.jsonl` under a caller-provided artifact root. `IpaGestureExperiment.AnalyzeRound` writes `analysis/metric-summary.csv`, `analysis/candidate-clusters.csv`, and `analysis/science-brief.md` for the science-worker handoff. This harness owns frozen descriptor/spline/primitive evidence only; clean vocal identity, full spectrogram parity, optimizer checkpoints, and worker orchestration stay downstream. Focused verification: `PatchScriptTests` pass 93/93.
|
|
- `IpaTrialOrchestrator.RunAsync` is the first local render/scoring worker for IPA trials. It generates candidate patches through `IpaGestureExperiment`, renders them through Faust, compares against local PT fixture references with `AudioAnalyzer`, writes WAV/report artifacts, and stores typed `IpaTrialResult` records in `ipa-trial-results.cc`. The five-seed trial run at `tests/AquaSynth.Dsl.Tests/bin/Debug/net10.0/artifacts/parity/ipa-trials/20260529T214127955/five-seed-trials` showed voiced vowels/nasals became audible only after primitive `SourcePort` lowering gained a true oscillatory voiced carrier; sibilants are pressure, plosives remain weak. Verification: opt-in IPA trial test passed, and focused `PatchScriptTests|IpaTrialResultsRoundTripThroughCultCache` pass 94/94.
|
|
- External IPA exploration now has a worker/tool boundary. `tools/IpaTrialWorker` owns `seed`, `score`, `search`, `show`, and audit-only `dump` commands over the typed `.cc` trial-result store; `score` renders external Codex-authored `.aqua` candidates through `IpaTrialOrchestrator.RunCandidateScriptsAsync`, while `search` is the semantic retrieval organ for hypothesis agents. `IpaTrialResult` records now embed extracted primitive timeline facts from `ProbeTimelineReport` for contact closure/reservoir/release, source load/flow, branch admittance/exchanged flow, radiation boundary/output, path area/delay/energy, and passivity; `search`, `show`, `dump`, and summary CSV output surface release/radiation/passivity witnesses directly from the `.cc` record. `search` follows VoidBot's Qdrant shape: `.cc` records plus timeline facts and referenced local artifacts become evidence chunks, local Ollama `qwen3-embedding:0.6b` produces 1024-dim vectors, Qdrant collection `aquasynth_ipa_trial_results` stores stable SHA-256 UUID points with trial/candidate payload metadata, and the report surfaces vector scores, excerpts, tags, metric facts, timeline facts, contrast candidates, `class_focus`, per-hit `class_match`, and `show` commands. Qdrant is a derived index; CultCache remains truth, and lexical/metric search is fallback when the vector stack is unavailable. Retrieval tuning added phonetic class-affinity scoring and candidate-specific mixed-lane ownership so `mix-p` can support stop seams without every mixed candidate matching stop evidence. `tools/run-ipa-trial-loop.ps1` orchestrates external `codex exec` hypothesis/evaluator workers around that store. Source-edit-enabled rounds now allow agents to golf DSL syntax, parser/model records, Faust lowering, worker evidence surfaces, and tests when evidence points at a repeated owner failure; agents must write `source-change-plan.md`, and the loop runs a focused build before scoring. `hypotheses.md` is the hypothesis worker report of record; `hypothesis-agent.md` is only the external agent's final chat summary. The first loose source-edit round produced no source edits and no aggregate metric win, then exposed a deeper learning-loop fault: family ideas were rotated across unrelated targets instead of aligned to phonetic owners. Production prompts now pass the previous evaluation path into the hypothesizer, require `Previous Round Learning`, require `Target-Class Lane Plan`, forbid round-robin family assignment, and let the evaluator fail class alignment when family/target assignments do not match phonetic owner classes or explicit transfer-test mutations. Candidate reports must include a `Scene Voice Model` naming primary-articulatory, tract-noise, release/transient, background-room, and recording-condition voices, with general AquaSynth synth primitives allowed for helper scene voices but not accepted as articulation evidence unless lower-layer witnesses move. At least one scene/noise or recording-condition family in a source-golf round must implement real auxiliary `.aqua` `voice` declarations instead of satisfying scene modeling with prose. The active trial shape is five target sets of five phoneme lanes each: vowels, nasals/approximants, fricatives, stops, and mixed generalization. Candidate names are exactly `<targetId>__<family>__<hypothesis-name>.aqua`, with lowercase kebab-case family ids. Three dry external Codex smoke passes refined hypothesizer/evaluator prompts into exact 25-lane output, retrieval receipts, claim audits, evidence-quality ledgers/verdicts, and fail-closed evaluator compliance. A later five-pass prompt optimization showed the best science comes from fixed receipt packets plus constrained reasoning; production prompts now require contrast pairs, `show` metric values, primitive timeline facts/excerpts or explicit `missing`, class-consistent reference matrices, scene voice models, `X owns Y so Z remains true` owner sentences, at least five micro-sweep perturbations before a seam is actionable, and a novelty gate rejecting loudness/dressing-only families as loss-landscape novelty. Verification: focused builds/tests pass, old-store show compatibility passes, and a fresh one-candidate smoke under `artifacts/parity/ipa-timeline-fact-smoke/20260531T233217641` proves release/radiation/passivity facts persist and retrieve through Qdrant/Ollama.
|
|
- Song-snippet parity now treats target analysis as CultMesh database evidence. `song-prepare` writes each 30-second clip's log-mel spectrogram CSV, per-band first/second derivative stats, RMS envelope, envelope autocorrelation, and analysis report. `song-score` upserts those as typed `SongChallengeEvidenceDocument` records in the same `.cc` store as `IpaTrialResult`, adds target metrics and `cultmesh://aquasynth/song-challenge-evidence/...` artifacts to every result, and `search/index` derive Qdrant chunks from the database records. `pattern` and `scale` DSL sugar are live authoring conveniences that lower into normal parameters and hold-loop curves; prompt agents may propose richer Strudel-like syntax, but candidate patches must use implemented syntax.
|
|
- Song-scene scoring now records instrument-role ownership so the music-generator curriculum does not learn that simple oscillator blips are good instruments by default. `song-score` emits `instrument_voice_syrinx`, `instrument_drum_subtractive`, `instrument_pad_additive`, `musical_instrument_score`, and `chip_distress_risk`; verdict/distillation ranking rewards owned roles and demotes chip-distress-risk candidates unless preserved as contrast. Swarm prompts now require voice-like leads to prefer syrinx/acoustic sources with pressure/opening/radiation motion, percussion to prefer subtractive pitched bodies plus filtered noise skins, and pads/beds to prefer additive/PAD `layer`/`harmonics`/`spectrum` banks.
|
|
- Song-scene harness supports full-song curriculum and in-agent revision. `song-prepare --duration-seconds 0` freezes the whole decoded song from sample zero, and `run-song-snippet-trial-swarm.ps1 -FullSongs` samples recursively from the Reinier parent folder including `.m4a/.mp4`. Target and candidate analysis now include whitened spectral autocorrelation over band-whitened log-mel flux. Candidate-side Faust-render artifacts include log-mel spectrogram/stats, RMS envelope/autocorr, whitened spectral autocorr, and an analysis markdown report. Swarm prompts require five local score/revise attempts per target before publishing the final `.aqua`.
|
|
- Patterned AquaSynth percussion now needs explicit voice-local retrigger ownership. Sequenced gain (`gain=@/seq/kick`) only changes level; without `trigger=<step_seconds>`, a one-shot drum envelope, pitch fall, FM decay, filter ramp, or phaser motion keeps aging from song start and later hits become dead-gate mush. Music agents should start 808 percussion from `patches/808/kick.aqua`, `snare.aqua`, `hat.aqua`, and `clap.aqua`, split body/click/skin/clap/hat layers explicitly, add `trigger`, and use drive/fold/sample-hold texture instead of broadband noise pretending to be a kit.
|
|
- TurbulenceJet now includes a release-timed burst-noise component in addition to the deterministic pressure pulse, but a stronger trial barely moved papa; the source is not the main remaining articulation bottleneck. Graph radiation now mixes 30% raw boundary flow with 70% high-passed flow after local admittance weighting, down from the over-bright 15/85 blend. Latest radiation/source artifact under `artifacts/parity/pink-trombone-utterance-logmel/20260527T174236049`: mama/papa/thrombosis cosine 0.6578/0.7692/0.5585, rmsRatio 3.0006/2.6153/2.3488, articulation 0.1437/0.1173/0.1191. Static `closure-release` under `artifacts/parity/pink-trombone-logmel/20260527T174139661` has rmsRatio 0.9900 and speechBandRatio 0.0842. This is still not speaking; next pressure is true tract resonance/passive scattering and pressure storage, not more burst gain.
|
|
- Same-path two-port area discontinuities now emit `graph_area_energy_in_*` and `graph_area_energy_out_*` probes alongside the three-port branch `graph_connection_energy_*` probes. Use these to inspect passivity and formant-body failures at the scatter sites rather than judging only final output loudness.
|
|
- `FaustExportOptions.DebugProbeUi` wraps graph probe signals in Faust `vbargraph` UI controls under `/debug/...` without changing audio output arity. Native streaming Faust patches now separate writable controls from read-only probe zones and can read/snapshot probe values after `ProcessBlock`; use this for acoustic graph passivity/radiation inspection, leave it off for normal parity renders.
|
|
- `PinkTromboneGraphDebugProbesWritePassivityReportWhenNativeFaustIsInstalled` streams the `nasal-vowel` graph with debug probes and writes `artifacts/parity/pink-trombone-graph-probes/<timestamp>/passivity-report.txt`. Latest run `20260527T200828013` shows same-path area and nasal-branch energy out/in ratios at 1.0, so current gross failure is not basic scatter energy explosion; next cuts should inspect frequency-dependent loss/radiation color and closure pressure storage.
|
|
- 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; `AcousticAreaControl` owns live sampled morphology controls on a path; `WaveClockPolicy` owns the legal delay floor instead of forcing every segment to one sample; generated graph tracts now use `HalfSampleGrid` to match the PT/Kelly-Lochbaum half-sample regime; ordinary same-path graph interiors now own signed two-port area-discontinuity scattering; `glottis` owns excitation controls with mild harmonic waveshaping and a small higher-harmonic brightness term for graph sources; `tract_injection` owns positioned frication/burst controls; `AcousticSourcePort.Transient` owns graph-native release/click energy as a pressure pulse rather than filtered noise; sustained `TurbulenceJet` lowering owns a narrow-open aperture gate so closed constrictions no longer hiss; `AcousticSourcePositionControl` owns differentiable runtime weights over fixed source terminals so moving articulators can move source energy without recompiling the graph; `AcousticRadiationPort` owns aperture-dependent boundary reflection, flow radiation, and current post-flow normalization; `nasal_branch` owns a second diameter/area tube and branch aperture while `AcousticConnection.Coupling` owns structural max admittance; `tract_motion` owns control slew and obstruction threshold; `AcousticPortNetwork` owns graph lowering. `PinkTromboneReferenceRenderer` ports the pinned MIT `chdh/pink-trombone-mod` DSP source (`external/pink-trombone-mod` at 359c2d3b42b10280404c1650dc601902112b4c90), and reference WAVs before `artifacts/parity/pink-trombone-utterances/20260526T211902375` are invalid. The accepted PT utterance curriculum is mama, papa, and thrombosis; lulek was cut because its control sketch taught a bad artifact. Latest graph-only utterance smoke under `artifacts/parity/pink-trombone-utterance-logmel/20260527T150836912`: mama/papa/thrombosis remain `not-accepted-articulation` with cosine 0.8337/0.8893/0.5317 and articulation scores 0.2118/0.1890/0.2594. `AudioComparison.Articulation` reports envelope cosine, active-frame ratio, silence mismatch, envelope/spectral flux ratios, motor-band ratio, speech-band ratio, and an articulation score so log-mel cannot forge a listening receipt. A direct LF coefficient source was tested and cut because it overdrove the graph and broke static open vowel; a broader harmonic-tail source was tested and cut because it worsened voiced-band behavior. A naive midpoint admittance scatter was tested and cut because it collapsed `mama`; the kept area-discontinuity scatter needed the opposite reflection sign for this graph state convention, and re-testing the literal SndKit sign after the clock fix made `thrombosis` loud/unstable. A long noisy release transient was tested and cut because it turned papa into motor-band energy; deterministic pressure release with PT-scale decay is structurally kept but still not sufficient. Next pressure is true graph pressure storage/release at severe closures; output coloring alone is not allowed to impersonate articulation.
|
|
- 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."
|
|
- "Cut any new graph-vocal feature that lands before primitive-collapse and flow-probe instrumentation make the tract body's sample/flow behavior observable."
|