engines/neuro.js — SynthNeuro

Sub and neurofunk bass synthesiser. Defined as a SynthEngine object with 13 modules. Dual detuned oscillators with FM routing, reese detune spread (1–8 voices), sub oscillator, noise injection, multi-mode filter with per-note ADSR envelope and LFO modulation, tempo-synced LFO, ADSR volume envelope, multi-stage distortion, OTT multiband compressor, dynamics compressor, and clarity processor.

Available standalone at /synth/neuro and as an engine in the sequencer.

Signal Flow

osc1 ──┐
osc2 ──┼── FM mix (osc2 → osc1.frequency) ──→ reese detune spread (1–8 voices)
       │                                              ↓
sub ───┘                                          filter (multi-mode)
noise ─┘                                              ↓
lfo → filter cutoff / volume / pitch / fm       distortion → OTT → clarity
                                                      ↓
                                                 compressor → masterGain (ADSR envelope)

Each note creates a per-trigger filter node and a per-trigger gain node to avoid scheduling conflicts between overlapping notes.

Modules

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

1. Osc (source)

Param Range Default Description
osc1Wave sawtooth/square/triangle/sine saw Oscillator 1 waveform
osc2Wave sawtooth/square/triangle/sine saw Oscillator 2 waveform
osc1Cents –100–100 ct 0 Osc 1 fine detune
osc2Cents –100–100 ct 0 Osc 2 fine detune
osc1Level 0–1 0.7 Osc 1 level
osc2Level 0–1 0.7 Osc 2 level
fmAmount 0–1 0 FM depth (osc2 → osc1 frequency, sqrt-scaled × 400)

Osc 2 modulates Osc 1's frequency at fmAmount^0.5 × 400 depth, creating classic neurofunk FM tones. Both oscillators run for the full note duration.

2. Reese (source)

Param Range Default Description
voiceCount 1–8 3 Number of detuned saw voices
detuneCents 0–50 ct 12 Max detune spread (half above, half below)
reeseMix 0–1 0.6 Reese voice mix level

Creates a thick "wall of sound" via multiple detuned sawtooth oscillators. Each voice is offset by (v / (voices-1) - 0.5) × 2 × detuneCents cents from the base frequency, producing the classic reese chord effect.

3. Sub (source)

Param Range Default Description
subWave sine/triangle sine Sub oscillator waveform
subLevel 0–1 0.5 Sub level
subOctave 1, 2 1 Octave divider (×1 = same, ×2 = octave below)

Clean sub oscillator at freq / subOctave. Pure sine or triangle for deep sub-bass foundations.

4. Noise (source)

Param Range Default Description
noiseLevel 0–1 0.03 White noise level

Per-note noise buffer for texture and transient grit.

5. Filter (source — handled manually in trigger)

Param Range Default Description
filterType lowpass/highpass/bandpass lowpass Filter mode
filterCut 20–20000 Hz 18000 Cutoff frequency
filterRes 0–1 0.3 Resonance (Q: 0.5–20)
envAmount 0–36 st 12 Envelope → cutoff modulation depth
lfoAmount 0–36 st 6 LFO → cutoff modulation depth

A per-trigger BiquadFilterNode is created for each note so overlapping notes don't conflict on the filter frequency AudioParam. The filter envelope opens on attack (peak = baseCut × 2^(envAmount/12)) and closes over attack + decay time.

LFO modulation adds baseCut × (2^(lfoAmt×lfoDepth/12) - 1) Hz (in semitones) to the cutoff frequency via AudioNode.connect(AudioParam).

6. LFO (source)

Param Range Default Description
lfoRate 0.1–20 Hz 2 Free-running LFO rate
lfoSync off/1/2/4/8/16 4 Tempo-synced division
lfoWave sine/triangle/sawtooth/square/sAndH sine LFO waveform
lfoTarget cutoff/volume/pitch/fm cutoff Modulation target
lfoDepth 0–1 0.5 LFO depth

When lfoSync is not 'off', the LFO rate is calculated as (tempo / 60) / division where tempo comes from params.tempo. Default tempo is 174 BPM standalone; sequencer passes this.bpm.

The LFO is per-trigger with start(time) and is stopped early by noteOff to prevent long tails (stopped at time + release + 0.5s).

7. Env (master)

Param Range Default Description
volAttack 0.001–1 s 0.005 Attack time
volDecay 0.01–0.5 s 0.08 Decay time
volSustain 0–1 0.6 Sustain level
volRelease 0.001–3 s 0.2 Release time

ADSR volume envelope applied to the per-trigger noteGain. In trigger() (sequencer mode) the full A→D→S→R is scheduled with auto-release. In noteOn() (keyboard mode) the envelope holds at sustain until noteOff() triggers the release ramp.

8. EQ (processor)

Standard 3-band EQ (same as other engines): lowshelf (250 Hz), peaking (1 kHz), highshelf (8 kHz), ±12 dB range.

9. Distortion

Standard multi-stage distortion card (same pattern as all other engines). 9 drive types, per-stage amount and drive controls.

10. OTT (processor)

Param Range Default Description
ottMode basic/adv basic Basic mode (depth only) vs advanced
ottDepth 0–1 0.4 Wet/dry mix
ottDown 0–1 0.7 Downward compression amount (adv)
ottUp 0–1 0.8 Upward compression amount (adv)
ottAttack 0.001–0.05 s 0.003 Compressor attack (adv)
ottRelease 0.01–0.5 s 0.08 Compressor release (adv)

Three-band multiband compressor (low ≤250 Hz, mid 250–4000 Hz, high ≥4000 Hz) with parallel upward + downward compression per band. Essential for the aggressive neurofunk sound.

11. Compressor (processor)

Param Range Default Description
compThreshold –60–0 dB –24 Threshold
compRatio 1–20 4 Ratio
compAttack 0.001–0.1 s 0.003 Attack
compRelease 0.01–1 s 0.1 Release

Standard dynamics compressor for final signal shaping.

12. Clarity (processor)

Dynamic mud (~350 Hz) + air (~4 kHz) reduction. Same module as used by kick, snare, hihat, and BIA Clone.

13. Normalize (builtin)

Param Type Default Description
normalize checkbox true Peak normalisation (target 0.944)

Dual Trigger Modes

The engine supports two distinct trigger patterns:

trigger(ctx, chain, params, time, velocity)

Used by the sequencer. Schedules the full ADSR envelope with auto-release:

t=0:           setValueAtTime(0)
t+attack:      linearRampToValueAtTime(1)
t+attack+decay: linearRampToValueAtTime(sustain)
t+dur-release: setValueAtTime(sustain)
t+dur:         linearRampToValueAtTime(0.001)

getDuration returns attack + decay + 0.5 + release + 0.1s.

noteOn(ctx, chain, params, time, velocity)

noteOff(ctx, chain, params, time)

Used by the standalone keyboard page. noteOn schedules A→D→S only and holds at sustain. noteOff schedules release:

cancelScheduledValues(now)
setValueAtTime(currentGain, now)
linearRampToValueAtTime(0.001, now + release)
setValueAtTime(0, now + release + 5ms)

LFO sources are also stopped at now + release + 0.5s to prevent long tails from still-running oscillators.

LFO Tempo Sync

When lfoSync is not 'off', the LFO rate is derived from params.tempo:

rate = (tempo / 60) / division
Sync Rate at 174 BPM Rate at 140 BPM
1 2.9 Hz 2.33 Hz
2 1.45 Hz 1.17 Hz
4 0.725 Hz 0.583 Hz
8 0.363 Hz 0.292 Hz
16 0.181 Hz 0.146 Hz

Standalone key press sets p.tempo = lfoBpm (default 174, adjustable via BPM input). The sequencer passes p.tempo = this.bpm.

Stereo and Mono

All processing is mono. The reese voices sum to mono. Stereo effects (reverb/delay in the sequencer) are applied post-engine on the strip bus.

Default Preset

The default preset produces a mid-range neuro bass with: - Dual sawtooth oscillators, slight detune (5ct on osc2) - FM modulation (30%) - 3-voice reese spread (12ct detune) - Sine sub at same octave (50% level) - Low-pass filter at 18 kHz with envelope (12 st) and LFO (6 st) modulation - OTT at 40% depth - Volume envelope: 5ms attack, 80ms decay, 60% sustain, 200ms release - SoftClip distortion at 30%

Dependencies

  • core.jsSAMPLE_RATE, randInRange, randInt, logRand
  • registry.jsregister()
  • modules/eq.js — EQ processor
  • modules/compressor.js — dynamics compressor
  • modules/ott.js — multiband OTT compressor
  • modules/clarity.js — mud/air reduction
  • distortion.jsbuildDistortionChain

Files

File Purpose
engines/neuro.js Engine definition (673 lines)
init-neuro.js Bootstrap with keyboard, noteOn/noteOff, BPM control, VU meter
templates/synth_neuro.html Standalone page with preset sidebar + piano keyboard
presets/neuro/default.json Factory default params
presets/neuro/manifest.json Built-in presets (empty)

See Also