# Strudel Live Coding Reference Complete reference for generating Strudel patterns, optimized for Techno, Modular, and House styles. ## 1. Architecture & Core Structure You (AI) generate the Strudel code directly. Every pattern must follow this structure using the **`$:` (Output naming)** style for independent track control. ### Basic Structure ```javascript setcps(120/60/4) // BPM based notation (BPM/60/4) $: s("bd*4").bank("tr909") $: s("- sd - sd").bank("tr909").gain(0.8) $: note("c2*8").s("sawtooth").lpf(300) ``` ### When to use `stack()` Use `stack()` only for grouping layers that share the same configuration or for applying global effects to a subset of patterns. ```javascript $: stack( s("bd*4"), s("- sd - sd"), s("hh*16") ).bank("tr909").room(0.5) // Shared reverb and bank ``` ## 2. Mini-Notation Syntax Every operator has specific meaning. ### Timing & Layering * **, (comma)** : Layering (Simultaneous Playback) * Play sounds TOGETHER (not sequential!) * `"bd,sd,hh"` = THREE sounds playing simultaneously * `"bd*4, - sd - sd, hh*8"` = THREE separate rhythm layers * *** (multiply)** : `"bd*4"` = 4 kicks per cycle * **- (dash) or ~ (tilde)** : Rest/Silence * **[] (subdivide)** : `"bd [hh hh]"` = kick then two fast hi-hats * **<> (rotate)** : `""` = one per cycle, rotating * **@ (elongate)** : `"bd@2 sd"` = kick twice as long as snare * **! (replicate)** : `"bd!3"` = three kicks same duration * **? (random)** : `"bd?0.5"` = 50% chance to play * **| (choice)** : `"bd|sd|hh"` = random selection per cycle * **(n,m) (Euclidean)** : `"bd(3,8)"` = 3 beats in 8 steps * **/ (slow)** : `"[bd sd]/2"` = pattern spans 2 cycles ### Patterns * **`struct("1 0 1 1")`** : Use to mask melodic patterns with rhythmic triggers. * **`iter(n)`** : Shifts the pattern every cycle. * **`scramble(n)`** : Randomizes subdivisions. ## 3. Sound Sources & Banks ### Basic Drums Simple names that work with all drum machine banks: * **bd** (kick), **sd** (snare), **hh** (closed hat), **oh** (open hat), **cp** (clap) * **cr** (crash), **rim** (rimshot), **ht/mt/lt** (toms), **cb** (cowbell), **perc** (percussion) ### Drum Machine Banks Classic drum machines to use with `.bank()`: * **Usage**: `s("bd*4, - sd - sd, hh*8").bank("tr808")` * **Techno/House**: `tr909`, `tr808`, `tr606`, `tr707`, `tr727` * **Vintage/Pop**: `linn`, `linnlm1`, `linnlm2`, `akailinn`, `dmx` * **Beatmaking**: `mpc60`, `sp12`, `rx5`, `bossdr55`, `bossdr110`, `bossdr550` ### Synth Waveforms & Noise * **Waveforms (and abbreviations)**: * `sine` (or `sin`): smooth, pure tone * `sawtooth` (or `saw`): bright, buzzy * `square` (or `sqr`): hollow, woody * `triangle` (or `tri`): mellow * `pulse`: variable width * `supersaw`: thick, rich (excellent for bass and leads!) * **Noise**: `white`, `pink`, `brown`, `crackle` (use with `.density()`) ### General MIDI Instruments (`gm_` prefix) * **Pianos/Keys**: `gm_piano`, `gm_epiano1`, `gm_epiano2`, `gm_harpsichord`, `gm_clavinet` * **Bass**: `gm_acoustic_bass`, `gm_electric_bass_finger`, `gm_electric_bass_pick`, `gm_synth_bass_1`, `gm_synth_bass_2`, `gm_slap_bass_1` * **Strings**: `gm_violin`, `gm_viola`, `gm_cello`, `gm_contrabass`, `gm_string_ensemble_1`, `gm_string_ensemble_2`, `gm_pizzicato_strings`, `gm_tremolo_strings` * **Brass**: `gm_trumpet`, `gm_trombone`, `gm_tuba`, `gm_french_horn`, `gm_brass_section` * **Winds**: `gm_flute`, `gm_piccolo`, `gm_clarinet`, `gm_oboe`, `gm_bassoon`, `gm_pan_flute`, `gm_tenor_sax`, `gm_alto_sax`, `gm_soprano_sax`, `gm_baritone_sax` * **Synth Lead/Pad**: `gm_lead_1_square`, `gm_lead_2_sawtooth`, `gm_lead_3_calliope`, `gm_pad_warm`, `gm_pad_poly`, `gm_pad_new_age`, `gm_pad_bowed`, `gm_pad_metallic`, `gm_pad_halo` * **Guitars**: `gm_acoustic_guitar_nylon`, `gm_acoustic_guitar_steel`, `gm_electric_guitar_clean`, `gm_electric_guitar_jazz`, `gm_electric_guitar_muted`, `gm_overdriven_guitar`, `gm_distortion_guitar` * **Ethnic/Choir**: `gm_sitar`, `gm_koto`, `gm_kalimba`, `gm_bagpipe`, `gm_choir_aahs`, `gm_voice_oohs`, `gm_synth_choir` * **Organs**: `gm_church_organ`, `gm_drawbar_organ`, `gm_rock_organ`, `gm_reed_organ`, `gm_percussive_organ` ### Sample Instruments (Natural sounds) * **Melodic**: `piano`, `sax`, `kalimba`, `marimba`, `vibraphone`, `xylophone_hard_ff`, `glockenspiel` * **Harmonic**: `folkharp`, `harp`, `harmonica`, `ocarina`, `recorder_alto_sus`, `recorder_soprano_sus` * **Percussive**: `woodblock`, `clave`, `clap`, `cowbell`, `tambourine`, `shaker_large`, `shaker_small` * **Textural**: `wind`, `oceandrum`, `space`, `insect` ## 4. Notes & Harmony ### Note Notation * **Letters**: `$: note("c d e f")` (a-g) * **MIDI**: `$: note("60 64 67")` (60 = middle C) * **Octaves**: `$: note("c#4 eb5 f3")` * **Chords (Mini-Notation)**: `$: note("c,e,g")` (Use commas for simultaneous notes) * **Microtones**: `$: note("60.5 64.25")` ### Scales * `$: n("0 2 4 7").scale("C:major")` (Scale degrees) * `$: n("0 1 2 3").scale("D:minor")` (Different root) * `$: n("0 2 4").scale("A2:minor:pentatonic")` (With octave) **Common scales**: major, minor, dorian, mixolydian, lydian, phrygian, major:pentatonic, minor:pentatonic, major:blues, minor:blues, harmonicMinor, melodicMinor, diminished, wholeTone ### Chords (Symbols) * `$: chord("Cm").voicing()` * `$: chord("C7#11").voicing()` (Extended) * `$: chord("Dm/F").voicing()` (Slash chords) ### Frequency * `$: freq("440 880")` (Direct Hz control) ## 5. Time Modifiers * **.fast(n)** : Speed up by n (e.g., `.fast("<1 2 4>")`) * **.slow(n)** : Slow down by n * **.rev()** : Reverse pattern * **.palindrome()** : Forward then backward * **.iter(n)** : Rotate subdivisions each cycle * **.ply(n)** : Repeat each event n times * **.euclid(beats, steps)** : Euclidean rhythm * **.euclidRot(beats, steps, rot)** : With rotation * **.early(cycles)** : Shift earlier (in cycles) * **.late(cycles)** : Shift later * **.every(n, fn)** : Apply function every nth cycle * **.when(cond, fn)** : Conditional application * **.sometimesBy(prob, fn)** : Random with probability * **.swing(n)** : Add swing * **.segment(n)** : Sample n times per cycle (essential for sweeps!) ## 6. Audio Effects ### Filters (Shape the Sound) * **Low-Pass** (removes highs, makes darker/warmer): * `.lpf(freq)`: Cutoff 0-20000 Hz * `.lpq(res)`: Resonance 0-50 * **High-Pass** (removes lows, makes thinner): * `.hpf(freq)`: Cutoff 0-20000 Hz * `.hpq(res)`: Resonance 0-50 * **Band-Pass** (only center frequencies): * `.bpf(freq)`: Center frequency * `.bpq(res)`: Resonance * **Vowel Filter**: * `.vowel("a e i o u ae aa oe ue")`: (Options: a, e, i, o, u, ae, aa, oe, ue, etc.) ### Filter Envelopes (Animated Sweeps) * `.lpenv(semitones)`: LP sweep depth * `.lpa(time)`: LP attack * `.lpd(time)`: LP decay * `.lps(level)`: LP sustain * `.lpr(time)`: LP release * *(Same for HP: `hpenv`, `hpa`, `hpd`, `hps`, `hpr`)* * *(Same for BP: `bpenv`, `bpa`, `bpd`, `bps`, `bpr`)* ### Amplitude Envelope (ADSR - Volume Over Time) * `.attack(time)`: Attack (or `.att()`) * `.decay(time)`: Decay (or `.dec()`) * `.sustain(level)`: Sustain 0-1 (or `.sus()`) * `.release(time)`: Release (or `.rel()`) * `.adsr("att:dec:sus:rel")`: Combined e.g., `"0.1:0.2:0.7:0.5"` ### Gain & Dynamics * `.gain(level)`: Volume 0-1 (can exceed 1) * `.velocity(level)`: Note velocity 0-1 * `.postgain(level)`: After effects * `.compressor("thresh:ratio:knee:att:rel")` ### Distortion & Saturation * `.distort(amount)`: Wavefold distortion 0-10+ (try 2-8) * `.dist(amount)`: Alias for distort * `.crush(bits)`: Bit crushing 1-16 (4-8 for grit) * `.shape(amount)`: Alternative waveshaping * **.coarse(factor)**: Sample rate reduction (Chrome only!) ### Modulation (Movement & Character) * `.vib(hz)`: Vibrato rate (4-8 Hz typical) * `.vibmod(depth)`: Vibrato depth in semitones * `.vib("hz:depth")`: Combined (e.g., `"6:1"`) * `.fm(index)`: FM synthesis brightness 0-10+ * `.fmh(ratio)`: FM harmonicity (2=octave) * `.fmattack(time)`: FM envelope attack * `.fmdecay(time)`: FM envelope decay * `.tremolosync(rate)`: Tremolo rate in cycles * `.tremolodepth(depth)`: Tremolo intensity 0-1 * `.phaser(rate)`: Phaser speed * `.phaserdepth(depth)`: Phaser amount ### Space & Time (Reverb/Delay) * `.orbit(n)`: Assign to orbit (orbits share effects!) * `.room(level)`: Reverb wet 0-1 (try 0.3-0.8) * `.room("level:size")`: Combined (e.g., `".5:8"`) * `.roomsize(size)`: Room size 0-10 * `.roomfade(time)`: Fade duration * `.roomlp(freq)`: Darken reverb tail * `.delay(level)`: Delay wet 0-1 (try 0.3-0.6) * `.delay("level:time:fb")`: Combined (e.g., `".5:.125:.8"`) * `.delaytime(time)`: Delay time in cycles (0.125, 0.25, 0.5) * `.delayfeedback(fb)`: Feedback 0-1 (keep under 1!) * **.pan(pos)**: Stereo 0-1 (0=left, 0.5=center, 1=right) * **.jux(fn)**: Apply function to the right channel only * **.juxBy(amount, fn)**: With amount control ### Sample Manipulation * `.chop(n)` - Divide into n pieces * `.slice(n, pattern)` - Slice and select: `.slice(8, "0 4 2 6")` * `.striate(n)` - Granular chopping * `.begin(pos)` - Start point 0-1 * `.end(pos)` - End point 0-1 * `.speed(rate)` - Playback speed (negative = reverse) * `.loop(1)` - Enable looping * `.loopAt(cycles)` - Stretch to fit cycles * `.fit()` - Match event duration * `.cut(group)` - Cut group (stop overlaps) ## 7. Pattern Factories * **`stack(p1, p2, ...)`** - Play patterns simultaneously (Primary for rich music!) * **`seq(p1, p2, ...)`** - Sequence patterns in one cycle (fastcat) * **`cat(p1, p2, ...)`** - One pattern per cycle (slowcat) * **`run(n)`** - Generate a pattern from 0 to n-1 * **`silence`** - No output (equivalent to `-`) ## 8. Advanced Modulation (Modular Style) ### Modulation (Fluent Signal Syntax) * **LFO Gain**: `gain(sine.range(.5, 1).fast(2))` * **Filter Sweeps**: `lpf(sawtooth.range(200, 4000).slow(4))` * **Vibrato**: `vib("6:0.5")` (rate:depth) ## 9. Style Templates ### A. Deep Minimal Techno ```javascript setcps(128/60/4) $: s("bd*4").bank("tr909").gain(1.2) $: s("- [hh|oh] - hh").bank("tr909").gain(0.8).jux(iter(4)) $: s("rim(3,8)").bank("tr606").room(0.3).delay(0.4) $: note("c1*16").s("sine").lpf(sine.range(40, 120).slow(8)).gain(0.9) ``` ### B. Modular Melodic Chaos ```javascript setcps(100/60/4) const mel = () => note(run(8).scale("C:minor:pentatonic")).scramble(4); $: mel().s("supersaw").lpf(1200).lpq(10).room(0.5).slow(2) $: s("bd(5,8)").bank("tr808").distort(1.5) $: s("cp").at(3).room(1).rev() ``` ### C. Classic House / Deep House ```javascript setcps(124/60/4) $: s("bd*4").bank("tr909").gain(1.1) $: s("- [cp|sd] - [cp|sd]").bank("tr909").gain(0.9) $: s("hh*8, - oh").bank("tr909").gain(0.7) $: chord("").voicing().s("gm_epiano1") .room(.6).delay(.4).slow(2) $: note("c2*2").s("saw").lpf(sine.range(100, 300).slow(4)).gain(0.8) ``` ### D. Dark Synthwave (80s retro) ```javascript setcps(100/60/4) $: s("bd*4, - sd - sd, hh*16, - - oh -").bank("tr808").gain(1.1) $: note("a0 [ - a0] [ - a0] a0").s("saw").lpf(sine.range(60, 150).slow(8)).gain(0.9) $: chord("").voicing().s("gm_pad_warm").room(0.8).slow(4).gain(0.7) $: note("*2").s("supersaw").lpf(800).delay(0.4).jux(rev) ``` ### E. Drum 'n' Bass (Fast & Breaky) ```javascript setcps(174/60/4) $: s("bd - - [sd - bd] - bd sd -").bank("tr808").gain(1.1) $: s("hh*16").gain(sine.range(0.4, 0.9).fast(8)).pan(sine.range(0.2, 0.8).slow(4)) $: note("c1").s("sin").lpf(sawtooth.range(40, 150).slow(8)).gain(0.8) $: note(run(8).scale("C:minor:pentatonic")).s("gm_lead_1_square") .struct("1(3,8)").room(0.5).jux(rev) ``` ### F. Deep Ambient / Texture ```javascript setcps(60/60/4) $: chord("").voicing().s("gm_pad_halo") .room(0.9).slow(4).gain(0.6).jux(rev) $: note(run(12).scale("F:lydian")).s("vibraphone") .room(0.8).delay(0.5).slow(8).scramble(8).pan(sine.range(0.1, 0.9).slow(16)) $: note("f1").s("sin").lpf(sine.range(40, 80).slow(12)).gain(0.5).slow(4) ``` ## 10. Critical Generation Rules 1. **ALWAYS start with `setcps(NUMBER)**`: This is required at the very beginning! Always use `setcps(BPM/60/4)`. 2. **Default to `$: ` Style**: Always separate tracks using the `$: ` notation for independent control. 3. **Rests**: Always use `-` instead of `~`. 4. **Modulation**: Use fluent signal syntax: `signal.range(min, max).fast(n)`. 5. **Layering**: Always include: 1. Rhythmic (Drums), 2. Harmonic (Bass/Chords), 3. Texture/Melody. 6. **Wide Stereo**: Use `.jux()` or `.pan()` for professional depth. 7. **No Simplify**: Keep mini-notation rich (e.g., use `(3,8)` or `[hh!3]`). 8. **Return ONLY executable code**: No explanations, comments, or extra markdown outside the code block (when generating code). 9. **Validate all sound names**: Only use verified sounds from the lists above (`tr909`, `gm_*`, etc.). ## 11. Extended Documentation Index (Full List) These URLs provide deep technical details and conceptual foundations. ### 11.1. Workshop & Getting Started - Strudel Overview: https://strudel.cc/workshop/getting-started/ - First Sounds: https://strudel.cc/workshop/first-sounds/ - First Notes: https://strudel.cc/workshop/first-notes/ - First Effects: https://strudel.cc/workshop/first-effects/ - Pattern Effects: https://strudel.cc/workshop/pattern-effects/ - Workshop Recap: https://strudel.cc/workshop/recap/ ### 11.2. Core Syntax & Manuals - Coding Syntax Detail: https://strudel.cc/learn/code/ - Mini Notation Detail: https://strudel.cc/learn/mini-notation/ - Mondo Notation Detail: https://strudel.cc/learn/mondo-notation/ - Pattern Functions Intro: https://strudel.cc/functions/intro/ - Patterns Detail: https://strudel.cc/technical-manual/patterns/ - Time Modifiers: https://strudel.cc/learn/time-modifiers/ ### 11.3. Sound Sources & Synthesis - Samples Detail: https://strudel.cc/learn/samples/ - Synths Detail: https://strudel.cc/learn/synths/ - Csound Integration: https://strudel.cc/learn/csound/ - Registering a sound: https://strudel.cc/technical-manual/sounds/ ### 11.4. Modulation & Theory - Continuous Signals: https://strudel.cc/learn/signals/ - Random Modifiers: https://strudel.cc/learn/random-modifiers/ - Conditional Modifiers: https://strudel.cc/learn/conditional-modifiers/ - Accumulation: https://strudel.cc/learn/accumulation/ - Tonal Functions: https://strudel.cc/learn/tonal/ - Understanding Cycles: https://strudel.cc/understand/cycles/ - Understanding Pitch: https://strudel.cc/understand/pitch/ - Chords and Voicings: https://strudel.cc/understand/voicings/ - Alignment & Combination: https://strudel.cc/technical-manual/alignment/ ### 11.5. Advanced & Specialized - Effects Detail: https://strudel.cc/learn/effects/ - Hydra Video Synth: https://strudel.cc/learn/hydra/ - Visual Feedback: https://strudel.cc/learn/visual-feedback/ - Music MetaData: https://strudel.cc/learn/metadata/ - Xen Harmonic Functions: https://strudel.cc/learn/xen/ - Strudel vs Tidal: https://strudel.cc/learn/strudel-vs-tidal/ - Recipes: https://strudel.cc/recipes/recipes/ ### 11.6. Hardware & Input/Output - MIDI, OSC and MQTT: https://strudel.cc/learn/input-output/ - Input Devices: https://strudel.cc/learn/input-devices/ - Device Motion: https://strudel.cc/learn/devicemotion/ - Using Strudel Offline: https://strudel.cc/learn/pwa/ ### 11.7. Project & Development - Project Start: https://strudel.cc/technical-manual/project-start/ - Packages: https://strudel.cc/technical-manual/packages/ - Strudel REPL: https://strudel.cc/technical-manual/repl/ - Documentation Guide: https://strudel.cc/technical-manual/docs/ - Testing (Development): https://strudel.cc/technical-manual/testing/