perf: stabilize audio engine for infinite-loop playback#5902
perf: stabilize audio engine for infinite-loop playback#59027se7en72025 wants to merge 4 commits intosugarlabs:masterfrom
Conversation
|
✅ All Jest tests passed! This PR is ready to merge. |
|
✅ All Jest tests passed! This PR is ready to merge. |
cfb8dce to
e82616d
Compare
|
✅ All Jest tests passed! This PR is ready to merge. |
|
❌ Some Jest tests failed. Please check the logs and fix the issues before merging. Failed Tests: |
Refactor unhighlight logic for note value blocks to ensure minimum highlight duration and prevent timer accumulation.
|
✅ All Jest tests passed! This PR is ready to merge. |
|
Hi, @walterbender synthutils.js: Increased POLYCOUNT from 3 to 6 to avoid voice starvation; introduced a fast path that bypasses audio graph rewiring for simple notes (the primary cause of underruns); introduced a 500 ms buffer for cleanup timers to avoid early synth garbage collection. |
kartikktripathi
left a comment
There was a problem hiding this comment.
@walterbender, approving. Changes are technically sound and improve stability under sustained/infinite playback without introducing regressions.
Thanks!
Summary
This PR resolves four compounding audio engine bottlenecks that resulted in
progressive crackling, main thread stalls, and eventual crashes during long or infinite Music Blocks sessions.
Changes
js/utils/synthutils.jsinstantly by two turtles playing chords, resulting in silent voice
stealing and missing notes.
_performNotesfast-path guard:paramsEffectsis always anon-null object (always contains
doPartials: true), so the existingparamsEffects === nullfast-path was never taken. Every plain notere-wired the Web Audio graph via
disconnect()/chain(). The fixchecks whether any real effect nodes are needed; if not, in-place
mutations are applied and
triggerAttackReleaseis called directly.beatValue * 1000 ms, coinciding with the note end. Any audio-clockjitter caused premature disposal (crackling). A 500 ms buffer absorbs drift.
js/turtle-singer.jssetTimeoutforunhighlight(blk)was spawned on every note regardless of whether aprevious one was still pending. In tight loops this accumulates
thousands of stale timers and stalls the main thread. A
_unhighlightTimersmap now cancels the previous timer beforesetting a new one.## Testing
Criticality Scores (pre-fix)