Repository navigation
audiopump.Ring on CircuitPython: audio your code computes, pulled by the board's outputs - #298
Merged
Merged
Conversation
bdbarnett
force-pushed
the
feat/stream-sample
branch
from
October 21, 2026 16:30
9f99c41 to
28eae70
Compare
… board's outputs pull
…he pump's Ring, and the mixer test on MicroPython in CI
…d the board check
bdbarnett
force-pushed
the
feat/stream-sample
branch
from
October 21, 2026 17:07
28eae70 to
2ff7ac5
Compare
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.
CircuitPython's audio outputs play samples, and a sample is filled from C, so there was no way to play audio that Python code or a graph of nodes renders as it goes. This adds
audiopump.Ringto the CircuitPython build: a sample your code writes PCM into, whichaudiobusio.I2SOut,audioio.AudioOut,audiopwmio.PWMAudioOutandaudiomixerpull in C, with no Python in the pull path.It has MicroPython's
audiopump.Ringsurface (write,space,level,stats,clear,deinit, the audiosample fields;from_usbstays MicroPython's), so one producer runs on both. An underrun plays a whole block of silence, keeps the partial block and counts it instats()[3]; a write that doesn't fit is short, in whole frames, and counts an overrun.What differs from the MicroPython twin, and why:
PWMAudioOut) pull from an interrupt. Soclear()doesn't write the consumer's indices: it posts one word saying where to drop to, and the next pull carries it out.space()andlevel()count the dropped room at once.audiomixerdoes it.It is a new module under
src/circuitpython_spike/and one word incircuitpython.mk. No existing node changes, and nothing in CircuitPython is patched.Tests.
tests/circuitpython/ring_through_mixer.pychecks the ring alone bit-exact (with the digests), underrun, overrun,clear(), a wrap many times round a ring whose capacity is not a power of two, and then pulls it throughaudiomixerin five shapes (mixer buffers that split and span ring blocks, mono, mono into stereo) with a starved stretch, checking every frame's left and right value and that the silence the mixer handed out is the silence the ring counted. 1063 checks pass on a CircuitPython 11.0.0-alpha.1 unix build. Three faults planted in the CircuitPython Ring each fail it: channels swapped, every seventh block dropped, an underrun not counted. The same file passes on MicroPython's unix build, and CI now runs it there (clean-build.yml).tests/test_binding_parity.pyholds the two Rings to the same names, and fails when one is removed from the CircuitPython binding.