Skip to content

Realtime Safety

"Real-time-safe" is the property that lets the same libsonare DSP run inside a live audio callback without glitching. It is not a feature you turn on — it is a set of rules the audio path must never break. This page explains those rules and how libsonare honors them; for the streaming APIs see Realtime and Streaming.

The audio callback has a deadline

Audio is delivered in blocks on a high-priority thread, and each block must be filled before the speaker needs it — often within a couple of milliseconds. Miss that deadline once and you get an audible click, pop, or dropout. So the callback has a hard real-time deadline, and anything that might take an unbounded amount of time is forbidden inside it.

A budget, and one block that overruns
one block period — one deadlineprocessheadroomallocation or lock waitoutputaudible click128 frames @ 48 kHz ≈ 2.7 ms
  • finished inside the deadline
  • ran past the deadline
  • block delivered to the device
Average speed is not the property that matters here. Every block has the same fixed budget, and normal blocks finish with headroom to spare — but a single wait on a mutex or an allocator blows through one deadline, the buffer is not ready, and the listener hears it. That is why the forbidden list is about operations whose cost is unbounded rather than operations that are merely slow.

What is forbidden in the callback

ForbiddenWhy it breaks audio
Memory allocation (new/malloc)Can block for an unpredictable time
Locks / mutexesCan stall waiting for another thread
File / network I/OUnbounded latency
Anything unboundedA single overrun misses the deadline

The discipline is: do all the slow work (allocation, file loading, setup) outside the callback, then let the callback only read and process pre-built buffers.

How libsonare stays safe

libsonare's realtime path follows the callback rules in a few concrete ways:

TechniqueWhy it matters
Pre-allocated buffersNo allocation happens per audio block
Lock-free parameter updatesUI changes do not stall the audio thread
Parameter smoothingControl changes do not click
Denormal guardsTiny floating-point tail values do not spike CPU

Together these let the same DSP code run offline and live.

The AudioWorklet

In the browser, real-time audio runs in an AudioWorklet. This is a dedicated audio-thread context separate from the main thread.

The intended pattern is:

  1. Prepare objects on the main thread.
  2. Move the prepared work into the AudioWorklet.
  3. Process blocks there without allocating.

The site runs this path SAB-free: it does not require SharedArrayBuffer, so it does not need special COOP/COEP headers.

How libsonare implements realtime safety

The mixer strips, buses, RealtimeEngine, and StreamAnalyzer share a real-time-safe core: pre-allocated buffers (including Mixer.createRealtimeBuffer() for per-block reuse), lock-free parameter changes, denormal guards, parameter smoothers for click-free moves, and plugin-delay compensation so parallel paths stay aligned. State that must cross threads is moved through lock-free channels and surfaced as telemetry rather than read directly. The same DSP therefore runs in offline rendering and inside a browser AudioWorklet without code changes.

Related: Realtime and Streaming, Streaming Analysis, Realtime Engine, Browser Local Processing