Skip to content

audio_callback.cssl — effect system showcase

Status: stub

Full audio callback walkthrough is planned for Phase 1 completion. This stub covers the key concepts.

The audio callback example shows Sigil’s effect system in a context where effect violations are not just bugs but timing catastrophes: real-time audio.

A real-time audio callback runs under hard timing constraints — typically 256–512 samples at 44.1kHz, which is a ~5ms budget. Any allocation, any I/O, any blocking operation within that callback causes an audible glitch.

In C++, there is nothing stopping you from calling malloc or printf from inside an audio callback. The callback type is just a function pointer — it has no information about its allowed effects. Runtime tools (like Dr. Dre or libAsanAudio) can detect the violation, but only after it causes a glitch in production.

// The audio system accepts callbacks with this exact type:
// fn(frame: &mut AudioFrame) !audio
//
// The !audio effect permits: buffer reads/writes, SIMD math, lock-free queues.
// The !audio effect forbids: !alloc, !io, !mutex (blocking locks), !panic.
//
// Any callback that touches forbidden effects is rejected at compile time.
fn process_audio(frame: &mut AudioFrame) !audio {
for sample in frame.iter_mut() {
*sample = oscillator.next_sample() * 0.5;
}
// If you add: println!("{}", frame.len());
// Compile error: !io is not allowed in !audio context
}

The !audio effect is a restricted effect — it’s a subset of what !io allows, with the allocation and blocking-I/O operations explicitly excluded.

Full example with:

  • Oscillator struct with lock-free parameter updates
  • Effect row diagram showing what !audio permits and forbids
  • Comparison with C++ equivalent showing the missing safety net

See §B.3 Effect System for the full effect system documentation.