Normalize graph turbulence aperture

This commit is contained in:
Meta Vens 2026-05-27 12:09:36 +01:00
commit 0a431bda65
5 changed files with 27 additions and 13 deletions

View file

@ -214,7 +214,7 @@ question is whether graph-authored PT compatibility can beat the current weak
The parity report now renders the graph lane only. The latest static fixture
evidence is useful instead of decorative: open/front/nasal/ma/sibilant/closure
cosine is 0.6252/0.6576/0.6893/0.6550/0.4166/0.5554. The useful levers so far
cosine is 0.6252/0.6576/0.6893/0.6550/0.4389/0.5993. The useful levers so far
are source semantics, radiation impedance, terminal-specific admittance,
frication injection, cutting stale first-frame morphology from generated graph
paths, and live path-area control at graph sample points.
@ -246,6 +246,14 @@ keeping turbulence as the noise amount. This only nudges the current sibilant
fixture (0.2302 cosine), but the primitive semantics are cleaner: turbulence
owns continuous noisy pressure, burst owns transient pressure.
The graph source law now separates sustained aperture noise from closure
release. `AcousticSourcePort.Transient` owns release energy, while sustained
`TurbulenceJet` noise is gated by the intersection of the old upper constriction
cap and a narrow-open aperture window. Closed constrictions no longer hiss just
because they are closed. Latest accepted utterance graph smoke is `mama` 0.3339,
`papa` 0.8320, and `thrombosis` 0.3957 under
`artifacts/parity/pink-trombone-utterance-logmel/20260527T110608640`.
## Cut Line
The current `Voice.Tract` scalar proxy may survive only as an adapter over real

View file

@ -80,6 +80,9 @@ Current AquaSynth can express:
and lip gestures into live diameter/area expressions at graph sample points;
- source-port `transient` control for graph-native release bursts on turbulent
or click-like sources;
- aperture-normalized turbulent source lowering, where sustained jet noise is
allowed only through a narrow-open constriction and closure release remains
owned by the transient path;
- graph lowering that splits paths at terminals, injects typed sources, scatters
connection groups, and radiates from typed terminal ports;
- oscillator/noise sources;
@ -158,11 +161,11 @@ Trombone anatomy:
`artifacts/parity/pink-trombone-logmel/`, and reports only the graph lane.
- Latest static graph fixture evidence after cutting the old parity lane:
open vowel cosine 0.6252, front vowel 0.6576, nasal 0.6893,
bilabial-nasal-ma 0.6550, sibilant 0.4166, closure-release 0.5554.
bilabial-nasal-ma 0.6550, sibilant 0.4389, closure-release 0.5993.
- Latest graph utterance smoke evidence:
`mama` cosine 0.3354 / RMS 1.0698, `papa` 0.8162 / 0.1815,
`thrombosis` 0.3584 / 1.9499 under
`artifacts/parity/pink-trombone-utterance-logmel/20260526T232106458`.
`mama` cosine 0.3339 / RMS 1.0698, `papa` 0.8320 / 0.1806,
`thrombosis` 0.3957 / 1.6144 under
`artifacts/parity/pink-trombone-utterance-logmel/20260527T110608640`.
This is still not final speech parity; it is the first honest graph-only
moving-utterance rung.
- `tools/vocal-tract-playground` exposes the same control surface for fast
@ -180,10 +183,12 @@ sound like an actual mouth.
Do not add another formant workaround. The next coherent implementation is one
of these:
1. Give plosive/closure release a graph-native transient owner instead of
smearing burst pressure through the turbulence port.
2. Improve graph source/radiation level normalization so `papa` is not
under-driven while `thrombosis` is hot.
1. Improve graph source/radiation impedance normalization so source injection
and radiation read/write pressure through path admittance rather than raw
per-node gain.
2. Improve plosive timing and source position distribution for moving
constrictions; a single compile-time source terminal is still too crude for
gestures that move along the tract.
3. Use the log-mel artifact loop to golf `mama`, `papa`, and `thrombosis`
against the source-ported PT renderer without reintroducing a parallel
PT-shaped backend.

View file

@ -818,7 +818,7 @@ public static class FaustEmitter
AcousticSourceKind.Reed =>
$"(ma.tanh(sin(2.0 * ma.PI * {phase}) * (1.0 + {pressure} * 8.0)) * {opening} + no.noise * {noise} * 0.2) * {balance}",
AcousticSourceKind.TurbulenceJet =>
$"((no.noise : fi.highpass(2, 900.0 + 2600.0 * clip01(1.0 - {opening}))) * {noise} * {pressure} * clip01((0.8 - {opening}) / 0.8) + (no.noise : fi.highpass(1, 450.0)) * {transient} * {pressure} * {release} * (0.8 + 0.8 * clip01({opening} / 0.8))) * {balance}",
$"((no.noise : fi.highpass(2, 900.0 + 2600.0 * clip01(1.0 - {opening}))) * {noise} * {pressure} * min(clip01((0.8 - {opening}) / 0.8), clip01(8.0 * (0.7 - {opening})) * clip01(30.0 * ({opening} - 0.3))) * 0.62 + (no.noise : fi.highpass(1, 450.0)) * {transient} * {pressure} * {release} * (0.8 + 0.8 * clip01({opening} / 0.8))) * {balance}",
AcousticSourceKind.Click =>
$"no.noise * {pressure} * max({opening}, {transient}) * exp(0.0 - age * 120.0) * {balance}",
AcousticSourceKind.Synthetic =>

View file

@ -168,3 +168,4 @@
{"evidence":"After adding ordinary internal-node scatter, focused graph parity tests passed. Latest static graph artifact artifacts/parity/pink-trombone-logmel/20260526T225955955 reports open/front/nasal/ma/sibilant/closure cosine 0.6015/0.6358/0.6851/0.5988/0.3836/0.4606. Latest graph utterance artifact artifacts/parity/pink-trombone-utterance-logmel/20260526T230028874 reports mama cosine 0.3365 RMS 1.2421; papa 0.8264 RMS 0.3149; thrombosis 0.3874 RMS 2.0519.","claim":"Internal source/injection terminals in the acoustic graph must transmit pressure between adjacent path segments unless an explicit connection or boundary law says otherwise. Treating an unconnected internal terminal as independent reflective boundaries split the tract and made moving utterances fail. Ordinary multi-port graph nodes now scatter incident pressure across ports, which moved mama from negative cosine to a usable graph-only smoke rung.","timestamp":"2026-05-26T23:02:00+00:00","topic":"acoustic-graph-internal-node-scatter"}
{"evidence":"Added `AcousticAreaControl` to acoustic paths, generated neutral oral area terminals for `tract propagation=graph`, and mirrored tract tongue/constriction/lip parameters into path-area fields. Focused graph parity tests passed. Latest static artifact artifacts/parity/pink-trombone-logmel/20260526T232021742 reports open/front/nasal/ma/sibilant/closure cosine 0.6252/0.6576/0.6893/0.6550/0.4166/0.5554. Latest utterance artifact artifacts/parity/pink-trombone-utterance-logmel/20260526T232106458 reports mama cosine 0.3354 RMS 1.0698; papa 0.8162 RMS 0.1815; thrombosis 0.3584 RMS 1.9499.","claim":"The typed acoustic graph now has live sampled morphology. Path rest shape remains the continuous owner, while `AcousticAreaControl` evaluates tongue, constriction, and lip gestures at graph sample terminals so scattering changes over time. This is the missing PT-class moving-tube primitive without preserving a PT-shaped waveguide backend.","timestamp":"2026-05-26T23:20:00+00:00","topic":"acoustic-path-live-area-control"}
{"evidence":"Added `AcousticSourcePort.Transient`, parser support for `transient`/`burst` on source ports, graph lowering for turbulence release bursts, and tract injection mirroring from `tract/injection/burst` to generated source transient. Focused graph utterance and structural tests passed. Boosting the release multiplier worsened papa/thrombosis, so the transient remains a semantic source hook rather than a metric-forced gain hack.","claim":"Closure-release energy belongs to a typed source port, not a PT-specific backend or a hidden utterance compensator. The current transient hook is architecturally correct but not yet the main parity lever; next pressure is timing/normalization rather than brute-force burst gain.","timestamp":"2026-05-27T10:36:00+01:00","topic":"acoustic-source-transient-control"}
{"evidence":"Changed graph `TurbulenceJet` sustained noise from a pure closedness gate to a normalized narrow-open aperture gate intersected with the previous upper constriction cap, leaving `AcousticSourcePort.Transient` as the closure-release owner. Focused graph utterance test passed with artifact artifacts/parity/pink-trombone-utterance-logmel/20260527T110608640: mama cosine 0.3339 RMS 1.0698, papa 0.8320 RMS 0.1806, thrombosis 0.3957 RMS 1.6144. Static graph test passed with artifacts/parity/pink-trombone-logmel/20260527T110649452: open/front/nasal/ma/sibilant/closure cosine 0.6252/0.6576/0.6893/0.6550/0.4389/0.5993.","claim":"Sustained frication is an aperture-window source law, not a reward for complete closure. Closed constrictions should not hiss; release energy belongs to the transient path. This improved papa, thrombosis, sibilant, and closure-release without disturbing vowel fixtures.","timestamp":"2026-05-27T11:08:00+01:00","topic":"acoustic-turbulence-aperture-normalization"}

View file

@ -1,6 +1,6 @@
project: AquaSynth
spine_version: 1
updated: 2026-05-26T21:50:00+00:00
updated: 2026-05-27T11:08:00+01:00
prime_directive: >
Build coherent synth machinery. References exist to reveal missing structure,
@ -119,8 +119,8 @@ live_invariants:
- The physical voice research packet now includes a practical implementation/researcher map (`research/physical-voice-modeling/PEOPLE.md`) and talk/transcript ledger (`research/physical-voice-modeling/talks/TALKS.md`). Birkholz/VocalTractLab pressures multi-level articulatory control and gestures; Story/TubeTalker pressures continuous parametric area functions and length/coupling; Smith pressures bidirectional delay-line scattering and fractional-delay waveguides; Fels/ArtiSynth pressures separation between biomechanics, acoustics, timeline controls, and diagnostics. These are reusable DSL semantics, not modules to clone.
- Physical voice implementation has started moving PT pressure into neutral acoustic owners: `AcousticPath`, `AcousticTerminal`, `AcousticConnection`, `AcousticSourcePort`, `AcousticBranch`, `AcousticRadiationPort`, `WaveClockPolicy`, and `AcousticPortNetwork`. Parser commands `path`, `terminal`, `connect`, `source_port`, `branch`, `radiation_port`, `wave_clock`, and `acoustic_network` now exist. Existing `tract_shape`, `glottis`, `tract_injection`, `nasal_branch`, and `tract` commands populate acoustic records as compatibility aliases while the current `Voice.Tract` Faust renderer still owns audio.
- `acoustic` / `acoustic_voice` can now render an `AcousticPortNetwork` through a compact Faust response proxy or, when typed terminals are present, a compiled bidirectional Faust segment graph. Graph lowering splits paths at terminal positions, aggregates co-located terminals into graph nodes, orders connection ports deterministically, scatters area-weighted/pressure/bypass connection groups, injects source terminals even at connected nodes, and sums radiation terminals. Segment delay follows physical segment length and the network `wave_clock` strategy through unit-grid, half-sample, linear fractional, Lagrange, or Thiran/allpass Faust delay primitives. Source, branch, radiation, terminal, and connection controls can bind through ordinary Aqua parameters into emitted Faust. PT-shaped `tract` authoring now routes accepted parity through `propagation=graph`; the old waveguide parity lane is not a comparison baseline or historical pressure lane.
- Pink Trombone log-mel parity now writes graph candidates only. Generated tract graphs mirror live `/pink/...` tract bindings into acoustic source, terminal, connection, 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 coupling/aperture, and the first nasal tube sample is no longer allowed to decide the velum opening. Graph radiation now blends raw pressure with high-passed pressure instead of throwing away body energy. Latest static graph evidence: open/front/nasal/ma/sibilant/closure cosine 0.6252/0.6576/0.6893/0.6550/0.4166/0.5554.
- 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; `glottis` owns excitation controls; `tract_injection` owns positioned frication/burst controls; `AcousticSourcePort.Transient` owns graph-native release/click energy; `nasal_branch` owns a second diameter/area tube and branch aperture; `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/20260526T232106458`: mama cosine 0.3354 / RMS 1.0698, papa 0.8162 / 0.1815, thrombosis 0.3584 / 1.9499. The internal-node scatter fix made unconnected injection/source terminals transmit pressure between adjacent segments instead of acting as dead boundaries. Next pressure is source/radiation level normalization and better plosive timing, not reviving the old PT-shaped waveguide path.
- Pink Trombone log-mel parity now writes graph candidates only. Generated tract graphs mirror live `/pink/...` tract bindings into acoustic source, terminal, connection, 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 coupling/aperture, and the first nasal tube sample is no longer allowed to decide the velum opening. Graph radiation now blends raw pressure with high-passed pressure instead of throwing away body energy. Latest static graph evidence: open/front/nasal/ma/sibilant/closure cosine 0.6252/0.6576/0.6893/0.6550/0.4389/0.5993.
- 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; `glottis` owns excitation controls; `tract_injection` owns positioned frication/burst controls; `AcousticSourcePort.Transient` owns graph-native release/click energy; sustained `TurbulenceJet` lowering owns a narrow-open aperture gate so closed constrictions no longer hiss; `nasal_branch` owns a second diameter/area tube and branch aperture; `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/20260527T110608640`: mama cosine 0.3339 / RMS 1.0698, papa 0.8320 / 0.1806, thrombosis 0.3957 / 1.6144. The internal-node scatter fix made unconnected injection/source terminals transmit pressure between adjacent segments instead of acting as dead boundaries. Next pressure is source/radiation impedance normalization and moving source distribution, not reviving the old PT-shaped waveguide path.
- 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.