K

Why process must stay fast

Where the audio-thread rules come from.

process has a few firm rules. They feel arbitrary until you see where they come from, and they all come from one fact: audio runs on a deadline.

Audio runs on a clock

Sound is a stream of tiny samples, tens of thousands a second, and they have to come out on time. Msh hands you a slice and needs the finished audio back before the next one is due. Miss that deadline, even once, and you don't get a slow device, you get a click or a dropout. There's no "a little late is fine" in audio.

So process can't do slow things

To always hit the deadline, process avoids anything that might take an unknown amount of time:

  • No asking for new memory. Reserving memory can stall. So no building filters, buffers, or arrays in here.
  • No waiting. No disk, no network, no locks.
  • No open-ended loops. Every loop finishes in a known number of steps.

That's what prepare is for

prepare runs before audio starts, off the clock, so it can do the heavy setup: build your filters, allocate your buffers, do the math you only need once. Then process just uses what prepare made. The whole pattern: build it once in prepare, use it in process.

One sharp edge: array bounds

For speed, finished devices are compiled with array bounds checks stripped out. Read or write past the end of an array and it's not caught, it quietly corrupts memory. So:

  • Size buffers once in prepare (a StaticArray of a fixed length).
  • Keep every loop inside sizes you control: ctx.n, ctx.inChannels(), a length you set yourself.

The safety net

You won't take down Msh by getting this wrong. If process runs away, Msh traps it, mutes that one device, and tells you. The rules keep your audio clean; the net keeps your mistakes cheap.