Files
Strudel-AI-music/agentic_workflow/syntax.md
2026-03-20 21:16:20 +01:00

263 lines
7.7 KiB
Markdown

# 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("<bd sd hh>")` |
| `~` 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("<C:minor D:dorian>/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("<Cm7 Fm7 G7 Cm7>").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
```