K

Use the building blocks

Drop in a ready-made filter, delay, or other DSP part.

You don't have to build everything from raw math. Msh ships a kit of audio parts. The pattern is always the same: build it in prepare, use it in process. The full catalog is split across three pages: DSP blocks (filters, delays, dynamics), Synth blocks (oscillators, envelopes, voice allocation), and Helpers (smoothing, randomness, math).

A lowpass filter

let filter: Biquad;

prepare(sampleRate: f64, maxBlock: i32): void {
  filter = new Biquad();
  filter.lowpass(800, 0.707, sampleRate as f32);
}

process(ctx: Ctx): void {
  for (let i = 0; i < ctx.n; i++) {
    ctx.output(0, i, filter.process(ctx.input(0, i)));
  }
}

Same shape for a Delay, an Envelope, an Oscillator, the rest of the kit.

Warning

Build these in prepare, never in process. Creating one reserves memory, which isn't allowed on the audio thread. Why.

Smooth a jumpy value

A knob value that jumps can click. Glide it:

let cutoff: Smoother;

prepare(sampleRate: f64, maxBlock: i32): void {
  cutoff = new Smoother(sampleRate as f32, 5); // 5 ms
}

process(ctx: Ctx): void {
  for (let i = 0; i < ctx.n; i++) {
    const hz = cutoff.process(ctx.modulatedParam(0, i));
  }
}

In tight loops, use Mathf (Mathf.sin, Mathf.sqrt) and cast literals with <f32>0.5 to keep the math fast.