Calibrate shared G1 model laws and track per-module parity #9

Merged
peterswimm merged 16 commits from baseline-calibration into main 2026-10-21 20:36:06 +00:00
Owner

Scope

Calibrate the shared model laws the v23 sweep exposed, give the remaining silent fixtures real stimuli, and start tracking per-module parity.

  • Parity tracking. nardwahl.py parity-matrix reduces a probe sweep summary to public-safe verdict counts for all 109 runtime modules, with a triage stage and each module's main gap, written to docs/G1_PARITY_MATRIX.{json,md} (a test keeps the Markdown in sync with the JSON). docs/PARITY_ROADMAP.md lays out the phases from observing every module to Disting NT audition. Linked from the README and the pipeline doc.
  • Fixtures.
    • Output and fade modules default to a captured destination / audible fade; OnOff on; LevMult off its bipolar zero. Other modules' fixtures are byte-identical.
    • Gated envelopes get a held Keyboard gate. An unpatched gate is low on G1, so ADSR, Mod-Env and Multi-Env probes previously compared only their OscA observer.
  • Levels (one measured G1 level taper, -23.3 dB at 64, 0 dB at 127): Mixer (8), LevMult, OscSineBank (plus fixed per-oscillator start phases), FilterBank (stagger-tuned band pairs), Phaser input level; Compressor static law (knee, ratio, limiter, act/mon polarity); FilterE cutoff, tracking and resonance.
  • Envelopes: measured time law, linear attack, exponential decay/release, ADSR attack shapes, AHD, AD-Env and Multi-Env segments and curves; an unpatched gate is low; Keyboard note into a gate is high above 64.
  • Pitch: ClkGen tempo (was ~4.7× fast); DrumSynth tune grid, decay, level and noise path; Sample&Hold holds on the rising edge.
  • Shape: Digitizer quantizer and sample-rate laws (was a passthrough); Expander threshold direction, ratio slope and open start; Overdrive input order; NoteVelScal gain law; OscA triangle uses os.lf_triangle (Faust's triangle ramps in over ~75 samples).
  • One stray change to the Expander detector inside the Compressor commit is reverted on its branch; the Expander calibration owns that line.

Testing

  • 125 tests pass (python3 -m unittest discover -s tests); new tests cover the parity matrix, fixture defaults and gates, and each changed law (tests/test_level_laws.py, tests/test_patch_layouts.py).
  • The merged tree is byte-identical to the tree that produced plan v24 and its sweep.
  • Full probe sweep against the private G1-Emu adapter, 1,489 probes per plan; no probe that passed in v23 fails in v24:
verdict v21 v23 v24 (this PR)
pass 207 541 842
peak-only 307 23 7
level 300 361 192
pitch 371 426 298
shape-or-phase 50 54 100
silence-mismatch 118 29 14
both-silent 134 55 36

Shape-or-phase rises because gated envelopes are now actually compared; their level and mean pitch match, and the residual is phase drift from OscA's pitch-mod depth (G1 measures 4.37–4.48 semitones per unit across levels; the model uses a constant 4.379).

Parity stages (v23 → v24): sweep-clean 10 → 17, near 18 → 22, partial 25 → 23, divergent 53 → 44, not-swept 3 → 3.

Impact Statement

  • Existing features: baseline fixtures change for output, fade, OnOff, LevMult and gated-envelope modules, so earlier plans no longer match regenerated fixtures. Faust output changes for every module listed in Scope.
  • Public APIs / contracts: new parity-matrix command; no existing command changes.
  • Schemas: new public format nardwahl-parity-matrix-v1.
  • Data / artifacts: docs/G1_PARITY_MATRIX.{json,md} added; docs/G1_BASELINE_STATUS.json regenerated from v24 (both-signal midpoints 92 → 104 of 109).
  • Integrations: target renders still need the separately installed G1-Emu adapter profile.
  • Mappings: no expected impact.
  • Backward compatibility: no module status changes; sweep verdicts and stages remain triage only.

Docs

docs/PARITY_ROADMAP.md (new), docs/G1_PARITY_MATRIX.md (generated), docs/G1_BASELINE_PIPELINE.md and README links.

Known gaps for the next round: OscA pitch-mod depth law, LFOB/LFOC startup phase, ClkGen pre-roll (AHD, AD-Env), Phaser notch structure, PercOsc pitch, OscA FMA input, Expander gate.

## Scope Calibrate the shared model laws the v23 sweep exposed, give the remaining silent fixtures real stimuli, and start tracking per-module parity. - **Parity tracking.** `nardwahl.py parity-matrix` reduces a probe sweep summary to public-safe verdict counts for all 109 runtime modules, with a triage stage and each module's main gap, written to `docs/G1_PARITY_MATRIX.{json,md}` (a test keeps the Markdown in sync with the JSON). `docs/PARITY_ROADMAP.md` lays out the phases from observing every module to Disting NT audition. Linked from the README and the pipeline doc. - **Fixtures.** - Output and fade modules default to a captured destination / audible fade; OnOff on; LevMult off its bipolar zero. Other modules' fixtures are byte-identical. - Gated envelopes get a held Keyboard gate. An unpatched gate is low on G1, so ADSR, Mod-Env and Multi-Env probes previously compared only their OscA observer. - **Levels** (one measured G1 level taper, -23.3 dB at 64, 0 dB at 127): Mixer (8), LevMult, OscSineBank (plus fixed per-oscillator start phases), FilterBank (stagger-tuned band pairs), Phaser input level; Compressor static law (knee, ratio, limiter, act/mon polarity); FilterE cutoff, tracking and resonance. - **Envelopes:** measured time law, linear attack, exponential decay/release, ADSR attack shapes, AHD, AD-Env and Multi-Env segments and curves; an unpatched gate is low; Keyboard note into a gate is high above 64. - **Pitch:** ClkGen tempo (was ~4.7× fast); DrumSynth tune grid, decay, level and noise path; Sample&Hold holds on the rising edge. - **Shape:** Digitizer quantizer and sample-rate laws (was a passthrough); Expander threshold direction, ratio slope and open start; Overdrive input order; NoteVelScal gain law; OscA triangle uses `os.lf_triangle` (Faust's triangle ramps in over ~75 samples). - One stray change to the Expander detector inside the Compressor commit is reverted on its branch; the Expander calibration owns that line. ## Testing - 125 tests pass (`python3 -m unittest discover -s tests`); new tests cover the parity matrix, fixture defaults and gates, and each changed law (`tests/test_level_laws.py`, `tests/test_patch_layouts.py`). - The merged tree is byte-identical to the tree that produced plan v24 and its sweep. - Full probe sweep against the private G1-Emu adapter, 1,489 probes per plan; no probe that passed in v23 fails in v24: | verdict | v21 | v23 | v24 (this PR) | |---|---|---|---| | pass | 207 | 541 | **842** | | peak-only | 307 | 23 | 7 | | level | 300 | 361 | 192 | | pitch | 371 | 426 | 298 | | shape-or-phase | 50 | 54 | 100 | | silence-mismatch | 118 | 29 | 14 | | both-silent | 134 | 55 | 36 | Shape-or-phase rises because gated envelopes are now actually compared; their level and mean pitch match, and the residual is phase drift from OscA's pitch-mod depth (G1 measures 4.37–4.48 semitones per unit across levels; the model uses a constant 4.379). Parity stages (v23 → v24): sweep-clean 10 → 17, near 18 → 22, partial 25 → 23, divergent 53 → 44, not-swept 3 → 3. ## Impact Statement - Existing features: baseline fixtures change for output, fade, OnOff, LevMult and gated-envelope modules, so earlier plans no longer match regenerated fixtures. Faust output changes for every module listed in Scope. - Public APIs / contracts: new `parity-matrix` command; no existing command changes. - Schemas: new public format `nardwahl-parity-matrix-v1`. - Data / artifacts: `docs/G1_PARITY_MATRIX.{json,md}` added; `docs/G1_BASELINE_STATUS.json` regenerated from v24 (both-signal midpoints 92 → 104 of 109). - Integrations: target renders still need the separately installed G1-Emu adapter profile. - Mappings: no expected impact. - Backward compatibility: no module status changes; sweep verdicts and stages remain triage only. ## Docs `docs/PARITY_ROADMAP.md` (new), `docs/G1_PARITY_MATRIX.md` (generated), `docs/G1_BASELINE_PIPELINE.md` and README links. Known gaps for the next round: OscA pitch-mod depth law, LFOB/LFOC startup phase, ClkGen pre-roll (AHD, AD-Env), Phaser notch structure, PercOsc pitch, OscA FMA input, Expander gate.
Unpatched envelope gates are low, the envelope starts 4 ms after its edge,
time knobs gain 0.2 ms per step, decay and release are exponential (40 dB
per time), ADSR attack shapes, AHD/AD-Env and Multi-Env segment laws, and
Keyboard-note gates threshold above note 64.
parity-matrix reduces a probe sweep summary to public-safe verdict counts for
all 109 runtime modules, with a triage stage (sweep-clean, near, partial,
divergent, blocked, unobserved, not-swept) and each module's main gap. The
Markdown renders only from the checked-in JSON and a test keeps them in sync.
PARITY_ROADMAP.md lays out the phases from observing every module to Disting NT
audition. The matrix is generated from probe-sweep v23.
The Compressor commit also changed the Expander's envelope follower, which
is outside the level calibration and was not swept. Restore it; the Expander
calibration owns that line.
An unpatched gate input is low on G1, so gated envelopes stayed at zero and
their probes compared only the OscA observer. A held Keyboard gate exercises
attack, decay and sustain; release is not observed. Keyboard is a singleton,
so a probe's own Keyboard source is reused.
Regenerate the parity matrix and baseline status from plan v24
All checks were successful
PR policy check / policy-gate (pull_request) Successful in 0s
8c3efa8b6d
Probe sweep v24: 842 of 1,489 probes pass (541 in v23); sweep-clean 17,
near 22, partial 23, divergent 44. Baseline midpoints carrying signal on both
engines rise from 92 to 104 of 109.
peterswimm deleted branch baseline-calibration 2026-10-21 20:36:07 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
peter-swimm/nardwahl!9
No description provided.