Reference suites: twelve modules reach reference-compared #10

Merged
peterswimm merged 5 commits from reference-suites into main 2026-10-22 02:14:10 +00:00
Owner

Scope

Phase 3 of the parity roadmap: private G1 reference suites for the modules the parity sweep found clean (excluding modules owned by the v25-calibration and input-fix work). Twelve modules now complete their reference contract and are marked reference-compared in the catalog. Cases and evidence stay private; this PR carries only model fixes, tests, catalog status and a short roadmap note.

Model fixes, each driven by a failing reference case, applied to the Faust export and the Python mirror with unittests:

  • Reference evidence: approval is now derived only from retained per-case reports that complete the current contract. A stored approved flag is no longer trusted.
  • Overdrive (62): the measured G1 soft-clip law replaces the tanh curve. The drive knob is value/128 (127 is full). The mod input is held on the 4-frame control grid.
  • Shaper (83): the five modes follow the measured polynomials (1−(1−m)³, 1−(1−m)², linear, m², m³).
  • CompareLev (59): the input is sampled on the 4-frame G1 control grid, so edges land where the G1 puts them.
  • FilterBank (32):
    • The bottom band is a 4-pole lowpass and the top band a 4-pole highpass; they were bandpasses before.
    • Adjacent bands alternate polarity, so they add at the crossovers instead of cancelling.
    • The Python mirror now uses TPT state-variable sections, matching fi.svf. The old Chamberlin sections were unstable near Nyquist at 48 kHz.
  • Preflight: contract_topology_violations compared the integer section with a string, so it flagged every module in every patch. It now checks the contract's allowed_sections.

Testing

python3 -m unittest discover -s tests: 131 tests OK. tools/export_public.py into an empty directory: public tree verified.

Each case renders on the private G1-Emu target and on the Faust candidate, under the harness's default tolerances (reference-compare --candidate-engine faust). Any pass whose RMS error was more than 10% of the reference RMS was additionally held back from import. Parameter-extremes always has at least two reports. Event cases use a single Keyboard note-on, start at analysis time 0, and use transient alignment.

Module Scenarios Result
2Output (4) extremes, midpoints (incl. selectors), ports, modulation, midi-events ×2 all pass → reference-compared
1Output (5) extremes, midpoints (incl. selectors), ports, modulation, midi-events ×2 all pass → reference-compared
FilterBank (32) extremes, midpoint, ports, modulation, reset-retrigger ×2 all pass after the fix (static within ~1.5%) → reference-compared; retrigger-2 held by the 10% guard (10.2%), scenario covered by retrigger-1
Mixer(8) (40) extremes, midpoint, single-input port probes, modulation all pass → reference-compared
Overdrive (62) extremes, midpoint, ports, modulation pass after fix (failed 5–18% before) → reference-compared
OnOff (76) extremes, midpoint, ports, modulation, reset-retrigger ×2 all pass → reference-compared
Delay (78) extremes, midpoint, ports, modulation all pass (rel < 5%) → reference-compared
Shaper (83) extremes, midpoints (selectors), ports, modulation pass after fix (mode 4 was 26% off) → reference-compared
LevMult (111), LevAdd (112), 1to2Fade (113), 2to1Fade (114) extremes, midpoint, ports, modulation all pass → reference-compared
Compressor (21) extremes, midpoint, ports, modulation all 25 cases pass tolerances; modulation (20 Hz) is 10.6% low, held → stays approximate
CompareLev (59) extremes, midpoint, ports, modulation static cases pass (~1%); modulation fails edge timing → stays approximate
EventSeq (17) — not run; needs a multi-edge clock → stays approximate

Documented blockers (also in docs/PARITY_ROADMAP.md):

  • Compressor:
    • Measured release is linear in dB, about 105·e^(−0.0344·knob) dB/s; the model's exponential decay is much faster.
    • The detector looks peak-referenced, yet the output is flat from 8 to 330 Hz. That is unresolved.
  • CompareLev: modulation edges drift −5 to +3 samples over 1 s with OscA fine-pitch error, which belongs to OscA calibration.
  • EventSeq: every fixture clock source (ClkGen, or CompareLev fed from OscA) is still being calibrated.

preflight-disting now accepts patches built only from the twelve modules: Delay→2Output, Overdrive→2Output and FilterBank→2Output all report ok. A patch with any non-reference-compared module (OscA, Compressor, CompareLev) is still refused as unverified. Before the topology fix it refused every patch. Nothing was built: the Disting NT toolchain is not installed.

Impact Statement

  • Twelve modules move from approximate to reference-compared, so Disting preflight accepts them.
  • Four model laws change audibly toward the G1:
    • Overdrive soft clip
    • Shaper curves
    • CompareLev control-grid timing
    • FilterBank edge bands and band summation
  • Patches using those modules will render differently, closer to the hardware.
  • No tolerances were widened.
  • The parity matrix was not regenerated.
  • No cases, captures, ROM material or local paths are included.
## Scope Phase 3 of the parity roadmap: private G1 reference suites for the modules the parity sweep found clean (excluding modules owned by the v25-calibration and input-fix work). Twelve modules now complete their reference contract and are marked `reference-compared` in the catalog. Cases and evidence stay private; this PR carries only model fixes, tests, catalog status and a short roadmap note. Model fixes, each driven by a failing reference case, applied to the Faust export and the Python mirror with unittests: - **Reference evidence**: approval is now derived only from retained per-case reports that complete the current contract. A stored `approved` flag is no longer trusted. - **Overdrive (62)**: the measured G1 soft-clip law replaces the tanh curve. The drive knob is value/128 (127 is full). The mod input is held on the 4-frame control grid. - **Shaper (83)**: the five modes follow the measured polynomials (1−(1−m)³, 1−(1−m)², linear, m², m³). - **CompareLev (59)**: the input is sampled on the 4-frame G1 control grid, so edges land where the G1 puts them. - **FilterBank (32)**: - The bottom band is a 4-pole lowpass and the top band a 4-pole highpass; they were bandpasses before. - Adjacent bands alternate polarity, so they add at the crossovers instead of cancelling. - The Python mirror now uses TPT state-variable sections, matching `fi.svf`. The old Chamberlin sections were unstable near Nyquist at 48 kHz. - **Preflight**: `contract_topology_violations` compared the integer section with a string, so it flagged every module in every patch. It now checks the contract's `allowed_sections`. ## Testing `python3 -m unittest discover -s tests`: 131 tests OK. `tools/export_public.py` into an empty directory: public tree verified. Each case renders on the private G1-Emu target and on the Faust candidate, under the harness's default tolerances (`reference-compare --candidate-engine faust`). Any pass whose RMS error was more than 10% of the reference RMS was additionally held back from import. Parameter-extremes always has at least two reports. Event cases use a single Keyboard note-on, start at analysis time 0, and use transient alignment. | Module | Scenarios | Result | |---|---|---| | 2Output (4) | extremes, midpoints (incl. selectors), ports, modulation, midi-events ×2 | all pass → reference-compared | | 1Output (5) | extremes, midpoints (incl. selectors), ports, modulation, midi-events ×2 | all pass → reference-compared | | FilterBank (32) | extremes, midpoint, ports, modulation, reset-retrigger ×2 | all pass after the fix (static within ~1.5%) → reference-compared; retrigger-2 held by the 10% guard (10.2%), scenario covered by retrigger-1 | | Mixer(8) (40) | extremes, midpoint, single-input port probes, modulation | all pass → reference-compared | | Overdrive (62) | extremes, midpoint, ports, modulation | pass after fix (failed 5–18% before) → reference-compared | | OnOff (76) | extremes, midpoint, ports, modulation, reset-retrigger ×2 | all pass → reference-compared | | Delay (78) | extremes, midpoint, ports, modulation | all pass (rel < 5%) → reference-compared | | Shaper (83) | extremes, midpoints (selectors), ports, modulation | pass after fix (mode 4 was 26% off) → reference-compared | | LevMult (111), LevAdd (112), 1to2Fade (113), 2to1Fade (114) | extremes, midpoint, ports, modulation | all pass → reference-compared | | Compressor (21) | extremes, midpoint, ports, modulation | all 25 cases pass tolerances; modulation (20 Hz) is 10.6% low, held → stays approximate | | CompareLev (59) | extremes, midpoint, ports, modulation | static cases pass (~1%); modulation fails edge timing → stays approximate | | EventSeq (17) | — | not run; needs a multi-edge clock → stays approximate | Documented blockers (also in `docs/PARITY_ROADMAP.md`): - **Compressor**: - Measured release is linear in dB, about 105·e^(−0.0344·knob) dB/s; the model's exponential decay is much faster. - The detector looks peak-referenced, yet the output is flat from 8 to 330 Hz. That is unresolved. - **CompareLev**: modulation edges drift −5 to +3 samples over 1 s with OscA fine-pitch error, which belongs to OscA calibration. - **EventSeq**: every fixture clock source (ClkGen, or CompareLev fed from OscA) is still being calibrated. `preflight-disting` now accepts patches built only from the twelve modules: Delay→2Output, Overdrive→2Output and FilterBank→2Output all report ok. A patch with any non-reference-compared module (OscA, Compressor, CompareLev) is still refused as unverified. Before the topology fix it refused every patch. Nothing was built: the Disting NT toolchain is not installed. ## Impact Statement - Twelve modules move from `approximate` to `reference-compared`, so Disting preflight accepts them. - Four model laws change audibly toward the G1: - Overdrive soft clip - Shaper curves - CompareLev control-grid timing - FilterBank edge bands and band summation - Patches using those modules will render differently, closer to the hardware. - No tolerances were widened. - The parity matrix was not regenerated. - No cases, captures, ROM material or local paths are included.
peterswimm deleted branch reference-suites 2026-10-22 02:14:10 +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!10
No description provided.