engines/kick.js — SynthKick

The kick drum synthesiser. Defined as a SynthEngine object with 7 modules.

Modules

The modules array defines both the UI panels (order, labels, params) and the signal chain (processor order).

1. Pitch (source)

Param Range Default Description
pitchStart 80–400 Hz 220 Initial oscillator frequency
pitchEnd 25–100 Hz 50 Final frequency after decay
pitchDecay 0.03–0.5 s 0.06055 Sweep duration
sineLevel 0–1 1 Sine oscillator level
triangleLevel 0–1 0 Triangle oscillator level
sawtoothLevel 0–1 0 Sawtooth oscillator level
pitchCurve exponential/linear exponential Contour of the frequency sweep
subMix 0–1 0.5 Sub oscillator (sine, octave down) blend

Creates the main oscillator with a frequency ramp (exponential or linear), a gain envelope, and an optional sub oscillator at half frequency.

2. Transient (source)

Param Range Default Description
noiseAmount 0–0.5 0.12 White noise burst volume
noiseDecay 0.003–0.08 s 0.015 Noise fade time
clickTone 200–2000 Hz 800 Pitched click frequency
clickMix 0–0.3 0.1 Click blend level

Generates a white noise buffer source and a sine oscillator click, both with exponential decay envelopes.

3. Distortion

Dynamic stage pipeline (see distortion.js).

4. Filter (processor)

Param Range Default Description
filterCut 200–20000 Hz 20000 Low-pass cutoff (bypassed at 20000)

BiquadFilter node with type: 'lowpass'. When cutoff is at maximum (20000 Hz), the filter bypasses (returns input unchanged).

5. Compressor (processor)

Param Range Default Description
compThreshold –60–0 dB –21.3 Compression threshold
compRatio 1–20 4 Compression ratio
compAttack 0.001–0.1 s 0.003 Attack time
compRelease 0.01–1.0 s 0.1 Release time

Wraps DynamicsCompressorNode with clamped parameter ranges. Wrapped in try/catch for browser compatibility — falls back to pass-through.

6. Volume (master)

Param Range Default Description
volAttack 0.001–0.1 s 0.002 Time to peak
volDecay 0.05–0.8 s 0.3 Time to sustain
volSustain 0–0.5 0.05 Post-decay level
volRelease 0.005–0.5 s 0.05 Fade to silence

Schedules linearRampToValueAtTime on the master gain node. Total duration: max(0.5, attack + decay + release + 0.1).

7. Normalize (builtin)

Param Default Description
normalize true Peak normalise to –0.5 dBFS after render

Signal Chain

osc + sub + noise + click
  → [distortion stages]
  → filter (lowpass)
  → compressor
  → master gain (ADSR volume)
  → destination

After rendering, normalize is applied to the PCM samples if enabled.

Canvas Visualisations

Three envelope canvases are rendered in a dedicated Envelopes card below the waveform:

Canvas ID Module Curve
env-pitch Pitch Exponential decay of frequency from start to end
env-volume Volume ADSR amplitude envelope
env-transient Transient Exponential decay of transient amplitude

Rendering

The render function creates source nodes (oscillator, sub, noise, click) and connects them to chainInput (the first distortion stage or master gain):

render(ctx, params, stages, chainInput, dur) {
  // Pitch oscillator + gain
  osc = ctx.createOscillator()
  schedulePitch(osc, params, dur)
  osc.connect(oscGain).connect(chainInput)

  // Sub oscillator (if subMix > 0)
  sub.connect(subGain).connect(chainInput)

  // Noise burst (if noiseAmount > 0)
  noiseBufferSource.connect(noiseGain).connect(chainInput)

  // Click tone (if clickMix > 0)
  click.connect(clickGain).connect(chainInput)
}

Defaults

Loaded from static/js/synth/presets/kick.json at startup, falling back to engine.defaults:

{
  "params": {
    "pitchStart": 220, "pitchEnd": 50, "pitchDecay": 0.06055,
    "sineLevel": 1, "triangleLevel": 0, "sawtoothLevel": 0,
    "pitchCurve": "linear", "subMix": 0.5,
    "noiseAmount": 0.12, "noiseDecay": 0.015,
    "clickTone": 800, "clickMix": 0.1,
    "filterCut": 20000,
    "volAttack": 0.002, "volDecay": 0.3, "volSustain": 0.05, "volRelease": 0.05,
    "compThreshold": -21.3, "compRatio": 4,
    "compAttack": 0.003, "compRelease": 0.1,
    "normalize": true
  },
  "stages": [{ "type": "softClip", "amount": 0.01 }]
}

Built-in Templates

Defined in static/js/synth/presets/templates/kick.json:

Template Description
None No constraints, params set to defaults
Sine Kick Sine wave, no compression, linear pitch, locked distortion
Hard Punch Sawtooth wave, subMix: 0.3, hardClip distortion
Sub Heavy Deep sub focus (subMix: 0.85), gentle saturation

Randomisation Ranges

Each module's randomise(param) function sets curated ranges. Locked params are skipped.

Section Param Range
Pitch Start 120–350 Hz
End 30–80 Hz
Decay 0.05–0.35 s
Sine/Triangle/Sawtooth each 0.3–1 (at least one non-zero)
Curve random: exponential / linear
Sub mix 0.2–0.8
Volume Attack 0.001–0.06 s
Decay 0.08–0.5 s
Sustain 0–0.25
Release 0.01–0.2 s
Transient Noise 0.03–0.4
Decay 0.004–0.06 s
Click tone 300–1500 Hz
Click mix 0.02–0.25
Filter Cutoff 300–18000 Hz (log)
Compressor Threshold –40 to –10 dB
Ratio 2–12
Attack 0.001–0.05 s
Release 0.02–0.5 s