Repository navigation
Rational comparison: ↑2, ↓2, 3/2 and 2/3 against libsamplerate, soxr, r8brain and SpeexDSP at matched spec and frontier - #77
Merged
Conversation
…gine matrix PR 3 of the comparison plan, in progress: the rational engine measured against libsamplerate, soxr, r8brain and SpeexDSP at four ratios of its vocabulary (up 2, down 2, 3/2, 2/3), at matched spec and at each library's frontier, through the family's tools/compare. - rational/bench/compare (host) and rational/bench/icount/cmp_main.cpp (M33/M55/Hexagon, 2 s and 4 s, four ratios); compare.yml becomes a matrix job per engine (scripts/compare_binaries.sh <engine>), each harvesting its own record; update_compare_docs.py derives the third doc. - notebooks/rational_comparison.ipynb, executed: the matched settings by the same rule as bridge's, applied across the four ratios at once, with the spurious products found at the exact candidate frequencies and the decimations probed in their stopbands; THD+N and DR at the 24-bit interface; latency in each engine's own unit, as milliseconds. - rational/docs/COMPARISON.md with the quality and latency tables; the family index's rational row; the README link. Still to land: the host table, the harvested record and its derived block. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3HxzEGiZp7jStoMuYNuBK
… cost line From the local M55/M33/Hexagon derivation; the committed record follows from the compare.yml dispatch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3HxzEGiZp7jStoMuYNuBK
One session on this host, median of 5, every subject at the four ratios. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3HxzEGiZp7jStoMuYNuBK
…gines) The first per-engine matrix run, on this branch's head: rational's record and its derived block (four ratios, three targets), with the async and bridge records re-measured in their own jobs — every count identical to the committed records, so only their provenance lines move. The rational block reproduces the local derivation in every steady-state cell; the Hexagon construction cells round 0.1 M lower from the same constant 1,620-instruction difference in the runner's process start-up. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3HxzEGiZp7jStoMuYNuBK
tap
pushed a commit
that referenced
this pull request
Oct 10, 2026
The comparison plan (#73, #75, #76, #77) and its follow-up (#78) closed; this is the plan for what the family's plans and ledgers still carry open, sequenced into twelve weeks in three blocks, with "production-ready" defined as a thirteen-row checklist per engine so the verdict can be checked rather than believed. Drafted and then audited by two independent adversarial reviews (one against the trees' facts and settled decisions, one against engineering judgement). The audit changed the draft materially: the book's bridge chapters are done (#68), so they are off the list; rational has no cross-engine validation by design (scipy and decimate.h are its legs); TSan runs async only; four host compilers and three QEMU targets, not the draft's counts; the +1.9 % M55 ratio23_q15_eco drift is ab8fea3's stated move, not a DspTap bump, and the chain rows sit +926/+1,102; the hardware block never ran bridge or rational on silicon; nothing builds with -fno-exceptions; TSan has never seen the converter with two threads; no footprint, stack or worst-single-call figure exists; Setup 1's "< 1 ppm" criterion tests the counting, not the servo, and cheap USB dongles may not own a crystal; the timestamp servo is a four-to-five-week extension, not an overload, and must not be frozen in the release that adds it; "C ABIs frozen" needs a reconciled NULL model, an extension rule, SOVERSION and a compat test. Section 7 holds the six decisions the maintainer takes before week 1, each with a recommendation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3HxzEGiZp7jStoMuYNuBK
tap
pushed a commit
that referenced
this pull request
Oct 10, 2026
The comparison plan (#73, #75, #76, #77) and its follow-up (#78) closed; this is the plan for what the family's plans and ledgers still carry open, sequenced into twelve weeks in three blocks, with "production-ready" defined as a thirteen-row checklist per engine so the verdict can be checked rather than believed. Drafted and then audited by two independent adversarial reviews (one against the trees' facts and settled decisions, one against engineering judgement). The audit changed the draft materially: the book's bridge chapters are done (#68), so they are off the list; rational has no cross-engine validation by design (scipy and decimate.h are its legs); TSan runs async only; four host compilers and three QEMU targets, not the draft's counts; the +1.9 % M55 ratio23_q15_eco drift is ab8fea3's stated move, not a DspTap bump, and the chain rows sit +926/+1,102; the hardware block never ran bridge or rational on silicon; nothing builds with -fno-exceptions; TSan has never seen the converter with two threads; no footprint, stack or worst-single-call figure exists; Setup 1's "< 1 ppm" criterion tests the counting, not the servo, and cheap USB dongles may not own a crystal; the timestamp servo is a four-to-five-week extension, not an overload, and must not be frozen in the release that adds it; "C ABIs frozen" needs a reconciled NULL model, an extension rule, SOVERSION and a compat test. Section 7 holds the six decisions the maintainer takes before week 1, each with a recommendation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3HxzEGiZp7jStoMuYNuBK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
PR 3 of the comparison plan, the last (after #73, #75, #76). The
rationalengine measured against the four resampler libraries at four ratios of its vocabulary — ↑2 (48 → 96 kHz), ↓2 (96 → 48), 3/2 (32 → 48) and 2/3 (48 → 32) — in quality, latency, host throughput and embedded instruction counts, through the family'stools/compare; andcompare.ymlrestructured as one job per engine.rational/bench/compare(host, Google Benchmark, 68 subjects) andrational/bench/icount/cmp_main.cpp(M33/M55/Hexagon, 2 s and 4 s, four ratios, 80 binaries per target).compare.ymlis a matrix overasync,bridge,rational, each job measuring its engine's binaries (scripts/compare_binaries.sh <engine>), harvesting its own record and uploading it ascompare_counts-<engine>; the three ran in parallel in 16 / 28 / 44 minutes.update_compare_docs.pyderives the third doc;ci.yml'scompare-docsgates all three andcompare-smokebuilds the new targets.rational/notebooks/rational_comparison.ipynb, executed: the matched-setting sweep across the four ratios at once (spurious products found at the exact candidate frequencies |a·f_in + b·f_out ± f|; decimations probed in their stopbands, since a Nyquist design's transition band aliases above the passband edge by contract), THD+N and DR at the 24-bit interface, latency in each engine's own unit as milliseconds.rational/docs/COMPARISON.md, the family index's rational row, the README link.Why
The async comparison asked what clock recovery costs and the bridge comparison asked the synchronous question at one pair;
rationalis the family's within-family engine, so its question is the same one at the ratios a Nyquist stage serves. The matching rule is the bridge comparison's, applied across four ratios at once: a competitor's matched setting is its cheapest whose measured stopband is at least the tier's and whose passband droops no more than 0.1 dB at the tier's edge (3/8 and 5/12 of the lower rate) at every ratio; a setting that passes three and fails one is not matched. The picks are asserted against the benches' constants.Verification
MEDIUM, soxr 16-bit at a 0.75 passband, r8brain 70 dB at a 16 % band, SpeexDSP quality 2 (float) and 3 (fixed-point); transparent —BEST, soxr 20-bit at 0.80, r8brain 120 dB at 10 %, SpeexDSP quality 9 (fixed-point:None). One notch below the bridge picks, as the fractional edges predict.economy−88 dB,transparent−140 dB, SpeexDSP quality 2 −82 dB, r8brain and libsamplerate's economy rows −122 dB). The doc says the 997 Hz table is a slice and the sweep is the contract measurement. SpeexDSP's quality 2 is the one competitor setting that lands oneconomy's 70 dB (70–76 dB worst product).bridge's 58-tap polyphase did not.economy; rational 7–12× libsamplerate; SpeexDSP's fixed-point build out-runs rational's Q15 stage on x86 by 1.6–2× (its 32-bit integer math vectorizes where rational's 64-bit accumulation does not), stated plainly with the embedded tables as the counterweight.WERRORand the C ABIs on, zero warnings; clang-format and clang-tidy clean on the two new units (house naming, mandatory braces); retired-words clean; both workflows parse;update_compare_docs.pyidempotent on all three records; the local native runs of all 40 workloads report ok.compare-smokejob's new rational targets on the hosted compilers (built locally with GCC; this PR's CI is its first run).Notes for the reviewer
sin()fixture dominates the 2 s / 4 s split, and rational's one-prototype design is a fraction of a million. The doc says so; the siblings' construction columns carry the same fixture but are dominated by their designs.BEST, down to −16 M on the M33) are the split's resolution against that engine's per-frame drift, footnoted as on Bridge comparison: 44.1 ↔ 48 against libsamplerate, soxr, r8brain and SpeexDSP at matched spec and frontier #76, not clamped.compare_countsartifact name is nowcompare_counts-<engine>.rational_comparison.ipynbis new and committed executed; the sibling notebooks are untouched.construct_q15_ecoratchet leg does not include the input fixture its streaming workloads synthesize, as async's and bridge's construct legs do since Comparison freshness gate, construct-only ratchet legs, async comparison refresh #73; aligning it re-records that baseline.🤖 Generated with Claude Code
https://claude.ai/code/session_01G3HxzEGiZp7jStoMuYNuBK
Generated by Claude Code