Repository navigation
v0.6.1: engine changes no longer stall the audio (#36) - #38
Merged
Merged
Conversation
Plaits clears its shared engine RAM on every engine change, and GCC sends those fills to picolibc's memset -- a byte loop on this toolchain, ~6.6 cycles a byte. Particle's 16 KB diffuser took ~1.7 ms (twice that when entered with MORPH below centre, where the M3f diffuser skip clears again), String's delay lines ~1.1 ms, inside a 2 ms audio block. FxEngine::Clear() and DelayLine::Reset() now call plaits::sp1_zero (firmware/src/sp1_zero.cc, word stores) through two one-passage overrides. Scoped to Plaits on purpose: libc's memset also zeroes .bss before main(), so it is not replaced. check_image.py fails an image where sp1_zero calls anything or Particle's / String's reset still calls memset. Host: all suites pass; renders bit-identical to main across 30 engine changes at four arena alignments. Hardware (2026-10-05): Particle's first call 457-625 us (was up to 4000), String 509 us (was 1559), worst block 80.9 %, no stream failures. Per-block output clears are #37. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fixes #36.
The bug
Changing engine could stall the audio for up to ~4 ms inside a 2 ms block. Plaits' engines share one block of RAM, so each engine's
Reset()clears its buffers on every change. GCC sends those fills to picolibc'smemset, which on this toolchain is a byte loop at ~6.6 cycles per byte:The fix
firmware/src/sp1_zero.cc:plaits::sp1_zerofills a word at a time, with byte head and tail for unaligned buffers. It's built with-fno-tree-loop-distribute-patternsso GCC can't turn it back into amemsetcall.FxEngine::Clear()(Particle's diffuser, the ensemble used by String machine and Chords) andDelayLine::Reset()(String). 14 call sites, the same byte counts as before.memsetis not replaced: it also zeroes.bssbeforemain(), where a fault is a boot loop on a device with no reset pin.tools/ci/check_image.py: fails an image wheresp1_zerocalls anything, or where Particle's or String's reset still callsmemset.firmware/VERSION, README, issue-form placeholders.Verification
0x20000,check_image.pyall pass.mainacross 30 engine changes with MORPH crossing centre, at four arena alignments. A guard-byte test ofsp1_zerocovers 296 alignment/length cases.fail/rstThe per-block output clears, which go through the same byte loop, are #37.
🤖 Generated with Claude Code