Effects
A synth sends some of its sound to an effect with one word.
const lead = makeSynth("lead")
lead.echo = 0.4 // repeats that die away
lead.reverb = 0.3 // the sound of a room
lead.chorus = 0.5 // a thicker, moving sound
function onMouseDown() {
lead.play("E4", 0.3)
}Each goes from 0 (none) to 1. A sample is a synth, so it has them too.
Shaping the echo, the reverb and the chorus
The echo, the reverb and the chorus are shared by every synth. Each synth says how much of itself goes to them, and setEffects shapes them for all:
setEffects({ echoTime: 0.3, echoFeedback: 0.5, echoBounce: true, reverbType: "hall", reverbSize: 0.8 })| JavaScript | Python | What it is |
|---|---|---|
echoTime | echo_time | Seconds between echoes |
echoFeedback | echo_feedback | How much each echo feeds the next (0 to 0.95) |
echoTone | echo_tone | How much treble survives |
echoBounce | echo_bounce | Whether the echoes bounce left and right |
reverbType | reverb_type | What kind of space the reverb is: one of the five below |
reverbSize | reverb_size | How big the space is (0 to 1). Bigger also rings longer |
reverbDamping | reverb_damping | How soon its treble dies |
reverbDecay | reverb_decay | How many seconds the tail takes to die away. 0 leaves it to the type and the size |
reverbPredelay | reverb_predelay | A gap before the reverb begins, up to 0.2 seconds, which keeps a sound clear of its own reverb |
reverbLowCut | reverb_low_cut | For fine tuning: bass below this many Hz is kept out of the reverb, so that it does not turn to mud (120 to begin with) |
reverbLevel | reverb_level | How loud the reverb comes back, for everything sent to it (1 is as it comes) |
echoLevel | echo_level | How loud the echo comes back |
chorusRate | chorus_rate | How fast the chorus wobbles |
chorusDepth | chorus_depth | How far it wobbles |
An echo in time with the music is a number of beats:
setTempo(104)
setEffects({ echoTime: beats(0.75), echoFeedback: 0.4 })The kinds of reverb
The reverb is a space the sound is in, and there are five to choose from:
reverbType | What it sounds like |
|---|---|
"room" | A small room: a short, soft tail of about a second. The one to begin with |
"hall" | A concert hall: big, smooth and warm, about two and a half seconds. Good for pads, strings and bells |
"plate" | A big sheet of metal, as recording studios used: bright, and thick from the first moment. Good on drums and voices |
"cathedral" | Enormous: it swells slowly and goes on and on, six seconds and more |
"spring" | The spring in a guitar amp: it twangs, and boings on anything sudden |
const pad = makeSynth("pad")
pad.reverb = 0.6 // how much of the pad goes to the reverb
setEffects({ reverbType: "hall" })
function onMouseDown() {
pad.play("Cmaj7", 1.5)
}The reverb is one room that every synth sends into, so its type and its shape are one setting for everything. lead.reverbType = "hall" and setEffects({ reverbType: "hall" }) do the same thing, and every synth reads the same value back. A synth's own part is how much it sends: lead.reverb.
No ready-made synth changes the type, because that would change it for all the others. The pad, the strings and the bell send to whatever room there is, and sound grander when you choose "hall".
With dials the type is a control like any other, and the knob clicks round the five names:
const lead = makeSynth("lead")
lead.reverb = 0.5
rotary("reverb", lead, "reverbType")
dial("size", lead, "reverbSize")
keyboard(lead)Grit
Two effects belong to the synth alone:
const bass = makeSynth("bass")
bass.distortion = 0.6 // grit, from 0 to 1
bass.crush = 6 // the bits each sample keeps: 16 is clean, 4 is an old games consoleMovement
A wobble is an effect too, and is a setting of the synth:
| Setting | What it does |
|---|---|
vibrato | A wobble of pitch, in semitones. vibratoRate is how fast and vibratoDelay how long before it begins |
tremolo | A wobble of loudness (0 to 1) |
wobble | A wobble of the filter, in semitones. wobbleRate is how fast |
pwm | The width of a "pulse" or "square" wave moving in and out (0 to 1): a thick, shifting sound. pwmRate is how fast, and is the same speed as wobbleRate |
autopan | The sound moves from side to side (0 to 1) |
The trance gate
A trance gate turns a synth's sound up and down in a pattern of steps, in time with the tempo, so a held chord becomes a rhythm. It chops whatever the synth is playing.
setTempo(138)
const pad = makeSynth("pad", { echo: 0.3 })
pad.tranceGate = "x.x.xx.x" // x is open, . is closed; a step is a sixteenth
let held = null
function onMouseDown() {
if (held) held.stop()
held = pad.start(["A3", "C4", "E4"])
}The pattern can be given three ways, and reads back as its text:
| Given | What it is |
|---|---|
| Text | x is a step that is open and . one that is closed. A digit from 0 to 9 is a step part of the way open, so "2468" swells |
| A name | "eighths", "offbeat", "gallop", "trance", "stutter", "pump", "triplets" (with tranceGateRate 6) or "dotted" |
| A list | Levels from 0 to 1, one a step |
"off" | Takes the gate away |
Its settings are settings of the synth, so a dial can be tied to each:
| JavaScript | Python | What it is |
|---|---|---|
tranceGateRate | trance_gate_rate | Steps to a beat: 4 is sixteenths, 2 eighths, 3 and 6 triplets |
tranceGateDepth | trance_gate_depth | How far a closed step closes: 1 is silence, 0.5 is half. Giving a pattern makes it 1 |
tranceGateSmooth | trance_gate_smooth | Seconds from one level to the next. Longer is softer |
tranceGateSwing | trance_gate_swing | Every second step that much of a step late |
tranceGateStereo | trance_gate_stereo | Left and right by turns |
tranceGateSends | trance_gate_sends | false: the echo and the reverb are fed the sound before it is chopped, so they ring through the gaps |
A pattern and its settings can be said in one line with setTranceGate, which takes rate, depth, smooth, swing, stereo and sends. The rate may be a note length there:
const pad = makeSynth("pad")
pad.setTranceGate("x.x.xx.x", { rate: "eighth", depth: 0.8, smooth: 0.02 })The steps begin at setTempo: call it where the bar begins and the gate is on the beat. pad.tranceGateStep() is the step that is sounding, for drawing it (trance_gate_step()).
The word gate alone is something else twice over: an arpeggio's gate is how long each of its notes is held, and the microphone's mic.gate is its noise gate.