Skip to content

ESP32 firmware renders audiodynamics.Dynamics at baseline differently from the pre-node build; Filter, Dynamics and Distortion differ board-vs-desktop under both desktop builds #55

Description

@bdbarnett

Found by the effects program's Phase 1 cost run (audiocomponents docs/effects-cost-table.md, "With the Phase 1 nodes"; tool tools/measure_effect_cost.py), 2026-09-07, on the ESP32-P4 (COM4) and ESP32-S3 (COM49) with firmware v1.28.0-dirty on 2026-09-07 built from audioif 2f6cbc3. Both boards agree with each other on every row; the findings are about the desktop and about the previous firmware.

1. audiodynamics.Dynamics at baseline settings moved between firmwares

The pre-node firmware (built 2026-09-04) rendered the cost tool's baseline Dynamics material to a990b35874e3cfde; the 2f6cbc3 firmware renders it to d99590c3e97d923c, on both boards. Five other baseline nodes are unchanged between the two firmwares. The twenty-one new options are ruled out as the cause: a desktop A/B at 1ad72ad~1 (before the options) and at 2f6cbc3 gives e9d39fe10823e8a1 for both. Neither firmware records the audioif revision it was built from, so what moved between the two builds is not recorded. The likely mechanism, given finding 3 below, is that the options refactor changed the kernel's code shape enough for the ESP32 compiler to contract multiply-adds differently — the same arithmetic, different rounding on the board only — but that is a hypothesis, not a measurement.

2. audiofilters.Filter, audiodynamics.Dynamics and audioeffects.Distortion differ board-vs-desktop under both desktop builds

Nine of the new-node digests differed from the desktop and were fully explained by fused multiply-add: rebuilding the CPython extension at the same commit with CC="gcc -mfma -ffp-contract=fast" (138 vfmadd instructions against 0) reproduced all nine board digests bit-exactly. setup.py:6-14 names the mechanism. These three targets differ from the desktop under both desktop builds, so a second cause is at work for them and was not chased.

Consequence

tests/parity/golden/dsp_nodes.json cannot see this class of difference: all four gated targets are x86-64 builds. Brad's standing rule (audioif#5, the aarch64 lane) is bit-identity within one architecture and an accepted baseline per architecture, never a tolerance. What this issue asks for: (a) firmware that records its audioif revision (a _audioif.__version__-style commit id in the module) so finding 1 can be attributed next time; (b) a per-board accepted baseline for the cost tool's digests, added the way verify_effects keeps per-architecture baselines; (c) the second cause for the three ported/legacy targets in finding 2 identified.

Raw digests and the FMA rebuild recipe are in audiocomponents docs/effects-alias-floor.json and the cost table's notes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions