distortion.js — Distortion Pipeline
Manages the multi-stage distortion pipeline: curve generation, stage CRUD, randomisation, chain wiring, and UI.
DISTORTION_TYPES
A map of nine drive types, each with a label:
| Key | Label |
|---|---|
off |
Off |
softClip |
Soft Clip |
hardClip |
Hard Clip |
tape |
Tape |
exponential |
Exponential |
tanh |
Tanh |
bitcrush |
Bitcrush |
wavefold |
Wavefold |
fullWaveRectify |
Full-wave Rectify |
distortionCurve(type, amount, len) → Float32Array
Generates a waveshaping curve for the given type. len is the curve resolution
(typically 4096). When type is 'off' or amount <= 0, returns the identity
curve. Valid for any type in DISTORTION_TYPES.
buildDistortionChain(ctx, stages, outputNode) → AudioNode
Wires active distortion stages (type !== 'off' && amount > 0) into the signal
chain in reverse order connecting to outputNode. Each active stage inserts a
pre-gain GainNode (if drive > 1) followed by a WaveShaperNode with the
curve for that stage. Returns the first stage's input node (or outputNode if
no active stages).
Stage format
{ type: 'softClip', amount: 0.3, drive: 2.5 }
| Field | Range | Default | Description |
|---|---|---|---|
type |
DISTORTION_TYPES key | softClip |
Waveshaper curve type |
amount |
0–1 | 0.3 | Curve intensity/character |
drive |
1–10 | 1 | Pre-gain amplification before the waveshaper |
Higher drive values push the signal harder into the waveshaper curve, producing more aggressive distortion. Drive = 1 passes the signal through at unity gain.
DistortionPipeline
Stateful class managing the stage array, lock state, and drive.
| Method | Description |
|---|---|
constructor(stages?) |
Creates pipeline; each stage is { type, amount, drive } |
add(type?, amount?) |
Appends a new stage (defaults: softClip, 0.3, drive 1) |
remove(index) |
Removes stage by index; no-op if out of range |
randomise() |
Mutates stages (type, amount 0.1–0.8, drive 1–5) respecting locks |
toJSON() |
Returns [{ type, amount, drive }, …] (no lock state) |
Lock model: Each stage has an independent boolean locked[i]. The
masterLocked flag overrides all stages — when true, randomise() is a no-op.
Randomise: 1. 50% chance each unlocked stage is removed 2. Remaining unlocked stages get random type + amount (0.1–0.8) + drive (1–5) 3. 0–2 new unlocked stages added 4. If empty after all operations, one random stage is added
buildDistortionUI(container, pipeline, onChange)
Builds (or rebuilds) the distortion card UI inside container. The card
includes:
- Header with title, master lock 🔓/🔒, randomise 🎲
- Per-stage cards, each containing:
- Row 1: Type pill buttons (clickable, active highlighted)
- Row 2: Drive slider (1–10× pre-gain)
- Row 3: Amount slider (0–1 curve intensity)
- Lock button, delete ✕
- "+ Add Stage" button
Calls onChange() after any mutation (type change, slider, add, remove,
randomise).