tools/measure_effect_cost.py writes OD_PRE_GAIN = 11.7709228 as a
literal, with the comment "written here as a literal so every leg feeds the
node the SAME number. The class computes it in Python floats, which are
double on CPython and on the unix build and single on a board; that
difference belongs to the class row and would otherwise be measured here as
if it were the node's."
A literal does not achieve that when the decimal is not exactly
representable. A board parses 11.7709228 once, in mp_float_t (single),
and holds 413c55b4. A desktop parses it in double and the node rounds that
to 413c55b3. One ULP apart, and the node is handed a different number on
each leg — which is exactly what the comment says the row exists to avoid.
Measured on the P4 (2026-09-18, audioif e3b95e7):
mpftp exec -d COM4 'import struct, binascii
print(binascii.hexlify(struct.pack(">f", 11.7709228)).decode())'
-> 413c55b4
.venv/bin/python -c 'import struct, binascii
print(binascii.hexlify(struct.pack(">f", 11.7709228)).decode())'
-> 413c55b3
The consequence is that all four audioshaper.Waveshaper@drive1/2/4/8 rows
render different bytes on a board than on either desktop, and the Phase 4
board run of 2026-09-17 recorded that split without a cause. It is the row,
not the node:
| target |
P4 |
T-Embed S3 |
CPython |
desktop MicroPython |
@drive4 (pre_gain 11.7709228) |
7dd67c39a186b05d |
= |
3de13c30d965d6b1 |
= |
@drive4exact (pre_gain 11.75) |
e52f8669fcb8ef41 |
= |
= |
= |
@drive1exact (pre_gain 11.75) |
38835bf9b3e99559 |
= |
= |
= |
@bits12 (pre_gain 1.0) |
117776fe4e37894c |
= |
= |
= |
8c3528c adds the three exact-pre_gain rows as the control and leaves
OD_PRE_GAIN alone, because changing it would move every @drive* figure
already in
docs/effects-internal/audits/effects-cost-table.md and those rows are
cited by five evidence packs.
What is owed: decide whether the @drive* rows keep the class's own
decimal (and say in the table that their digests are leg-dependent for this
reason) or move to a pre_gain every format holds — and if they move, re-take
the rows and the packs that cite them in one pass. The same trap applies to
any palette row whose settings are not exactly representable; @x1..@x8
and the @od-*/@ex-* biquad rows should be checked the same way.
Found by the Phase 4 board run, 2026-09-18. Cost figures are unaffected.
tools/measure_effect_cost.pywritesOD_PRE_GAIN = 11.7709228as aliteral, with the comment "written here as a literal so every leg feeds the
node the SAME number. The class computes it in Python floats, which are
double on CPython and on the unix build and single on a board; that
difference belongs to the class row and would otherwise be measured here as
if it were the node's."
A literal does not achieve that when the decimal is not exactly
representable. A board parses
11.7709228once, inmp_float_t(single),and holds
413c55b4. A desktop parses it in double and the node rounds thatto
413c55b3. One ULP apart, and the node is handed a different number oneach leg — which is exactly what the comment says the row exists to avoid.
Measured on the P4 (2026-09-18, audioif
e3b95e7):The consequence is that all four
audioshaper.Waveshaper@drive1/2/4/8rowsrender different bytes on a board than on either desktop, and the Phase 4
board run of 2026-09-17 recorded that split without a cause. It is the row,
not the node:
@drive4(pre_gain11.7709228)7dd67c39a186b05d=3de13c30d965d6b1=@drive4exact(pre_gain11.75)e52f8669fcb8ef41===@drive1exact(pre_gain11.75)38835bf9b3e99559===@bits12(pre_gain1.0)117776fe4e37894c===8c3528cadds the three exact-pre_gainrows as the control and leavesOD_PRE_GAINalone, because changing it would move every@drive*figurealready in
docs/effects-internal/audits/effects-cost-table.mdand those rows arecited by five evidence packs.
What is owed: decide whether the
@drive*rows keep the class's owndecimal (and say in the table that their digests are leg-dependent for this
reason) or move to a
pre_gainevery format holds — and if they move, re-takethe rows and the packs that cite them in one pass. The same trap applies to
any palette row whose settings are not exactly representable;
@x1..@x8and the
@od-*/@ex-*biquad rows should be checked the same way.Found by the Phase 4 board run, 2026-09-18. Cost figures are unaffected.