Skip to content

fix: resolve review findings (audio-thread safety, robustness)#19

Merged
yves-vogl merged 5 commits into
mainfrom
fix/review-findings
Jul 16, 2026
Merged

fix: resolve review findings (audio-thread safety, robustness)#19
yves-vogl merged 5 commits into
mainfrom
fix/review-findings

Conversation

@yves-vogl

Copy link
Copy Markdown
Contributor

Summary

Fixes the two HIGH-severity audio-thread heap allocations found in the 2026-07-15 whole-repo review, plus adds the regression test that should have caught them.

Verification

Both fixes were verified against pinned JUCE 8.0.14 sources (juce_dsp/processors/juce_IIRFilter.cpp/.h, juce_IIRFilter_Impl.h): Coefficients<NumericType>::makeHighShelf/makeBandPass are return *new Coefficients(...), while ArrayCoefficients<NumericType>::makeHighShelf/makeBandPass return a stack std::array<float,6> with zero allocation. RealtimeCoefficients.h::applyBiquadCoefficients writes that array's values into the existing Coefficients object's raw storage, normalising by a0 the same way Coefficients::assignImpl does internally (juce_IIRFilter_Impl.h).

Locally, on this branch:

export CPM_SOURCE_CACHE="$HOME/.cache/CPM"
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build --target Tests Seraph_Standalone --parallel 3
ctest --test-dir build --output-on-failure

→ 31/31 tests pass (28 pre-existing + 3 new allocation tests). The full-chain allocation test was confirmed to fail before either DSP fix (64 allocations/32 blocks with both bugs present, 32 with only the Air bug remaining after the DeEsser fix) and pass at 0 after both.

Test plan

  • ctest --test-dir build --output-on-failure green (31/31) with both fixes applied
  • New allocation test confirmed red before the fixes, green after (verified commit-by-commit locally)
  • Existing 28 tests (null tests, sample-rate sweeps, robustness, state, latency) still green — no behavioural change, only the coefficient-write mechanism changed
  • CI (pluginval strictness 10 + auval, macOS + Windows) — not run locally per repo convention, will run on this PR

🤖 Generated with Claude Code

yves-vogl and others added 5 commits July 16, 2026 00:01
Add a global operator new/delete counting harness (TestAlloc::
AllocationGuard) plus a processBlock()-level regression test exercising
every DSP stage at once, since neither pluginval (--strictness-level 10)
nor auval (-strict) do allocation-instrumented profiling and none of the
existing 28 Catch2 tests had any allocation-counting mechanism.

This test currently fails (64 allocations across 32 blocks), catching the
two known audio-thread heap allocations fixed in the following commits.

Fixes #14
…pute

DeEsser::process() called Coefficients<float>::makeBandPass() every block
regardless of amount/bypass state, which juce_IIRFilter.cpp implements as
`return *new Coefficients(...)` - a heap alloc/dealloc pair on the audio
thread every block, violating this repo's RT-safety invariant.

Switch to ArrayCoefficients<float>::makeBandPass() (stack std::array, no
allocation) and write its values into the already-allocated
detectorCoefficients object in place via the new shared
RealtimeCoefficients.h helper - the same pattern already proven in sibling
plugin lancet's src/dsp/RealtimeCoefficients.h.

Fixes #13
SeraphEngine::process() called Coefficients<float>::makeHighShelf() every
block regardless of whether Air actually changed, which juce_IIRFilter.cpp
implements as `return *new Coefficients(...)` - a heap alloc/dealloc pair
on the audio thread every block, violating this repo's RT-safety
invariant.

Switch to ArrayCoefficients<float>::makeHighShelf() (stack std::array, no
allocation) and write its values into the already-allocated
airShelf.state object in place via RealtimeCoefficients.h, same as the
DeEsser fix in the previous commit.

With this, the full-chain regression test added for #14 goes green (0
allocations across 32 blocks, down from 64 before either fix).

Fixes #12
@yves-vogl
yves-vogl merged commit c9c22ce into main Jul 16, 2026
2 checks passed
@yves-vogl
yves-vogl deleted the fix/review-findings branch July 16, 2026 00:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment