Skip to content

rational M5: the fixed-point profiles, measured per stage - #60

Merged
tap merged 1 commit into
mainfrom
claude/sample-rate-expansion-strategies-ezqzu6
Oct 2, 2026
Merged

tap merged 1 commit into
mainfrom
claude/sample-rate-expansion-strategies-ezqzu6

Conversation

@tap

@tap tap commented Oct 2, 2026

Copy link
Copy Markdown
Owner

What this changes

Milestone M5 of rational/PLAN.md: tests/test_fixed_point.cpp, a battery that states the Q15 and Q31 contract of every ratio of the vocabulary at every named profile as numbers. The plan goes to v0.8 with a measured per-stage table and two stated limits. No engine code changes; the stage has been format-generic since M3.

Why

M5's acceptance asks for Q31 within float's floor, Q15's format-limited numbers stated per stage, exact-unity row sums, wrap safety, the structural zeros out of the dot and bit-pinned tables. The datapaths already existed, so this PR measures them and pins what it finds, including two things that do not meet the 70 dB promise in Q15.

Verification

  • FixedPoint.EveryRowSumsToExactUnityInBothFormats: every phase row, and every decimator's whole filter, sums to 2^14 / 2^30.
  • FixedPoint.TablesAreBitPinned: FNV-1a-64 per ratio, profile and format, 112 pins.
  • FixedPoint.StructuralZerosNeverEnterTheDot: no design zero inside the trimmed span of any interpolator, decimator or mixed-up stage. Float and Q31 MACs equal the design's nonzero count; Q15 MACs are pinned per stage.
  • FixedPoint.Q31TracksDoubleAndQ15IsTheFormatFloor: worst |Q31 − double| 3.4e−9 against float's 5.1e−8. Q15 RMS deviation −85.6 to −95.8 dBFS, pinned per stage within 1 dB.
  • FixedPoint.QuantizedTablesAttainTheirStatedStopbands (host only): Q31 keeps the design's stopband; Q15's attained stopband is pinned per stage within 0.5 dB.
  • FixedPoint.FullScaleNoiseSaturatesNeverWraps: ±full-scale noise lands within 8.8e−4 (Q15) and 1.6e−8 (Q31) of the clamped double model.
  • FixedPoint.FullScaleDcIsExactFromEveryPhase and FixedPoint.ChainsStackTheFloorStageByStage.
  • Run here: the family battery on a host with clang 18 and -Werror (278 of 278), the fixed-point battery with GCC, scripts/tidy.sh clean, clang-format clean, the Cortex-M33 one-shot (87 tests, 87 s) and the Cortex-M55 one-shot (7 s). Hexagon runs in CI; its rational row now also excludes the stopband test.

Notes for the reviewer

  • Q15 decimators are format-limited. The table is h / M on the same Q1.14 LSB, so the attained stopband loses about 20·log10 M dB. At economy, ↓6 reaches −64.7 dB and ↓8 −62.9 dB; ↓2 and ↓3 hold 70. transparent buys nothing in Q15. A lever (per-branch unity tables with the 1/M folded into the finalize) is recorded in the plan and deferred to the codegen phase after M6, since it changes the pinned tables and the rounding point.
  • Mixed ratios going down multiply some structural zeros. 2/3, 3/4 and 3/8 run L-phase rows over a band-M design, so each row crosses the band's zeros: 20 of 65 MACs per superblock for 2/3 at economy. The matrix's MAC figures already count this. Sparse rows are a deferred lever too.
  • Both limits are pinned, so a future fix shows up as a deliberate pin change.

🤖 Generated with Claude Code

https://claude.ai/code/session_015VR1VC4SDGxHZQQsQvPBaA


Generated by Claude Code

The stage has been format-generic since M3 (tap::dsp::sample_traits);
M5 is the battery that states each format's contract as numbers, for
every ratio of the vocabulary at every named profile
(tests/test_fixed_point.cpp):

- every phase row, and every decimator's whole filter, sums to exact
  unity in Q15 and Q31, so full-scale DC of either sign is exactly full
  scale from every phase;
- the Q15 and Q31 tables are bit-pinned (FNV-1a-64, 112 pins);
- no structural zero enters the dot of an interpolator, a decimator or
  a mixed ratio going up; float and Q31 count the design's nonzero
  taps, Q15 its quantized span (pinned per stage; the 120 dB designs'
  outer taps round to zero in Q1.14 and are trimmed);
- Q31 tracks double within 3.4e-9 of full scale, a decade under float
  (5.1e-8; bridge's floor is 5e-8);
- Q15's RMS deviation from double (-85.6 to -95.8 dBFS) and the
  stopband its quantized table attains are pinned per stage;
- +-full-scale noise saturates and never wraps (within 8.8e-4 / 1.6e-8
  of the clamped double model); chains stack the floors stage by stage.

Two honest limits, stated in PLAN.md section 6 and pinned: a Q15
decimator's table is h / M on the same Q1.14 LSB, so its attained
stopband loses about 20 log10 M dB (by 6 at economy -64.7 dB, by 8
-62.9 dB; Q15's pairing is economy, transparent buys nothing there);
and a mixed ratio going down (2/3, 3/4, 3/8) runs L-phase rows over a
band-M design and multiplies the band's zeros its rows cross (20 of 65
MACs per superblock for 2/3). Both levers are deferred with the
codegen levers after M6.

The quantized-stopband test is a host suite (a 16384-point DFT over
112 tables), excluded on the QEMU legs and Hexagon. Plan v0.8; the
stage header, READMEs and CLAUDE files follow.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015VR1VC4SDGxHZQQsQvPBaA
@tap
tap merged commit d25e4ff into main Oct 2, 2026
27 checks passed
@tap
tap deleted the claude/sample-rate-expansion-strategies-ezqzu6 branch October 2, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants