DSP library

Reusable, prepared audio building blocks for filters, effects, synthesis, and analysis.

The maruaudio/dsp/... entries are the reusable signal-processing library behind modules and processors. It provides focused leaves with explicit state, configuration, per-sample processing, and reset behavior. A module composes the leaves it needs with the Audio SDK; it does not need a separate browser or native DSP implementation.

The library is designed for prepared realtime use. Allocate persistent state before processing, update controls through named setters, then tick the leaf in the audio callback. Product modules own their parameters, routing, presets, and user interface.

Effects

Filters and EQ

  • RBJ biquad filters and tone stages
  • State-variable responses
  • Parametric, three-band, and fixed-band EQ building blocks
  • Envelope and LFO filter composites
  • Bounded direct FIR convolution

Dynamics

  • Peak and RMS envelope followers
  • Keyed and linked stereo compression
  • Gates, hold behavior, and downward expansion
  • Transient shaping with mid and side balance
  • Lookahead limiting for products that declare its alignment
  • Linked de-essing with a detector-listen mode

Drive and destruction

  • Tone shaping and direct overdrive
  • Bitcrusher and Decimator reduction
  • Wavefolder and voiced drive stages
  • Oversampled waveshaping and Chebyshev shaping
  • Tape-style companding, flutter, bias, and head-bump stages
  • Hard clipping, asymmetric saturation, and half/full-wave rectification
  • Static triode-stage shaping and zero-crossing octave division
  • Seeded jittered sample-rate reduction

Delays

  • Bounded and fractional delay lines
  • Feedback and ping-pong delay structures
  • Saturated feedback and cross-feed stereo delay
  • Click-safe retuning and staged clearing primitives
  • Four-tap delay, windowed reverse delay, and damped comb filtering

Modulation

  • Chorus, flanger, phaser, tremolo, and vibrato
  • LFOs, glide, and bounded parameter slew helpers
  • Auto panning and stereo modulation utilities
  • Dual-carrier ring modulation
  • Dual-tap audio pitch shifting and stereo microshift
  • Two-band rotary-speaker modulation

Space, stereo, and spectral

  • Schroeder, Dattorro, and feedback delay network reverbs
  • Stereo width, panning, and stereo-to-mono utilities
  • Single-sideband frequency shifting
  • Bounded pitch shifting and channel vocoding primitives
  • Eight-line algorithmic hall and dispersive spring reverbs
  • Haas delay widening and explicit M/S encoding/decoding

Record textures and generators

  • Seeded record crackle and dust impulses
  • 50/60 Hz mains hum with a second harmonic and stereo phase

Effect APIs and operating limits

The following focused imports provide the 21 newer effect profiles. Paths are relative to maruaudio/dsp/; several profiles share one configurable leaf. These are available source APIs. A compiled release still needs qualification for its particular module, topology, host, and target.

ProfilesImport suffixControls and use
De-Esserdynamics/stereo-de-esserDetector frequency 2–16 kHz, range 0–24 dB, threshold −60–0 dBFS, and detector listen. Linked dynamic high shelf; no lookahead.
Hard Clipper, Asymmetric Saturator, Rectifierdistortion/color-shaperMode, drive 0–36 dB, ceiling/bias/half-or-full character, tone, output trim. Wet-only transfer functions with DC removal; hard edges can alias.
Record Crackle, Record Dust, Mains Humnoise/record-textureCrackle/dust: density 0–200 events/s, impulse amplitude 0–1, tone, spread. Hum: 50/60 Hz, amplitude 0–0.1, harmonic balance, phase. Outputs noise only; add it to the carrier.
Audio Pitch Shifter, Microshiftspectral/delay-pitch-shifterPer-channel semitone shift, window, extra delay, stereo phase. Microshift uses opposing small detunes. Borrowed delay rings; variable read delay, no formant preservation.
Multitap Delay, Haas Widener, Comb Filterdelays/tap-patternMode selects four geometric taps, one delayed channel, or a damped feedback comb. Their controls use different units. Borrowed delay rings; check Haas in mono.
Reverse Delaydelays/reverse-delayWindow 20–500 ms, feedback, edge fade, output trim. Plays a completed window backward while recording the next. Borrowed rings; fades attenuate splice edges.
M/S Encoder, M/S Decoderstereo/widthEncode M=(L+R)/2, S=(L−R)/2; decode L=M+S, R=M−S. No macros. Decode encoded M/S, and use full wet for the format transforms.
Octave Dividerdistortion/octave-dividerOne/two-octave division, crossing hysteresis, tone, output trim. Envelope-scaled square subharmonic; chords and noisy crossings can mistrigger.
Jitter Reducerdistortion/jitter-reducerCapture rate, seeded interval jitter, tone, output trim. Rate is bounded by the host rate; timing resolves to host samples.
Hall FDNreverbs/borrowed-hall-fdnSize, nominal decay 0.5–15 s, damping, diffusion. Eight-line algorithmic network using borrowed rings; not a measured room.
Rotary Speakermodulation/borrowed-rotaryRate, depth, width, horn balance. Two-band amplitude and delay modulation using borrowed rings; a stylized model.
Dispersive Springreverbs/borrowed-springLength, nominal decay 0.3–8 s, dispersion, damping. Borrowed rings and prepared allpass histories; a stylized spring, not a calibrated tank model.
Triode Stagedistortion/triode-stageDrive, negative bias magnitude, tone, output trim. Prepared static Koren transfer table; not a complete tube amplifier or dynamic circuit simulation.

A leaf's configuration functions take physical units. Multifx's four macros are normalized positions interpreted by the Audio SDK's Multifx effect-chain contract: use multifxMacroSpec and applyMultifxMacroLaw for that mapping, rather than passing a normalized knob value directly to a leaf's hertz or decibel argument. The contract also owns stable algorithm IDs, ranges, and menu audition settings. Presets and automation retain their supplied values; an explicit Multifx menu selection applies the chosen profile's audition settings and enables its slot.

Prepare borrowed rings before processing and size them for the selected algorithm. For example, the pitch leaf requires window + extra delay + two frames; the hall requires at least sampleRate + two frames per borrowed ring. Reset scalar state and clear the borrowed storage together. Full clears and resizing belong outside the realtime callback; use staged clearing for live transitions. The consumer owns dry/wet blending and output headroom.

Adding a record texture

This example prepares a seeded crackle generator, then adds its noise-only outputs to stereo input. The amplitude is an impulse scale, not a promised output peak or RMS level; measure the combined output before choosing a trim.

ts
import {
  RECORD_TEXTURE_CRACKLE,
  configureRecordTexture,
  initRecordTexture,
  recordTextureTick,
  resetRecordTexture,
} from "maruaudio/dsp/noise/record-texture"

// Preparation, outside the audio callback.
const texture = initRecordTexture(48_000, 12345)
configureRecordTexture(texture, RECORD_TEXTURE_CRACKLE, 100, 0.4, 8_000, 0.5)

// Inside the callback, once per stereo sample.
function processSample(
  left: number,
  right: number,
  outputLeft: Float32Array,
  outputRight: Float32Array,
  frame: number,
): void {
  recordTextureTick(texture)
  outputLeft[frame] = left + texture.outLeft
  outputRight[frame] = right + texture.outRight
}

// Restart the same seeded sequence when resetting the processor.
resetRecordTexture(texture)

Zero density stops new crackle/dust events; existing tails still decay. These generators intentionally produce sound on silent input when enabled. Dust uses a shorter impulse tail than crackle. Hum's configuration arguments use frequency, amplitude, harmonic fraction, and stereo-phase degrees instead of the crackle/dust argument units.

Synthesis and analysis

Synthesis and physical sound

  • Band-limited and variable-shape oscillators
  • ADSR and other envelope primitives
  • Modal resonators, mallets, strikes, and radiation stages
  • Deterministic noise and wavetable/sample readers

Analysis and composition

  • Streaming pitch detection
  • Deterministic MIDI timelines
  • One-to-six slot serial-effect scheduling
  • Control gain, level, mix, and decibel helpers

Use focused imports

Import the leaf your processor needs, initialize its state during preparation, and retain that state for the callback. A narrow import makes the dependency and the eventual compiled closure clear.

ts
import {
  BIQUAD_LOWPASS,
  biquadNodeTick,
  initBiquadNode,
  setBiquadNodeFrequency,
  setBiquadNodeQ,
  setBiquadNodeType,
  updateBiquadNodeCoefficients,
} from "maruaudio/dsp/filters/biquad"

const filter = initBiquadNode(48_000)
setBiquadNodeType(filter, BIQUAD_LOWPASS)
setBiquadNodeFrequency(filter, 2_400)
setBiquadNodeQ(filter, 0.7071)
updateBiquadNodeCoefficients(filter)

function process(input: number): number {
  return biquadNodeTick(filter, input)
}

Use the leaf documentation and exported bounds to choose valid parameter ranges. Stateful leaves also export reset functions. Prepared storage, clear behavior, and the product's dry/wet policy belong to the consumer.

From a leaf to a module

The DSP library supplies algorithms and controls. The Audio SDK supplies module declarations, ports, parameter schemas, saved state, and host activation. Use the module boundary for a musician-facing product and keep its DSP source in the module's processor implementation.

Many leaves can be tested directly in JavaScript and compiled as part of a Processor. How it works introduces the module workflow; Check, build and export explains how projects are built and verified for their supported targets.

Qualification is specific to a product and target

The presence of a reusable leaf does not promise that every composition is available in every host, has zero processing alignment, or matches a named commercial effect. A module chooses its topology and controls, then qualifies the selected source and target combination for audio quality, state, and realtime behavior.

Parity and determinism describes the checks used to compare repeatable scenarios across supported runtimes.