โŒ˜K

DSP blocks

The catalog of ready-made audio DSP parts, built in prepare.

These are native audio parts you build once in prepare and drive in process. Creation allocates on the host; process only indexes a handle, so it stays real-time safe. For the how-to, see Use the building blocks.

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

Warning

Build stateful blocks in prepare, not process. The why is worth a read.

The catalog

CategoryBlocks
Filters and EQBiquad, Svf, OnePole, TptSvf, Ladder, Allpass, DcBlock, Comb, TiltEq, Butterworth, Lr4Crossover
DelayDelay, Comb
Shaping and driveWavefolder, Oversampler, and the helpers softClip, hardClip, tanhFast
PitchPitchShifter, Formant, Hilbert
GranularGrainCloud (grain cloud over an AudioBuffer)
SpectralSpectral, Fft
ConvolutionConvolver
RecordAudioBuffer, decodeWav / WavAudio (load a WAV to planar f32)
StereoMidSide, panGainL / panGainR (equal-power pan)
SmoothingSmoother, Slew

Oscillators, envelopes, LFOs, meters, and random sources live in Synth blocks. Pure math, curve, easing, and mixing helpers live in Helpers.

Common signatures

The ones you'll reach for most. Construct with the sample rate where shown.

BlockBuildUse
Biquadnew Biquad()filter.lowpass(hz, q, sr) (or highpass, bandpass, notch, peaking, lowShelf, highShelf, allpass), then process(x).
Delaynew Delay(maxSamples)write(x) then read(delaySamples) (fractional, interpolated).
Laddernew Ladder(sr)process(x, cutoffHz, resonance, drive). Moog-style 4-pole, can self-oscillate.
Wavefoldernew Wavefolder()setFolds(folds) (1..8), then process(x). Antialiased.
Convolvernew Convolver(blockSize, capacity, sr)setIr(irLPtr, irRPtr, len) in prepare, then process(ctx) per block. Latency is blockSize.
Spectralnew Spectral(fftSize, channels, maxBlock)process(ctx) per block; edit the spectrum in processSpectrum(frame, ctx). Latency is fftSize.

Filters and EQ

BlockBuildUse
Biquadnew Biquad()set(BiquadMode, freq, q, gainDb, sr) or a named helper; process(x).
Svfnew Svf()set(SvfMode, cutoffHz, resonance, sr), process(x). Zero-delay-feedback, modulate freely.
OnePolenew OnePole()lowpass(hz, sr) / highpass(hz, sr), process(x).
TptSvfnew TptSvf()process(x, cutoff, reso, sr, TptSvfMode.Lowpass). Coefficients derived per call.
Allpassnew Allpass()set(freqHz, sr), process(x). First-order phase rotation.
DcBlocknew DcBlock(sr, cutoffHz?)process(x). 1-pole highpass; pass a low cutoff (e.g. 10 Hz).
Combnew Comb(maxDelaySamples)process(x, delaySamples, gain). Feedback comb with a modulatable fractional delay.
TiltEqnew TiltEq(sr, pivotHz)set(tilt), process(x). One control tilts the spectrum around the pivot.
Butterworthnew Butterworth()set(freqHz, slopeDbPerOct, sr, ButterworthType.Lowpass), process(x).
Lr4Crossovernew Lr4Crossover()setCutoff(hz, sr), process(ch, x) returns the low band, high() the high. Phase-coherent 2-band split.

BiquadMode: Lowpass, Highpass, Bandpass, Notch, Peaking, LowShelf, HighShelf, Allpass. SvfMode: Off, Lowpass, Lowpass4, Bandpass, Bandpass4, Highpass, Highpass4, Notch. TptSvfMode: Lowpass, Bandpass, Highpass. ButterworthType: Lowpass, Highpass.

Shaping and drive

BlockBuildUse
Wavefoldernew Wavefolder()setFolds(folds) (1..8), process(x). Antialiased Buchla-style folding.
Oversamplernew Oversampler(factor, maxBlock)Per channel each block: upsample(ctx.inPtr(ch), n), shape buffer() in place, downsample(ctx.outPtr(ch), n). Report latency().

The pure shapers softClip(x), hardClip(x), and tanhFast(x) are in Helpers.

Pitch

BlockBuildUse
PitchShifternew PitchShifter(sr, maxGrainSeconds)process(x, semitones, grainSeconds, feedback?, readOffset?). Granular.
TimeStretchernew TimeStretcher(sr, channels?, maxSeconds?, windowMs?)WSOLA time-stretch over live input: write(ctx, chBase) to feed, setSpeed(0.25..4) (1 = realtime, pitch unchanged), setPitch(0.5..2) (independent of speed), processInto(outL, outR, len) to render. Segments align by waveform similarity, so transients don't phase; stereo stays coherent. latencySamples() via m.latency. maxSeconds is the input history a slow stretch can trail behind.
Formantnew Formant(sr)set(vowelPos, shiftSemitones, qScale?), process(l, r) returns left, right() the right.
Hilbertnew Hilbert()process(x) returns the in-phase part, imag() the quadrature. Build a frequency shifter / SSB.

Delay and convolution

BlockBuildUse
Delaynew Delay(maxSamples)write(x), read(delaySamples) (fractional). Size for the longest delay.
Convolvernew Convolver(blockSize, capacity, sr)setIr(irLPtr, irRPtr, len) in prepare, process(ctx) per block. Latency is blockSize: report m.latency(blockSize).

Spectral

Spectral is a fixed-hop WOLA STFT processor (it can pitch-shift but not time-stretch). Fft hands you the raw transform so you own the windowing, hop, and phase (build a variable-hop phase vocoder, e.g. time-stretch from an AudioBuffer).

BlockBuildUse
Spectralnew Spectral(fftSize, channels, maxBlock, overlap?, window?, sidechainChannels?)process(ctx) per block, edit bins in processSpectrum(frame, ctx). hopSize(). Latency is fftSize.
Spectral transformssetFreeze(amount), setWarp(ratio), setShift(bins)Host-side phase-vocoder ops applied to each frame before processSpectrum sees it. Freeze captures a frame on leaving 0 and sustains it phase-coherently (an infinite, non-looping hold); warp pitch-scales bins (ratio 0.25 to 4); shift translates every partial by fractional bins (bins = hz * fftSize / sampleRate), turning harmonic material inharmonic. Call from process, not from processSpectrum.
Fftnew Fft(size)forward(input, spectrum) (no window applied), inverse(spectrum, output) (normalized). bins(), size().

fftSize and Fft's size are rounded up to a power of two. Size time-domain buffers to Fft.size(), and spectrum buffers to Fft.bins() * 2 (interleaved re, im). SpectralWindow: Hann, SqrtHann. For the full walkthrough including sidechain vocoding, see Process a spectrum.

Record

BlockBuildUse
AudioBuffernew AudioBuffer(maxFrames, channels?)push(l, r?) to record, read(ch, fractionalFrame) for cubic-interpolated playback; at, set, length, reset.

Smoothing

BlockBuildUse
Smoothernew Smoother(sr, timeMs?, initial?)process(target) glides toward the latest target; reset(v), value(). The standard zipper-noise fix.
Slewnew Slew(riseRate?, fallRate?, initial?)process(target) bounds the per-sample change; setRates(rise, fall), reset(v).