# DSP library

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

Canonical: https://maru.audio/docs/dsp
Documentation index: https://maru.audio/llms.txt

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.

| Profiles | Import suffix | Controls and use |
| --- | --- | --- |
| De-Esser | `dynamics/stereo-de-esser` | Detector 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, Rectifier | `distortion/color-shaper` | Mode, 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 Hum | `noise/record-texture` | Crackle/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, Microshift | `spectral/delay-pitch-shifter` | Per-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 Filter | `delays/tap-pattern` | Mode 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 Delay | `delays/reverse-delay` | Window 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 Decoder | `stereo/width` | Encode 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 Divider | `distortion/octave-divider` | One/two-octave division, crossing hysteresis, tone, output trim. Envelope-scaled square subharmonic; chords and noisy crossings can mistrigger. |
| Jitter Reducer | `distortion/jitter-reducer` | Capture rate, seeded interval jitter, tone, output trim. Rate is bounded by the host rate; timing resolves to host samples. |
| Hall FDN | `reverbs/borrowed-hall-fdn` | Size, nominal decay 0.5–15 s, damping, diffusion. Eight-line algorithmic network using borrowed rings; not a measured room. |
| Rotary Speaker | `modulation/borrowed-rotary` | Rate, depth, width, horn balance. Two-band amplitude and delay modulation using borrowed rings; a stylized model. |
| Dispersive Spring | `reverbs/borrowed-spring` | Length, nominal decay 0.3–8 s, dispersion, damping. Borrowed rings and prepared allpass histories; a stylized spring, not a calibrated tank model. |
| Triode Stage | `distortion/triode-stage` | Drive, 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](https://maru.audio/docs/audio-sdk.md)
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](https://maru.audio/docs/how-it-works.md) introduces the module workflow;
[Check, build and export](https://maru.audio/docs/export.md) 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](https://maru.audio/docs/parity-and-determinism.md) describes the checks
used to compare repeatable scenarios across supported runtimes.
