# engine module ## Owned files - Engine.h, Engine.cpp ## Rules - Own the voice pool, LFOs, wavetable library, FX rack, matrix and macros by value. - Bind APVTS pointers in `prepare()`; `v()` reads captured values without constructing parameter-name strings. - Build the `RenderContext` once per host block and refresh its modulation inputs for each render segment. - Render up to 64 samples at a time, splitting at MIDI event offsets and respecting prepared buffer capacity. - Size `mixBuffer` once in `prepare()`; use non-owning views for shorter segments. - Prebuild wavetables in the Engine constructor, before either GUI painting or audio rendering can read them. - Clamp the final output with the soft limiter. - Never call `setSize` on any buffer inside `processBlock`. ## IF-THEN - IF a per-block buffer is needed THEN allocate it in `prepare()` and clear it per block. - IF a module needs the matrix, macros or wavetables THEN go through Engine accessors rather than reaching into another module. ## Examples ```cpp // BAD: per-callback buffer reconfiguration on the audio thread void processBlock (...) { mixBuffer.setSize (2, n, false, false, true); ... } ``` ```cpp // GOOD: size once, then wrap a non-owning view per segment void prepare (double sr, int blockSize) { mixBuffer.setSize (2, blockSize, false, false, true); } void processBlock (...) { // No allocation; the view only borrows mixBuffer's channels. juce::AudioBuffer block (mixBuffer.getArrayOfWritePointers(), 2, segmentLength); block.clear(); ... } ``` This file overrides /AGENTS.md where they conflict.