Repository navigation
audioif: the GIGA renders its audio from an interrupt - #392
Merged
Merged
Conversation
The DAC's pump ran on the interpreter, so a garbage collection, a write to /flash or a long Python callback emptied the 93 ms ring and the jack played silence. It now runs from an interrupt of the driver's own (SWPMI1's vector, priority 7, below the flash code's mask) on a 12 KB stack of its own, with the heap locked. The interpreter's side of the pump lock holds the interrupt off, and _audioif.render_mode() switches back to the interpreter. The interrupt needs an audiodsp with render_kick (AUDIODSP_PORT_IRQ_HOOKS); built against an older one the pump stays on the interpreter, as before.
This was referenced Nov 10, 2026
Moves the audiodsp pin from 6d08b07 to 46e9224: the render_kick hook the GIGA driver here uses to render from its DAC interrupt (audiodsp#403), the 20 ms walk of a Mix or level move in the nodes (audiodsp#400), and type stubs for thirteen modules (audiodsp#401).
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.
On the Arduino GIGA R1, the audio pump has rendered on the interpreter, so anything that held the interpreter for longer than the DAC's 93 ms ring played silence: a garbage collection, a write to
/flash, a burst of BLE callbacks. This moves the render to an interrupt of its own (SWPMI1, NVIC priority 7, on a 12 KB stack of its own), raised by the DAC's DMA and the 4 ms soft timer. This is the driver half of #290 and #291; the other half is audiodsp's interrupt hooks.The interrupt sits below the flash code's mask (priority 6), which masks one block operation at a time, so the render catches up between blocks.
_audioif.render_mode()switches between"irq"and"interpreter"at run time, and_audioif.render_stats()reports renders, the longest render, stack used and the priority. Built against an audiodsp withoutAUDIODSP_PORT_IRQ_HOOKS(today's pin), the driver stays on the interpreter as before andrender_mode("irq")raises. The ESP32, unix and Windows drivers don't change.What I ran, on a GIGA R1 with the Display Shield, playing Synth Station's electric piano with a held chord,
gc.collect()every 3 s and a 32 KB write to/flashevery 30 s, for ten minutes:render_mode("interpreter"), 2 minThe longest render was 24.9 ms and the deepest stack 4,396 of 12,288 bytes. #291's case, 60 s of a PC central writing about 50 times a second while the board notifies every 10 ms, starved 1,721 frames before and 0 after. A full-screen LVGL refresh took a median 97 ms on the interpreter render and 99 ms on the interrupt render, with nothing starved in either. The board booted to its Home app and joined Wi-Fi on three resets.
On unix, a render through audiodsp's interrupt-hooks branch is byte-identical to one through its main (same SHA-256), and the audioif probes pass.
Not verified: the measurements above used an audiodsp with the interrupt hooks, which isn't merged yet; until it is and the pin moves, CI builds this in interpreter mode. One earlier interrupt build hung once and didn't reproduce in 300 play/stop cycles afterwards; the interpreter-side races found while chasing it are fixed on the audiodsp side.