fix: make reverb allocation failure safe (mirrors existing echo guard)#744
Conversation
…@ alloc_echo_delay_lines (line 204), config_echo (line 243-245), Render guard (line 1975)
🎛️ AMYboard HW CIDispatched this PR's |
🎛️ HW CI (physical bench)Built from this AMY PR, pinned into the tulipcc AMYboard (USB-MIDI + AMY Tulip (TULIP4_R11; serial-REPL audio + WiFi screenshot): ✅ PASS — flashed this PR’s firmware; all checks matched the references. ⬇️ Artifacts: recordings · screenshot · serial logs · run logs Self-hosted bench. Audio spectral-compared to |
Bug:
init_stereo_reverb()allocates 10 delay lines but returnsvoid, so a partialallocation failure is silently ignored. The idempotency guard at the top of the
function checks only rev->delay_1: if delay_1 succeeds but any later line fails,
rev->delay_1is non-NULL on all subsequent calls, so the half-initialised structis never repaired.
config_reverb()then sets reverb.level unconditionally, andthe render guard in
amy_fill_bufferchecks onlyreverb.level > 0— sostereo_reverb()runs and dereferences aNULLdelay-line pointer, guaranteed crash.Echo already has the correct guard
(echo_delay_lines[0] != NULL). This PR bringsreverb in line, adapted to the struct-based
reverb_params_t design:Allocator — returns bool, rolls back on failure:
config_echo — bails on allocation failure before committing level:
Render guard:
Fix:
init_stereo_reverb(reverb_params_t *rev)returnsbool. On any allocationfailure it calls the existing
deinit_stereo_reverb()to roll back all partialallocations (leaving every pointer
NULL) and returnsfalse.alloc_reverb_delay_lines()returnsbool, propagating the failure to its caller.config_reverb()forces level=0 and returns early on allocation failure insteadof committing a non-zero level against an uninitialised rev.
rev != NULL && rev->delay_1 != NULLas a final defenceagainst NULL deref (mirrors the echo pattern; delay_1 is the first line
allocated and the last freed, making it a reliable sentinel).
Behaviour is unchanged when allocation succeeds. The added render-path check is
two pointer comparisons per block.
Pardon me if I am missing something obvious and wasted anyones time.