Skip to content

RT-safety: per-block IIR coefficient allocation in AureateEngine::process() #22

Description

@yves-vogl

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions