Skip to content

audiograph: round without lrintf so RP2350 CircuitPython links (#311) - #314

Merged
bdbarnett merged 1 commit into
mainfrom
fix/lrintf-rp2350
Oct 23, 2026
Merged

bdbarnett merged 1 commit into
mainfrom
fix/lrintf-rp2350

Conversation

@bdbarnett

Copy link
Copy Markdown
Contributor

Building audiodsp into CircuitPython for an RP2350 board, such as the Raspberry Pi Pico 2, failed at link with undefined reference to 'lrintf' from audiodsp_graph.o. The RP2350 port doesn't link that libm function, so the README's claim that every module builds into CircuitPython 11 didn't hold there.

The graph runner called lrintf in two places: to turn a sample-and-hold rate in Hz into a whole number, and to round a clamped float sample to int16. Both now use a small static inline in audiodsp_graph.c that rounds to nearest, ties to even, which is what lrintf does in the default rounding mode. This is the same approach audiodsp_trig took for fmod on the RP2040 (#210, #225).

Nothing changes on other builds. The helper agrees with lrintf for every float up to 2^24 in magnitude, both signs (about 2.5 billion values, checked exhaustively), which covers any sample rate and any int16 sample. No other lrint or fmod call remains in src/shared or src/circuitpython_spike.

How it was checked, with CircuitPython main at fb98f214c and arm-gnu-toolchain 14.2.rel1:

  • raspberry_pi_pico2: before the change, the link fails with five undefined reference to 'lrintf'. After it, the link is clean and the .uf2 is 1,995,776 bytes (997,804 bytes of flash used).
  • pimoroni_pico_plus2w: links clean with every audiodsp module, .uf2 of 3,079,680 bytes (1,539,772 bytes of flash used).
  • The graph tests pass: test_cpython_audiograph.py and test_cpython_audiograph_nodes.py (25 passed), graph_probe.py on a unix MicroPython build (GRAPH PASS), and verify_graph.py comparing CPython with that MicroPython at a tolerance of 0 counts (0 samples differ). Each planted fault in both gates still fails.

Fixes #311

CircuitPython's raspberry_pi_pico2 port links no lrintf, so building audiodsp
there failed at link with an undefined reference from audiodsp_graph.o. The
graph runner called it in two places: turning a sample-and-hold rate in Hz
into a whole number, and rounding a clamped float sample to int16.

Both now go through a small static inline that rounds to nearest, ties to
even, which is what lrintf does in the default rounding mode. It matches
lrintf for every float up to 2^24 in magnitude (checked exhaustively), so the
render is the same on every build.
@bdbarnett
bdbarnett merged commit 0a52f83 into main Oct 23, 2026
33 of 34 checks passed
@bdbarnett
bdbarnett deleted the fix/lrintf-rp2350 branch October 23, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

CircuitPython build for raspberry_pi_pico2 fails to link: undefined lrintf in audiograph

1 participant