Audio-thread ownership and control handoff¶
The main thread can allocate, parse JSON, enumerate devices and prepare coefficients. The audio owner must process already-prepared data without allocation, deallocation, blocking or I/O. These are implementation obligations, not guarantees conferred by a Rust type alone.
Prepare data before sending it¶
SynthPatch::new validates controls and constructs a fixed 256-entry filter table on the control thread. The callback receives a prepared patch, rather than computing logarithms, exponentials and filter coefficients for each sample. Patches contain fixed storage; dropping a command in the callback does not drop a heap-owned table.
The live audio adapter uses a 16-command SPSC queue. The UI owns the producer and the audio owner owns the consumer. Command carries prepared synth patches, delay values, a demo switch or a validated short MIDI message.
Bound work and handle overflow¶
Each callback consumes at most 16 control commands and makes at most 64 native MIDI polling attempts across no more than 16 inputs. Each native MIDI input uses 256 packet slots. A full queue is a correctness condition: losing note-off messages can leave notes held indefinitely.
The example requests a panic/reset on control overflow. Detected native packet loss clears voice state and drains bounded pending packets. This avoids pretending every packet was delivered and gives the UI an explicit error it can present.
Publish telemetry without sharing mutable DSP¶
ravet_foundation::SnapshotMailbox transfers coherent fixed-size word snapshots. The example publishes an 80-word record containing a frame counter, four peak/RMS readings, a drop counter and up to eight voice records. Float values are transferred using their bit representation; a UI snapshot reconstructs them with f32::from_bits.
A failed try_read leaves the previous displayed snapshot usable. A failed try_publish does not justify blocking the callback. Do not use this mechanism as a replacement for ordered event delivery: it communicates the latest coherent state, not every intermediate change.
Stop before changing ownership¶
Device replacement, format changes and teardown belong outside running callbacks. The UI pauses and releases the stream, closes MIDI inputs, drops the producer and resets telemetry before creating another audio owner. Native UI message flow follows that sequence in detail.