# Strudel Syntax Reference Complete reference for the Strudel live coding language (strudel.cc). ## 1. Tempo & Timing ```js setcps(BPM/60/4) // cycles per second — PREFERRED method setcpm(BPM/4) // cycles per minute — alternative // Default: 0.5 cps = 120 BPM = 1 cycle every 2 seconds ``` BPM to CPS conversion: `cps = BPM / 60 / 4` (assuming 4 beats per cycle). ## 2. Mini-Notation (Pattern Language) Used inside quotes in functions like `sound("...")`, `note("...")`, `n("...")`. ### Sequencing | Syntax | Meaning | Example | |--------|---------|---------| | `a b c` | Sequence (space-separated) | `sound("bd sd hh")` | | `[a b]` | Sub-sequence (squish into parent slot) | `sound("bd [hh hh] sd hh")` | | `a , b` | Play in parallel (polyrhythm) | `sound("bd sd, hh*4")` | | `< a b >` | Alternate: one per cycle | `sound("")` | | `~` or `-` | Rest / silence | `sound("bd ~ sd ~")` | ### Speed & Duration | Syntax | Meaning | Example | |--------|---------|---------| | `a*N` | Repeat N times (speed up) | `sound("hh*16")` — 16 hi-hats per cycle | | `a/N` | Slow down by factor N | `note("[c e g b]/2")` — over 2 cycles | | `a@N` | Elongate: take N time units | `note("c@3 e")` — c is 3/4, e is 1/4 | | `a!N` | Replicate N times (copy) | `note("c!3 e")` — c c c e | ### Sample Selection | Syntax | Meaning | Example | |--------|---------|---------| | `name:N` | Sample number N | `sound("bd:0 bd:1 bd:2")` | ### Advanced Mini-Notation | Syntax | Meaning | Example | |--------|---------|---------| | `a?` | 50% chance of playing | `sound("hh hh? hh hh?")` | | `a?0.3` | 30% chance of playing | `sound("hh?0.3")` | | `{a b c}%N` | Euclidean rhythm | `sound("{bd bd bd}%8")` | ## 3. Core Functions ### Sound Sources ```js sound("bd sd hh cp") // play samples by name (alias: s) note("c3 e3 g3 b3") // play pitched notes (letter or MIDI number) n("0 2 4 6") // play by index (useful with .scale()) ``` ### Sound Selection ```js .sound("piano") // set instrument/sample .s("piano") // shorthand for .sound() .bank("RolandTR909") // select drum machine bank .n("0 1 2 3") // sample number within a sound ``` ### Drum Sound Names `bd` (bass drum), `sd` (snare), `hh` (hi-hat closed), `oh` (open hi-hat), `cp` (clap), `rim` (rimshot), `lt` (low tom), `mt` (mid tom), `ht` (high tom), `rd` (ride), `cr` (crash) ### Drum Machine Banks `RolandTR808`, `RolandTR909`, `RolandTR707`, `RolandTR505`, `RolandCompurhythm1000`, `AkaiLinn`, `RhythmAce`, `ViscoSpaceDrum`, `CasioRZ1` ### Synth Waveforms (use as sound name) `sawtooth`, `square`, `triangle`, `sine`, `white`, `pink`, `brown` ### GM Instrument Sounds (selection) `piano`, `gm_electric_guitar_muted`, `gm_acoustic_bass`, `gm_synth_bass_1`, `gm_synth_bass_2`, `gm_voice_oohs`, `gm_blown_bottle`, `gm_synth_strings_1`, `gm_synth_strings_2`, `gm_xylophone`, `gm_accordion`, `gm_electric_piano_1` ## 4. Effects ### Filter ```js .lpf(800) // low-pass filter cutoff in Hz .hpf(200) // high-pass filter cutoff in Hz .bpf(1000) // band-pass filter .lpq(5) // filter resonance (Q) — higher = more resonant .vowel("a e i o") // vowel formant filter ``` ### Amplitude ```js .gain(0.8) // volume 0-1+ .velocity(0.7) // MIDI-style velocity ``` ### Envelope (ADSR) ```js .attack(0.1) // fade in time (seconds) .decay(0.2) // fade to sustain time .sustain(0.5) // sustain level 0-1 .release(0.3) // fade out time after note ends .adsr(".1:.2:.5:.3") // shorthand: attack:decay:sustain:release ``` ### Space ```js .room(0.5) // reverb amount 0-1+ .size(0.9) // reverb room size 0-1 .delay(0.5) // delay amount 0-1 .delaytime(0.25) // delay time in seconds (or pattern) .delayfeedback(0.5) // delay feedback 0-1 .pan(0.5) // stereo position 0=left, 0.5=center, 1=right ``` ### Playback ```js .speed(2) // playback speed (negative = reverse) .begin(0.25) // start position in sample 0-1 .end(0.75) // end position in sample 0-1 .cut(1) // cut group — stops previous sound in same group .loop(1) // loop the sample ``` ### Distortion & Character ```js .distort(0.5) // distortion amount .crush(8) // bit crush (lower = crunchier) .coarse(8) // sample rate reduction .shape(0.5) // waveshaping distortion ``` ## 5. Signals (Continuous Modulation) Signals produce smooth continuous values for automating parameters. ```js sine // smooth wave 0-1 saw // ramp up 0-1 tri // triangle 0-1 square // on/off 0-1 cosine // cosine wave 0-1 rand // random values perlin // smooth random (Perlin noise) ``` ### Signal Modifiers ```js sine.range(200, 2000) // remap to range sine.range(200, 2000).slow(4) // slow down the LFO sine.range(200, 2000).fast(2) // speed up the LFO sine.segment(8) // quantize to 8 steps ``` ### Usage ```js .lpf(sine.range(300, 3000).slow(4)) // sweeping filter .gain(sine.range(0.2, 0.8)) // pulsing volume .pan(sine.range(0, 1).slow(2)) // auto-pan ``` ## 6. Pattern Manipulation Functions ### Time ```js .fast(2) // speed up pattern 2x .slow(2) // slow down pattern 2x .early(0.25) // shift pattern earlier by 1/4 cycle .late(0.25) // shift pattern later ``` ### Structural ```js .rev() // reverse the pattern .palindrome() // play forward then backward .ply(2) // repeat each event N times .chop(8) // chop each sample into N pieces .striate(8) // similar to chop but interleaved ``` ### Conditional ```js .every(4, x => x.rev()) // apply every 4th cycle .every(3, x => x.fast(2)) // double speed every 3rd cycle .sometimes(x => x.speed(2)) // 50% chance .sometimesBy(0.3, x => x.rev()) // 30% chance .when(x => x % 2 === 0, x => x.rev()) // conditional ``` ### Combination ```js .jux(rev) // play original left, modified right .off(1/8, x => x.add(7)) // offset copy + modify .add(2) // add to note values .sub(1) // subtract from note values ``` ### Stacking Patterns ```js // Method 1: $: prefix (PREFERRED for multi-pattern) $: sound("bd sd") $: note("c3 e3 g3") // Method 2: stack() function (single expression) stack( sound("bd sd"), note("c3 e3 g3") ) // Method 3: comma in mini-notation (within one function) sound("bd sd, hh*8") ``` ## 7. Scales & Tonal System ```js n("0 2 4 6").scale("C:minor") // scale degrees n("0 2 4 6").scale("C4:minor") // with octave n("0 2 4 6").scale("/4") // changing scales ``` ### Available Scales `major`, `minor`, `dorian`, `phrygian`, `lydian`, `mixolydian`, `locrian`, `minor:pentatonic`, `major:pentatonic`, `blues`, `chromatic`, `harmonicMinor`, `melodicMinor`, `whole`, `diminished` ### Voicings (Chord Shorthand) ```js voicing("").sound("piano") ``` ## 8. Sample Loading ```js samples('github:tidalcycles/dirt-samples') // load from GitHub samples({ mySound: ['url1.wav', 'url2.wav'] }) // custom ``` ## 9. Muting & Soloing ```js $: sound("bd sd") // playing _$: sound("hh*8") // muted (prefix with _) // .hush() // append to mute one pattern // hush() // global mute ``` ## 10. Variables & JavaScript Strudel is JavaScript — you can use variables, functions, arrays: ```js const drums = s("bd sd [~ bd] sd").bank("RolandTR909") const hats = s("hh*8").bank("RolandTR909").gain(0.3) const bass = note("c2 ~ c2 ~ eb2 ~ g1 ~").sound("sawtooth").lpf(600) $: drums $: hats $: bass ```