AUDIO
Source snapshot · 12 October 2026

Building an audio processor

A processor owns the mutable state that changes while samples are rendered. It does not need to own a window, a device, a plug-in SDK or a file writer. Implement ravet_foundation::Processor and let a separate consumer supply blocks.

Choose the audio layout and limits

ravet_foundation::ProcessConfig describes sample rate, channel layout, maximum block size and bounded event storage. The caller creates a valid configuration; the processor still decides whether it supports that configuration. The example delay accepts mono/stereo effects at 8–192 kHz, at most 1,024 frames and 128 input events. The subtractive example accepts mono/stereo instruments with no audio inputs.

prepare is the place to allocate delay history, scratch buffers and tables. Clear the active configuration first: a failed preparation must not leave an earlier configuration apparently active. Store the new configuration only after all required resources are prepared. The callback must not race preparation or deactivation.

Implement the callback

Begin process by checking preparation and calling config.validate_block(block). Reject invalid layout, frame counts and event storage before changing DSP state. Product-specific constraints, such as a delay's physical parameter range, need an additional complete event preflight.

On rejection, call block.clear_outputs() and return ProcessStatus::Fault(error). This clears active audio and emitted events. Successful processing initializes every active output sample. Unknown valid event kinds may be ignored if the processor documents that policy.

Apply events for a frame before rendering that frame. Process same-frame events in their supplied order. A zero-frame block can carry offset-zero events: apply those without advancing an oscillator, smoother or envelope.

Reset and deactivate

reset clears signal history while keeping the prepared configuration and requested controls. It has the same callback restrictions as processing. The example delay clears its rings and snaps smoothers to their current targets; the synth clears voices, envelopes, filters and oscillator phases.

deactivate stops prepared processing and may release resources outside the callback. The two teaching processors reset and clear their configuration. Their conservative Tail::Infinite declarations do not mean samples are guaranteed to remain audible indefinitely.

Verify the contract

Use fixed expected samples, different block partitions and an invalid late event to check whole-block rejection. Measure both allocation and deallocation around repeated callbacks, reset and prepared control changes. A passing allocation test does not prove a real-time deadline or host compatibility.

Read the delay walkthrough and the synth walkthrough for complete implementations.