Summary
AureateEngine::process() recomputes several filters' IIR coefficients once per audio block via juce::dsp::IIR::Coefficients<float>::makeLowPass / makeHighShelf / makeLowShelf / makePeakFilter. Each of these JUCE factory methods heap-allocates a reference-counted Coefficients object internally (new inside the factory method) before the result is copied into the persistent filter state and the temporary is discarded.
This is a genuine per-block audio-thread allocation.
Scope
This is documented in the repo's CLAUDE.md (see the "Known pre-existing real-time-safety caveat" note) as pre-existing since v0.1.0, not introduced in v0.2.0. It affects:
warmthLowPass
tiltLowShelf
tiltHighShelf
hfTrimShelf
lfTrimShelf
headBumpPeak (added in v0.2.0, follows the same established — allocating — pattern as the others)
hissShelf is not affected: its coefficients are fixed and computed once in prepare(), so it does not add a per-block allocation.
Why it wasn't fixed in the v0.2.0 voicing pass
Per CLAUDE.md: fixing this would require a materially different filter-coefficient architecture (e.g. the ArrayCoefficients + applyBiquadCoefficients pattern used elsewhere in the suite, which avoids the JUCE factory-method heap allocation), which was out of scope for the v0.2.0 voicing brief. It was flagged there for a future real-time-safety hardening pass.
Proposed fix direction
Port the ArrayCoefficients + AllocationGuard-verified pattern already established in the suite (see e.g. Overture's Tight/Tone/Bite/Bite Tilt filters, issue-tracked in that repo) to the six filters above, replacing the JUCE factory-method allocations with a manual coefficient computation that writes into pre-allocated storage. Add/extend an AllocationTests.cpp-style guard so this doesn't regress silently in a future PR.
References
basilica-audio/Aureate CLAUDE.md, "Known pre-existing real-time-safety caveat" section.
Summary
AureateEngine::process()recomputes several filters' IIR coefficients once per audio block viajuce::dsp::IIR::Coefficients<float>::makeLowPass/makeHighShelf/makeLowShelf/makePeakFilter. Each of these JUCE factory methods heap-allocates a reference-countedCoefficientsobject internally (newinside the factory method) before the result is copied into the persistent filter state and the temporary is discarded.This is a genuine per-block audio-thread allocation.
Scope
This is documented in the repo's
CLAUDE.md(see the "Known pre-existing real-time-safety caveat" note) as pre-existing since v0.1.0, not introduced in v0.2.0. It affects:warmthLowPasstiltLowShelftiltHighShelfhfTrimShelflfTrimShelfheadBumpPeak(added in v0.2.0, follows the same established — allocating — pattern as the others)hissShelfis not affected: its coefficients are fixed and computed once inprepare(), so it does not add a per-block allocation.Why it wasn't fixed in the v0.2.0 voicing pass
Per
CLAUDE.md: fixing this would require a materially different filter-coefficient architecture (e.g. theArrayCoefficients+applyBiquadCoefficientspattern used elsewhere in the suite, which avoids the JUCE factory-method heap allocation), which was out of scope for the v0.2.0 voicing brief. It was flagged there for a future real-time-safety hardening pass.Proposed fix direction
Port the
ArrayCoefficients+AllocationGuard-verified pattern already established in the suite (see e.g. Overture'sTight/Tone/Bite/Bite Tiltfilters, issue-tracked in that repo) to the six filters above, replacing the JUCE factory-method allocations with a manual coefficient computation that writes into pre-allocated storage. Add/extend anAllocationTests.cpp-style guard so this doesn't regress silently in a future PR.References
basilica-audio/AureateCLAUDE.md, "Known pre-existing real-time-safety caveat" section.