600 lines
41 KiB
Markdown
600 lines
41 KiB
Markdown
# AGENTS.md
|
|
|
|
## Strudel Live Coding Assistant Guidelines
|
|
|
|
### Overview
|
|
This document provides essential guidelines for AI agents assisting with Strudel live coding. Strudel is a JavaScript-based port of TidalCycles for algorithmic music composition and live coding performance.
|
|
|
|
### Critical Knowledge Requirements
|
|
|
|
#### 1. Core Syntax Understanding
|
|
- **IS JavaScript**: Strudel is built on JavaScript and supports all JavaScript features including variables, functions, objects, arrays, loops, conditionals, and more
|
|
- **Variable declarations**: You can use `const`, `let`, `var` for variables
|
|
- **Function syntax**: You can define functions using arrow functions, regular functions, or the `register()` function for custom pattern functions
|
|
- **ES6+ features**: Template literals, destructuring, spread operators, async/await, etc. are all supported
|
|
|
|
#### 2. Parallel Pattern Syntax
|
|
```javascript
|
|
// ✅ CORRECT - Multiple patterns in parallel
|
|
$: sound("bd*4")
|
|
$: sound("~ sd ~ sd")
|
|
$: sound("hh*8").gain(0.3)
|
|
|
|
// ✅ ALSO CORRECT - JavaScript variables and functions
|
|
const kick = sound("bd*4");
|
|
const snare = sound("~ sd ~ sd");
|
|
const hats = sound("hh*8").gain(0.3);
|
|
|
|
stack(kick, snare, hats)
|
|
|
|
// ✅ Custom functions
|
|
const createBeat = () => stack(
|
|
sound("bd*4"),
|
|
sound("~ sd ~ sd"),
|
|
sound("hh*8").gain(0.3)
|
|
);
|
|
|
|
createBeat()
|
|
```
|
|
|
|
#### 3. Muting Patterns
|
|
```javascript
|
|
// ✅ Mute a pattern (for live performance)
|
|
_$: sound("bd*4") // underscore mutes
|
|
|
|
// ✅ Active pattern
|
|
$: sound("bd*4") // dollar sign plays
|
|
|
|
// ✅ Named patterns (can be muted/unmuted)
|
|
kick: sound("bd*4")
|
|
snare: sound("~ sd ~ sd")
|
|
|
|
// To mute: _kick: sound("bd*4")
|
|
```
|
|
|
|
#### 4. Notes and Scales
|
|
```javascript
|
|
// ✅ CORRECT - Using scale degrees with n()
|
|
$: n("0 2 4 6").scale("C:minor").sound("piano")
|
|
|
|
// ❌ WRONG - Manual note names (this works but is not idiomatic)
|
|
$: note("c eb g bb").sound("piano")
|
|
|
|
// ✅ Scale variations
|
|
$: n("0 2 4 <[6,8] [7,9]>").scale("C:minor").sound("piano")
|
|
```
|
|
|
|
#### 5. Common Scale Names
|
|
- `C:major`, `C:minor`
|
|
- `A2:minor` (with octave)
|
|
- `D:dorian`, `G:mixolydian`
|
|
- `A2:minor:pentatonic`
|
|
- `F:major:pentatonic`
|
|
|
|
#### 6. Pattern Notation (Mini-notation)
|
|
```javascript
|
|
// Basic patterns
|
|
"bd ~ sd ~" // kick-rest-snare-rest
|
|
"bd*4" // four kicks per cycle
|
|
"bd*<2 4>" // alternating subdivisions
|
|
"<bd sd>" // alternating sounds
|
|
"[bd sd]" // both in one beat
|
|
"bd@3 sd" // bd three times longer
|
|
"bd!3 sd" // replicate bd three times
|
|
"[bd ~ sd ~]/2" // slow down by half
|
|
|
|
// Advanced patterns
|
|
"~ 0 ~ 2 ~ 4 ~ 6" // scale degrees with rests
|
|
"0*4 2*2 4*2 6*4" // complex subdivisions
|
|
"0,2,4,6" // chord (simultaneous)
|
|
```
|
|
|
|
#### 7. Sound Sources
|
|
```javascript
|
|
// Drum samples
|
|
$: sound("bd sd hh oh")
|
|
|
|
// Instrument banks
|
|
$: sound("bd sd").bank("RolandTR909")
|
|
|
|
// Synthesizers
|
|
$: n("0 2 4 6").sound("sawtooth") // waveforms
|
|
$: n("0 2 4 6").sound("piano") // samples
|
|
$: n("0 2 4 6").sound("gm_acoustic_bass") // GM sounds
|
|
```
|
|
|
|
##### Built-in Synths
|
|
```
|
|
brown bytebeat crackle gm_accordion(7) gm_acoustic_bass(4) gm_acoustic_guitar_nylon(9) gm_acoustic_guitar_steel(10) gm_agogo(6) gm_alto_sax(6) gm_applause(15) gm_bagpipe(1) gm_bandoneon(10) gm_banjo(6) gm_baritone_sax(6) gm_bassoon(4) gm_bird_tweet(7) gm_blown_bottle(5) gm_brass_section(5) gm_breath_noise(8) gm_celesta(6) gm_cello(6) gm_choir_aahs(9) gm_church_organ(5) gm_clarinet(6) gm_clavinet(4) gm_contrabass(3) gm_distortion_guitar(7) gm_drawbar_organ(7) gm_dulcimer(5) gm_electric_bass_finger(4) gm_electric_bass_pick(5) gm_electric_guitar_clean(9) gm_electric_guitar_jazz(9) gm_electric_guitar_muted(10) gm_english_horn(4) gm_epiano1(11) gm_epiano2(9) gm_fiddle(9) gm_flute(5) gm_french_horn(5) gm_fretless_bass(2) gm_fx_atmosphere(13) gm_fx_brightness(12) gm_fx_crystal(10) gm_fx_echoes(10) gm_fx_goblins(9) gm_fx_rain(6) gm_fx_sci_fi(9) gm_fx_soundtrack(5) gm_glockenspiel(5) gm_guitar_fret_noise(8) gm_guitar_harmonics(3) gm_gunshot(12) gm_harmonica(6) gm_harpsichord(8) gm_helicopter(16) gm_kalimba(5) gm_koto(9) gm_lead_1_square(3) gm_lead_2_sawtooth(7) gm_lead_3_calliope(7) gm_lead_4_chiff(6) gm_lead_5_charang(10) gm_lead_6_voice(6) gm_lead_7_fifths(5) gm_lead_8_bass_lead(5) gm_marimba(7) gm_melodic_tom(9) gm_music_box(5) gm_muted_trumpet(5) gm_oboe(5) gm_ocarina(4) gm_orchestra_hit(5) gm_orchestral_harp(5) gm_overdriven_guitar(10) gm_pad_bowed(5) gm_pad_choir(6) gm_pad_halo(8) gm_pad_metallic(7) gm_pad_new_age(12) gm_pad_poly(7) gm_pad_sweep(7) gm_pad_warm(7) gm_pan_flute(8) gm_percussive_organ(6) gm_piano(32) gm_piccolo(5) gm_pizzicato_strings(6) gm_recorder(5) gm_reed_organ(8) gm_reverse_cymbal(9) gm_rock_organ(5) gm_seashore(16) gm_shakuhachi(5) gm_shamisen(7) gm_shanai(5) gm_sitar(7) gm_slap_bass_1(4) gm_slap_bass_2(4) gm_soprano_sax(5) gm_steel_drums(6) gm_string_ensemble_1(11) gm_string_ensemble_2(7) gm_synth_bass_1(9) gm_synth_bass_2(7) gm_synth_brass_1(4) gm_synth_brass_2(7) gm_synth_choir(5) gm_synth_drum(7) gm_synth_strings_1(7) gm_synth_strings_2(4) gm_taiko_drum(10) gm_telephone(10) gm_tenor_sax(4) gm_timpani(6) gm_tinkle_bell(1) gm_tremolo_strings(6) gm_trombone(5) gm_trumpet(4) gm_tuba(4) gm_tubular_bells(6) gm_vibraphone(6) gm_viola(5) gm_violin(9) gm_voice_oohs(6) gm_whistle(4) gm_woodblock(9) gm_xylophone(6) pink pulse saw sawtooth sbd sin sine sqr square supersaw tri triangle white z_noise z_sawtooth z_sine z_square z_tan z_triangle zzfx
|
|
```
|
|
|
|
##### Built-in Drum Machines
|
|
```
|
|
9000_bd(1) 9000_cb(2) 9000_cr(2) 9000_hh(1) 9000_ht(2) 9000_lt(2) 9000_mt(1) 9000_oh(1) 9000_perc(3) 9000_rd(2) 9000_rim(1) 9000_sd(1) 9000_tb(1) ace_bd(3) ace_hh(1) ace_ht(1) ace_lt(1) ace_oh(1) ace_perc(6) ace_sd(3) ajkpercusyn_bd(1) ajkpercusyn_cb(2) ajkpercusyn_ht(1) ajkpercusyn_sd(1) akailinn_bd(1) akailinn_cb(1) akailinn_cp(1) akailinn_cr(1) akailinn_hh(1) akailinn_ht(1) akailinn_lt(1) akailinn_mt(1) akailinn_oh(1) akailinn_rd(1) akailinn_sd(1) akailinn_sh(1) akailinn_tb(1) akaimpc60_bd(2) akaimpc60_cp(1) akaimpc60_cr(1) akaimpc60_hh(1) akaimpc60_ht(1) akaimpc60_lt(1) akaimpc60_misc(2) akaimpc60_mt(1) akaimpc60_oh(1) akaimpc60_perc(5) akaimpc60_rd(1) akaimpc60_rim(1) akaimpc60_sd(3) akaixr10_bd(10) akaixr10_cb(1) akaixr10_cp(1) akaixr10_cr(3) akaixr10_hh(2) akaixr10_ht(1) akaixr10_lt(2) akaixr10_misc(4) akaixr10_mt(2) akaixr10_oh(1) akaixr10_perc(15) akaixr10_rd(1) akaixr10_rim(2) akaixr10_sd(10) akaixr10_sh(1) akaixr10_tb(1) alesishr16_bd(1) alesishr16_cp(1) alesishr16_hh(1) alesishr16_ht(1) alesishr16_lt(1) alesishr16_oh(1) alesishr16_perc(8) alesishr16_rim(1) alesishr16_sd(1) alesishr16_sh(3) alesissr16_bd(13) alesissr16_cb(1) alesissr16_cp(1) alesissr16_cr(2) alesissr16_hh(3) alesissr16_misc(3) alesissr16_oh(4) alesissr16_perc(7) alesissr16_rd(3) alesissr16_rim(1) alesissr16_sd(12) alesissr16_sh(1) alesissr16_tb(1) bd(8) bossdr110_bd(1) bossdr110_cp(1) bossdr110_cr(1) bossdr110_hh(1) bossdr110_oh(1) bossdr110_rd(1) bossdr110_sd(1) bossdr220_bd(1) bossdr220_cp(1) bossdr220_cr(1) bossdr220_hh(1) bossdr220_ht(1) bossdr220_lt(1) bossdr220_mt(1) bossdr220_oh(1) bossdr220_perc(1) bossdr220_rd(1) bossdr220_sd(1) bossdr55_bd(2) bossdr55_hh(2) bossdr55_rim(1) bossdr55_sd(8) bossdr550_bd(5) bossdr550_cb(2) bossdr550_cp(1) bossdr550_cr(1) bossdr550_hh(2) bossdr550_ht(3) bossdr550_lt(3) bossdr550_misc(3) bossdr550_mt(2) bossdr550_oh(2) bossdr550_perc(11) bossdr550_rd(2) bossdr550_rim(1) bossdr550_sd(6) bossdr550_sh(2) bossdr550_tb(1) brk(1) casiorz1_bd(1) casiorz1_cb(1) casiorz1_cp(1) casiorz1_cr(1) casiorz1_hh(1) casiorz1_ht(1) casiorz1_lt(1) casiorz1_mt(1) casiorz1_rd(2) casiorz1_rim(1) casiorz1_sd(1) casiosk1_bd(1) casiosk1_hh(1) casiosk1_ht(1) casiosk1_mt(1) casiosk1_oh(1) casiosk1_sd(1) casiovl1_bd(1) casiovl1_hh(1) casiovl1_sd(1) cb(1) circuitsdrumtracks_bd(1) circuitsdrumtracks_cb(1) circuitsdrumtracks_cp(1) circuitsdrumtracks_cr(1) circuitsdrumtracks_hh(1) circuitsdrumtracks_ht(1) circuitsdrumtracks_oh(1) circuitsdrumtracks_rd(1) circuitsdrumtracks_rim(1) circuitsdrumtracks_sd(1) circuitsdrumtracks_sh(1) circuitsdrumtracks_tb(1) circuitstom_bd(1) circuitstom_cp(1) circuitstom_cr(1) circuitstom_hh(1) circuitstom_ht(2) circuitstom_oh(1) circuitstom_sd(1) compurhythm1000_bd(1) compurhythm1000_cb(1) compurhythm1000_cp(1) compurhythm1000_cr(1) compurhythm1000_hh(1) compurhythm1000_ht(1) compurhythm1000_lt(1) compurhythm1000_mt(1) compurhythm1000_oh(1) compurhythm1000_perc(3) compurhythm1000_rd(1) compurhythm1000_rim(1) compurhythm1000_sd(1) compurhythm78_bd(1) compurhythm78_cb(1) compurhythm78_hh(2) compurhythm78_misc(4) compurhythm78_oh(2) compurhythm78_perc(8) compurhythm78_sd(1) compurhythm78_tb(1) compurhythm8000_bd(1) compurhythm8000_cb(1) compurhythm8000_cp(1) compurhythm8000_cr(1) compurhythm8000_hh(1) compurhythm8000_ht(1) compurhythm8000_lt(1) compurhythm8000_mt(1) compurhythm8000_oh(1) compurhythm8000_perc(2) compurhythm8000_rim(1) compurhythm8000_sd(1) concertmatemg1_bd(3) concertmatemg1_sd(2) cp(2) cr(2) d110_bd(1) d110_cb(2) d110_cr(1) d110_hh(1) d110_lt(1) d110_oh(2) d110_perc(3) d110_rd(1) d110_rim(1) d110_sd(3) d110_sh(1) d110_tb(1) d70_bd(4) d70_cb(1) d70_cp(1) d70_cr(1) d70_hh(1) d70_lt(1) d70_mt(1) d70_oh(1) d70_perc(1) d70_rd(1) d70_rim(1) d70_sd(5) d70_sh(1) ddm110_bd(1) ddm110_cp(1) ddm110_cr(1) ddm110_hh(1) ddm110_ht(2) ddm110_lt(2) ddm110_oh(1) ddm110_rim(1) ddm110_sd(1) ddr30_bd(8) ddr30_ht(4) ddr30_lt(4) ddr30_sd(8) dmx_bd(3) dmx_cp(1) dmx_cr(1) dmx_hh(1) dmx_ht(1) dmx_lt(1) dmx_mt(1) dmx_oh(1) dmx_rd(1) dmx_rim(1) dmx_sd(3) dmx_sh(1) dmx_tb(1) doepferms404_bd(2) doepferms404_hh(1) doepferms404_lt(1) doepferms404_oh(1) doepferms404_sd(1) dpm48_bd(3) dpm48_cp(1) dpm48_cr(1) dpm48_hh(2) dpm48_ht(1) dpm48_lt(2) dpm48_mt(1) dpm48_oh(1) dpm48_perc(2) dpm48_rd(1) dpm48_rim(1) dpm48_sd(2) dpm48_sh(2) dr110_bd(1) dr110_cp(1) dr110_cr(1) dr110_hh(1) dr110_oh(1) dr110_rd(1) dr110_sd(1) dr220_bd(1) dr220_cp(1) dr220_cr(1) dr220_hh(1) dr220_ht(1) dr220_lt(1) dr220_mt(1) dr220_oh(1) dr220_perc(1) dr220_rd(1) dr220_sd(1) dr55_bd(2) dr55_hh(2) dr55_rim(1) dr55_sd(8) dr550_bd(5) dr550_cb(2) dr550_cp(1) dr550_cr(1) dr550_hh(2) dr550_ht(3) dr550_lt(3) dr550_misc(3) dr550_mt(2) dr550_oh(2) dr550_perc(11) dr550_rd(2) dr550_rim(1) dr550_sd(6) dr550_sh(2) dr550_tb(1) drumulator_bd(1) drumulator_cb(1) drumulator_cp(1) drumulator_cr(1) drumulator_hh(1) drumulator_ht(1) drumulator_lt(1) drumulator_mt(1) drumulator_oh(1) drumulator_perc(1) drumulator_rim(1) drumulator_sd(1) emudrumulator_bd(1) emudrumulator_cb(1) emudrumulator_cp(1) emudrumulator_cr(1) emudrumulator_hh(1) emudrumulator_ht(1) emudrumulator_lt(1) emudrumulator_mt(1) emudrumulator_oh(1) emudrumulator_perc(1) emudrumulator_rim(1) emudrumulator_sd(1) emumodular_bd(2) emumodular_misc(1) emumodular_perc(2) emusp12_bd(14) emusp12_cb(1) emusp12_cp(1) emusp12_cr(1) emusp12_hh(2) emusp12_ht(6) emusp12_lt(6) emusp12_misc(7) emusp12_mt(4) emusp12_oh(1) emusp12_perc(1) emusp12_rd(1) emusp12_rim(2) emusp12_sd(21) hh(5) hr16_bd(1) hr16_cp(1) hr16_hh(1) hr16_ht(1) hr16_lt(1) hr16_oh(1) hr16_perc(8) hr16_rim(1) hr16_sd(1) hr16_sh(3) ht(1) jd990_bd(10) jd990_cb(1) jd990_cp(1) jd990_cr(1) jd990_hh(4) jd990_ht(1) jd990_lt(5) jd990_misc(12) jd990_mt(2) jd990_oh(2) jd990_perc(6) jd990_rd(1) jd990_sd(15) jd990_tb(1) korgddm110_bd(1) korgddm110_cp(1) korgddm110_cr(1) korgddm110_hh(1) korgddm110_ht(2) korgddm110_lt(2) korgddm110_oh(1) korgddm110_rim(1) korgddm110_sd(1) korgkpr77_bd(1) korgkpr77_cp(1) korgkpr77_hh(1) korgkpr77_oh(1) korgkpr77_sd(1) korgkr55_bd(1) korgkr55_cb(1) korgkr55_cr(1) korgkr55_hh(1) korgkr55_ht(1) korgkr55_oh(1) korgkr55_perc(2) korgkr55_rim(1) korgkr55_sd(1) korgkrz_bd(1) korgkrz_cr(1) korgkrz_fx(2) korgkrz_hh(1) korgkrz_ht(1) korgkrz_lt(1) korgkrz_misc(1) korgkrz_oh(1) korgkrz_rd(1) korgkrz_sd(2) korgm1_bd(3) korgm1_cb(1) korgm1_cp(1) korgm1_cr(1) korgm1_hh(2) korgm1_ht(2) korgm1_misc(16) korgm1_mt(1) korgm1_oh(2) korgm1_perc(7) korgm1_rd(1) korgm1_rim(1) korgm1_sd(4) korgm1_sh(1) korgm1_tb(1) korgminipops_bd(7) korgminipops_hh(4) korgminipops_misc(4) korgminipops_oh(4) korgminipops_sd(13) korgpoly800_bd(4) korgt3_bd(5) korgt3_cp(1) korgt3_hh(2) korgt3_misc(4) korgt3_oh(2) korgt3_perc(4) korgt3_rim(1) korgt3_sd(5) korgt3_sh(3) kpr77_bd(1) kpr77_cp(1) kpr77_hh(1) kpr77_oh(1) kpr77_sd(1) kr55_bd(1) kr55_cb(1) kr55_cr(1) kr55_hh(1) kr55_ht(1) kr55_oh(1) kr55_perc(2) kr55_rim(1) kr55_sd(1) krz_bd(1) krz_cr(1) krz_fx(2) krz_hh(1) krz_ht(1) krz_lt(1) krz_misc(1) krz_oh(1) krz_rd(1) krz_sd(2) linn_bd(1) linn_cb(1) linn_cp(1) linn_cr(1) linn_hh(1) linn_ht(1) linn_lt(1) linn_mt(1) linn_oh(1) linn_rd(1) linn_sd(1) linn_sh(1) linn_tb(1) linn9000_bd(1) linn9000_cb(2) linn9000_cr(2) linn9000_hh(1) linn9000_ht(2) linn9000_lt(2) linn9000_mt(1) linn9000_oh(1) linn9000_perc(3) linn9000_rd(2) linn9000_rim(1) linn9000_sd(1) linn9000_tb(1) linndrum_bd(1) linndrum_cb(1) linndrum_cp(1) linndrum_cr(1) linndrum_hh(3) linndrum_ht(2) linndrum_lt(2) linndrum_mt(1) linndrum_oh(1) linndrum_perc(6) linndrum_rd(1) linndrum_rim(3) linndrum_sd(3) linndrum_sh(1) linndrum_tb(1) linnlm1_bd(4) linnlm1_cb(1) linnlm1_cp(1) linnlm1_hh(1) linnlm1_ht(1) linnlm1_lt(1) linnlm1_oh(1) linnlm1_perc(3) linnlm1_rim(1) linnlm1_sd(1) linnlm1_sh(1) linnlm1_tb(1) linnlm2_bd(4) linnlm2_cb(1) linnlm2_cp(1) linnlm2_cr(1) linnlm2_hh(2) linnlm2_ht(1) linnlm2_lt(1) linnlm2_mt(1) linnlm2_oh(2) linnlm2_rd(1) linnlm2_rim(2) linnlm2_sd(4) linnlm2_sh(1) linnlm2_tb(1) lm1_bd(4) lm1_cb(1) lm1_cp(1) lm1_hh(1) lm1_ht(1) lm1_lt(1) lm1_oh(1) lm1_perc(3) lm1_rim(1) lm1_sd(1) lm1_sh(1) lm1_tb(1) lm2_bd(4) lm2_cb(1) lm2_cp(1) lm2_cr(1) lm2_hh(2) lm2_ht(1) lm2_lt(1) lm2_mt(1) lm2_oh(2) lm2_rd(1) lm2_rim(2) lm2_sd(4) lm2_sh(1) lm2_tb(1) lm8953_bd(3) lm8953_cr(1) lm8953_hh(2) lm8953_ht(2) lm8953_lt(2) lm8953_mt(2) lm8953_oh(1) lm8953_rd(1) lm8953_rim(2) lm8953_sd(5) lm8953_tb(1) lt(1) m1_bd(3) m1_cb(1) m1_cp(1) m1_cr(1) m1_hh(2) m1_ht(2) m1_misc(16) m1_mt(1) m1_oh(2) m1_perc(7) m1_rd(1) m1_rim(1) m1_sd(4) m1_sh(1) m1_tb(1) mc202_bd(5) mc202_ht(3) mc202_perc(1) mc303_bd(16) mc303_cb(2) mc303_cp(8) mc303_fx(2) mc303_hh(6) mc303_ht(5) mc303_lt(5) mc303_misc(8) mc303_mt(6) mc303_oh(5) mc303_perc(39) mc303_rd(2) mc303_rim(6) mc303_sd(26) mc303_sh(7) mc303_tb(5) mfb512_bd(1) mfb512_cp(1) mfb512_cr(1) mfb512_hh(1) mfb512_ht(1) mfb512_lt(1) mfb512_mt(1) mfb512_oh(1) mfb512_sd(1) microrhythmer12_bd(1) microrhythmer12_hh(1) microrhythmer12_oh(1) microrhythmer12_sd(1) minipops_bd(7) minipops_hh(4) minipops_misc(4) minipops_oh(4) minipops_sd(13) misc(5) moogconcertmatemg1_bd(3) moogconcertmatemg1_sd(2) mpc1000_bd(5) mpc1000_cp(1) mpc1000_hh(4) mpc1000_oh(1) mpc1000_perc(1) mpc1000_sd(4) mpc1000_sh(1) mpc60_bd(2) mpc60_cp(1) mpc60_cr(1) mpc60_hh(1) mpc60_ht(1) mpc60_lt(1) mpc60_misc(2) mpc60_mt(1) mpc60_oh(1) mpc60_perc(5) mpc60_rd(1) mpc60_rim(1) mpc60_sd(3) mridangam_ardha(20) mridangam_chaapu(13) mridangam_dhi(7) mridangam_dhin(8) mridangam_dhum(7) mridangam_gumki(14) mridangam_ka(12) mridangam_ki(7) mridangam_na(12) mridangam_nam(8) mridangam_ta(9) mridangam_tha(7) mridangam_thom(7) ms404_bd(2) ms404_hh(1) ms404_lt(1) ms404_oh(1) ms404_sd(1) mt(1) mt32_bd(1) mt32_cb(1) mt32_cp(1) mt32_cr(1) mt32_hh(1) mt32_ht(1) mt32_lt(1) mt32_mt(1) mt32_oh(2) mt32_perc(13) mt32_rd(1) mt32_rim(1) mt32_sd(2) mt32_sh(2) mt32_tb(1) oberheimdmx_(3) oberheimdmx_bd(3) oberheimdmx_cp(1) oberheimdmx_cr(1) oberheimdmx_hh(1) oberheimdmx_ht(1) oberheimdmx_lt(1) oberheimdmx_mt(1) oberheimdmx_oh(1) oberheimdmx_rd(1) oberheimdmx_rim(1) oberheimdmx_sd(3) oberheimdmx_sh(1) oberheimdmx_tb(1) oh(4) percysyn_bd(1) percysyn_cb(2) percysyn_ht(1) percysyn_sd(1) polaris_bd(4) polaris_misc(4) polaris_sd(4) poly800_bd(4) r8_bd(7) r8_cb(1) r8_cp(1) r8_cr(1) r8_hh(2) r8_ht(4) r8_lt(4) r8_mt(4) r8_oh(1) r8_perc(8) r8_rd(2) r8_rim(2) r8_sd(12) r8_sh(2) r8_tb(1) r88_bd(1) r88_cr(1) r88_hh(1) r88_oh(1) r88_sd(2) rd(1) rhodespolaris_bd(4) rhodespolaris_misc(4) rhodespolaris_sd(4) rhythmace_bd(3) rhythmace_hh(1) rhythmace_ht(1) rhythmace_lt(1) rhythmace_oh(1) rhythmace_perc(6) rhythmace_sd(3) rim(2) rm50_bd(103) rm50_cb(6) rm50_cp(2) rm50_cr(22) rm50_hh(18) rm50_ht(25) rm50_lt(49) rm50_misc(28) rm50_mt(34) rm50_oh(12) rm50_perc(56) rm50_rd(13) rm50_sd(108) rm50_sh(6) rm50_tb(3) rolandcompurhythm1000_bd(1) rolandcompurhythm1000_cb(1) rolandcompurhythm1000_cp(1) rolandcompurhythm1000_cr(1) rolandcompurhythm1000_hh(1) rolandcompurhythm1000_ht(1) rolandcompurhythm1000_lt(1) rolandcompurhythm1000_mt(1) rolandcompurhythm1000_oh(1) rolandcompurhythm1000_perc(3) rolandcompurhythm1000_rd(1) rolandcompurhythm1000_rim(1) rolandcompurhythm1000_sd(1) rolandcompurhythm78_bd(1) rolandcompurhythm78_cb(1) rolandcompurhythm78_hh(2) rolandcompurhythm78_misc(4) rolandcompurhythm78_oh(2) rolandcompurhythm78_perc(8) rolandcompurhythm78_sd(1) rolandcompurhythm78_tb(1) rolandcompurhythm8000_bd(1) rolandcompurhythm8000_cb(1) rolandcompurhythm8000_cp(1) rolandcompurhythm8000_cr(1) rolandcompurhythm8000_hh(1) rolandcompurhythm8000_ht(1) rolandcompurhythm8000_lt(1) rolandcompurhythm8000_mt(1) rolandcompurhythm8000_oh(1) rolandcompurhythm8000_perc(2) rolandcompurhythm8000_rim(1) rolandcompurhythm8000_sd(1) rolandd110_bd(1) rolandd110_cb(2) rolandd110_cr(1) rolandd110_hh(1) rolandd110_lt(1) rolandd110_oh(2) rolandd110_perc(3) rolandd110_rd(1) rolandd110_rim(1) rolandd110_sd(3) rolandd110_sh(1) rolandd110_tb(1) rolandd70_bd(4) rolandd70_cb(1) rolandd70_cp(1) rolandd70_cr(1) rolandd70_hh(1) rolandd70_lt(1) rolandd70_mt(1) rolandd70_oh(1) rolandd70_perc(1) rolandd70_rd(1) rolandd70_rim(1) rolandd70_sd(5) rolandd70_sh(1) rolandddr30_bd(8) rolandddr30_ht(4) rolandddr30_lt(4) rolandddr30_sd(8) rolandjd990_bd(10) rolandjd990_cb(1) rolandjd990_cp(1) rolandjd990_cr(1) rolandjd990_hh(4) rolandjd990_ht(1) rolandjd990_lt(5) rolandjd990_misc(12) rolandjd990_mt(2) rolandjd990_oh(2) rolandjd990_perc(6) rolandjd990_rd(1) rolandjd990_sd(15) rolandjd990_tb(1) rolandmc202_bd(5) rolandmc202_ht(3) rolandmc202_perc(1) rolandmc303_bd(16) rolandmc303_cb(2) rolandmc303_cp(8) rolandmc303_fx(2) rolandmc303_hh(6) rolandmc303_ht(5) rolandmc303_lt(5) rolandmc303_misc(8) rolandmc303_mt(6) rolandmc303_oh(5) rolandmc303_perc(39) rolandmc303_rd(2) rolandmc303_rim(6) rolandmc303_sd(26) rolandmc303_sh(7) rolandmc303_tb(5) rolandmt32_bd(1) rolandmt32_cb(1) rolandmt32_cp(1) rolandmt32_cr(1) rolandmt32_hh(1) rolandmt32_ht(1) rolandmt32_lt(1) rolandmt32_mt(1) rolandmt32_oh(2) rolandmt32_perc(13) rolandmt32_rd(1) rolandmt32_rim(1) rolandmt32_sd(2) rolandmt32_sh(2) rolandmt32_tb(1) rolandr8_bd(7) rolandr8_cb(1) rolandr8_cp(1) rolandr8_cr(1) rolandr8_hh(2) rolandr8_ht(4) rolandr8_lt(4) rolandr8_mt(4) rolandr8_oh(1) rolandr8_perc(8) rolandr8_rd(2) rolandr8_rim(2) rolandr8_sd(12) rolandr8_sh(2) rolandr8_tb(1) rolands50_bd(4) rolands50_cb(1) rolands50_cp(1) rolands50_cr(2) rolands50_ht(1) rolands50_lt(2) rolands50_misc(6) rolands50_mt(1) rolands50_oh(1) rolands50_perc(14) rolands50_rd(1) rolands50_sd(3) rolands50_sh(4) rolands50_tb(2) rolandsh09_bd(43) rolandsystem100_bd(15) rolandsystem100_hh(2) rolandsystem100_misc(2) rolandsystem100_oh(3) rolandsystem100_perc(19) rolandsystem100_sd(21) rolandtr505_bd(1) rolandtr505_cb(2) rolandtr505_cp(1) rolandtr505_cr(1) rolandtr505_hh(1) rolandtr505_ht(1) rolandtr505_lt(1) rolandtr505_mt(1) rolandtr505_oh(1) rolandtr505_perc(3) rolandtr505_rd(1) rolandtr505_rim(1) rolandtr505_sd(1) rolandtr606_bd(1) rolandtr606_cr(1) rolandtr606_hh(1) rolandtr606_ht(1) rolandtr606_lt(1) rolandtr606_oh(1) rolandtr606_sd(1) rolandtr626_bd(2) rolandtr626_cb(1) rolandtr626_cp(1) rolandtr626_cr(2) rolandtr626_hh(1) rolandtr626_ht(2) rolandtr626_lt(2) rolandtr626_mt(2) rolandtr626_oh(1) rolandtr626_perc(8) rolandtr626_rd(2) rolandtr626_rim(1) rolandtr626_sd(3) rolandtr626_sh(1) rolandtr626_tb(1) rolandtr707_bd(2) rolandtr707_cb(1) rolandtr707_cp(1) rolandtr707_cr(1) rolandtr707_hh(1) rolandtr707_ht(1) rolandtr707_lt(1) rolandtr707_mt(1) rolandtr707_oh(1) rolandtr707_rim(1) rolandtr707_sd(2) rolandtr707_tb(1) rolandtr727_perc(10) rolandtr727_sh(2) rolandtr808_bd(25) rolandtr808_cb(2) rolandtr808_cp(5) rolandtr808_cr(25) rolandtr808_hh(1) rolandtr808_ht(5) rolandtr808_lt(5) rolandtr808_mt(5) rolandtr808_oh(5) rolandtr808_perc(16) rolandtr808_rim(1) rolandtr808_sd(25) rolandtr808_sh(2) rolandtr909_bd(4) rolandtr909_cp(5) rolandtr909_cr(5) rolandtr909_hh(4) rolandtr909_ht(9) rolandtr909_lt(9) rolandtr909_mt(9) rolandtr909_oh(5) rolandtr909_rd(5) rolandtr909_rim(3) rolandtr909_sd(16) rx21_bd(1) rx21_cp(1) rx21_cr(1) rx21_hh(1) rx21_ht(1) rx21_lt(1) rx21_mt(1) rx21_oh(1) rx21_sd(1) rx5_bd(2) rx5_cb(1) rx5_fx(1) rx5_hh(1) rx5_lt(1) rx5_oh(1) rx5_rim(1) rx5_sd(3) rx5_sh(1) rx5_tb(1) ry30_bd(13) ry30_cb(2) ry30_cp(1) ry30_cr(2) ry30_hh(4) ry30_ht(3) ry30_lt(3) ry30_misc(8) ry30_mt(2) ry30_oh(4) ry30_perc(13) ry30_rd(3) ry30_rim(2) ry30_sd(21) ry30_sh(2) ry30_tb(1) rz1_bd(1) rz1_cb(1) rz1_cp(1) rz1_cr(1) rz1_hh(1) rz1_ht(1) rz1_lt(1) rz1_mt(1) rz1_rd(2) rz1_rim(1) rz1_sd(1) s50_bd(4) s50_cb(1) s50_cp(1) s50_cr(2) s50_ht(1) s50_lt(2) s50_misc(6) s50_mt(1) s50_oh(1) s50_perc(14) s50_rd(1) s50_sd(3) s50_sh(4) s50_tb(2) sakatadpm48_bd(3) sakatadpm48_cp(1) sakatadpm48_cr(1) sakatadpm48_hh(2) sakatadpm48_ht(1) sakatadpm48_lt(2) sakatadpm48_mt(1) sakatadpm48_oh(1) sakatadpm48_perc(2) sakatadpm48_rd(1) sakatadpm48_rim(1) sakatadpm48_sd(2) sakatadpm48_sh(2) sd(5) sds400_ht(3) sds400_lt(6) sds400_mt(8) sds400_sd(3) sds5_bd(12) sds5_hh(5) sds5_ht(3) sds5_lt(8) sds5_mt(6) sds5_oh(2) sds5_rim(7) sds5_sd(21) sequentialcircuitsdrumtracks_bd(1) sequentialcircuitsdrumtracks_cb(1) sequentialcircuitsdrumtracks_cp(1) sequentialcircuitsdrumtracks_cr(1) sequentialcircuitsdrumtracks_hh(1) sequentialcircuitsdrumtracks_ht(1) sequentialcircuitsdrumtracks_oh(1) sequentialcircuitsdrumtracks_rd(1) sequentialcircuitsdrumtracks_rim(1) sequentialcircuitsdrumtracks_sd(1) sequentialcircuitsdrumtracks_sh(1) sequentialcircuitsdrumtracks_tb(1) sequentialcircuitstom_bd(1) sequentialcircuitstom_cp(1) sequentialcircuitstom_cr(1) sequentialcircuitstom_hh(1) sequentialcircuitstom_ht(2) sequentialcircuitstom_oh(1) sequentialcircuitstom_sd(1) sergemodular_bd(1) sergemodular_misc(1) sergemodular_perc(5) sh(1) sh09_bd(43) simmonssds400_ht(3) simmonssds400_lt(6) simmonssds400_mt(8) simmonssds400_sd(3) simmonssds5_bd(12) simmonssds5_hh(5) simmonssds5_ht(3) simmonssds5_lt(8) simmonssds5_mt(6) simmonssds5_oh(2) simmonssds5_rim(7) simmonssds5_sd(21) sk1_bd(1) sk1_hh(1) sk1_ht(1) sk1_mt(1) sk1_oh(1) sk1_sd(1) soundmastersr88_bd(1) soundmastersr88_cr(1) soundmastersr88_hh(1) soundmastersr88_oh(1) soundmastersr88_sd(2) sp12_bd(14) sp12_cb(1) sp12_cp(1) sp12_cr(1) sp12_hh(2) sp12_ht(6) sp12_lt(6) sp12_misc(7) sp12_mt(4) sp12_oh(1) sp12_perc(1) sp12_rd(1) sp12_rim(2) sp12_sd(21) spacedrum_bd(11) spacedrum_cb(1) spacedrum_hh(6) spacedrum_ht(7) spacedrum_lt(2) spacedrum_misc(2) spacedrum_mt(2) spacedrum_oh(3) spacedrum_perc(2) spacedrum_rim(1) spacedrum_sd(3) sr16_bd(13) sr16_cb(1) sr16_cp(1) sr16_cr(2) sr16_hh(3) sr16_misc(3) sr16_oh(4) sr16_perc(7) sr16_rd(3) sr16_rim(1) sr16_sd(12) sr16_sh(1) sr16_tb(1) system100_bd(15) system100_hh(2) system100_misc(2) system100_oh(3) system100_perc(19) system100_sd(21) t3_bd(5) t3_cp(1) t3_hh(2) t3_misc(4) t3_oh(2) t3_perc(4) t3_rim(1) t3_sd(5) t3_sh(3) tb(1) tg33_bd(4) tg33_cb(3) tg33_cp(1) tg33_cr(3) tg33_fx(1) tg33_ht(2) tg33_lt(2) tg33_misc(10) tg33_mt(2) tg33_oh(1) tg33_perc(12) tg33_rd(2) tg33_rim(1) tg33_sd(5) tg33_sh(1) tg33_tb(1) tr505_bd(1) tr505_cb(2) tr505_cp(1) tr505_cr(1) tr505_hh(1) tr505_ht(1) tr505_lt(1) tr505_mt(1) tr505_oh(1) tr505_perc(3) tr505_rd(1) tr505_rim(1) tr505_sd(1) tr606_bd(1) tr606_cr(1) tr606_hh(1) tr606_ht(1) tr606_lt(1) tr606_oh(1) tr606_sd(1) tr626_bd(2) tr626_cb(1) tr626_cp(1) tr626_cr(2) tr626_hh(1) tr626_ht(2) tr626_lt(2) tr626_mt(2) tr626_oh(1) tr626_perc(8) tr626_rd(2) tr626_rim(1) tr626_sd(3) tr626_sh(1) tr626_tb(1) tr707_bd(2) tr707_cb(1) tr707_cp(1) tr707_cr(1) tr707_hh(1) tr707_ht(1) tr707_lt(1) tr707_mt(1) tr707_oh(1) tr707_rim(1) tr707_sd(2) tr707_tb(1) tr727_perc(10) tr727_sh(2) tr808_bd(25) tr808_cb(2) tr808_cp(5) tr808_cr(25) tr808_hh(1) tr808_ht(5) tr808_lt(5) tr808_mt(5) tr808_oh(5) tr808_perc(16) tr808_rim(1) tr808_sd(25) tr808_sh(2) tr909_bd(4) tr909_cp(5) tr909_cr(5) tr909_hh(4) tr909_ht(9) tr909_lt(9) tr909_mt(9) tr909_oh(5) tr909_rd(5) tr909_rim(3) tr909_sd(16) univoxmicrorhythmer12_bd(1) univoxmicrorhythmer12_hh(1) univoxmicrorhythmer12_oh(1) univoxmicrorhythmer12_sd(1) viscospacedrum_bd(11) viscospacedrum_cb(1) viscospacedrum_hh(6) viscospacedrum_ht(7) viscospacedrum_lt(2) viscospacedrum_misc(2) viscospacedrum_mt(2) viscospacedrum_oh(3) viscospacedrum_perc(2) viscospacedrum_rim(1) viscospacedrum_sd(3) vl1_bd(1) vl1_hh(1) vl1_sd(1) xdrumlm8953_bd(3) xdrumlm8953_cr(1) xdrumlm8953_hh(2) xdrumlm8953_ht(2) xdrumlm8953_lt(2) xdrumlm8953_mt(2) xdrumlm8953_oh(1) xdrumlm8953_rd(1) xdrumlm8953_rim(2) xdrumlm8953_sd(5) xdrumlm8953_tb(1) xr10_bd(10) xr10_cb(1) xr10_cp(1) xr10_cr(3) xr10_hh(2) xr10_ht(1) xr10_lt(2) xr10_misc(4) xr10_mt(2) xr10_oh(1) xr10_perc(15) xr10_rd(1) xr10_rim(2) xr10_sd(10) xr10_sh(1) xr10_tb(1) yamaharm50_bd(103) yamaharm50_cb(6) yamaharm50_cp(2) yamaharm50_cr(22) yamaharm50_hh(18) yamaharm50_ht(25) yamaharm50_lt(49) yamaharm50_misc(28) yamaharm50_mt(34) yamaharm50_oh(12) yamaharm50_perc(56) yamaharm50_rd(13) yamaharm50_sd(108) yamaharm50_sh(6) yamaharm50_tb(3) yamaharx21_bd(1) yamaharx21_cp(1) yamaharx21_cr(1) yamaharx21_hh(1) yamaharx21_ht(1) yamaharx21_lt(1) yamaharx21_mt(1) yamaharx21_oh(1) yamaharx21_sd(1) yamaharx5_bd(2) yamaharx5_cb(1) yamaharx5_fx(1) yamaharx5_hh(1) yamaharx5_lt(1) yamaharx5_oh(1) yamaharx5_rim(1) yamaharx5_sd(3) yamaharx5_sh(1) yamaharx5_tb(1) yamahary30_bd(13) yamahary30_cb(2) yamahary30_cp(1) yamahary30_cr(2) yamahary30_hh(4) yamahary30_ht(3) yamahary30_lt(3) yamahary30_misc(8) yamahary30_mt(2) yamahary30_oh(4) yamahary30_perc(13) yamahary30_rd(3) yamahary30_rim(2) yamahary30_sd(21) yamahary30_sh(2) yamahary30_tb(1) yamahatg33_bd(4) yamahatg33_cb(3) yamahatg33_cp(1) yamahatg33_cr(3) yamahatg33_fx(1) yamahatg33_ht(2) yamahatg33_lt(2) yamahatg33_misc(10) yamahatg33_mt(2) yamahatg33_oh(1) yamahatg33_perc(12) yamahatg33_rd(2) yamahatg33_rim(1) yamahatg33_sd(5) yamahatg33_sh(1) yamahatg33_tb(1)
|
|
```
|
|
|
|
##### Built-in Samples
|
|
```
|
|
agogo(5) anvil(9) balafon(6) balafon_hard(6) balafon_soft(6) ballwhistle(2) bassdrum1(8) bassdrum2(30) belltree(6) bongo(28) brakedrum(17) cabasa(6) cajon(18) casio(3) clap(10) clash(10) clash2(5) clave(6) clavisynth(19) conga(34) cowbell(13) crow(4) dantranh(17) dantranh_tremolo(16) dantranh_vibrato(16) darbuka(20) didgeridoo(12) east(9) fingercymbal(1) flexatone(8) fmpiano(22) folkharp(29) framedrum(18) glockenspiel(7) gong(7) gong2(6) guiro(5) handbells(3) handchimes(19) harmonica(9) harmonica_soft(10) harmonica_vib(10) harp(23) hihat(15) insect(3) jazz(8) kalimba(11) kalimba2(25) kalimba3(22) kalimba4(22) kalimba5(14) kawai(37) marimba(10) marktrees(6) metal(10) num(21) numbers(9) ocarina(11) ocarina_small(10) ocarina_small_stacc(13) ocarina_vib(10) oceandrum(3) organ_4inch(27) organ_8inch(27) organ_full(27) piano(29) piano1(22) pipeorgan_loud(21) pipeorgan_loud_pedal(11) pipeorgan_quiet(21) pipeorgan_quiet_pedal(11) psaltery_bow(11) psaltery_pluck(11) psaltery_spiccato(11) ratchet(8) recorder_alto_stacc(12) recorder_alto_sus(12) recorder_alto_vib(12) recorder_bass_stacc(15) recorder_bass_sus(12) recorder_bass_vib(14) recorder_soprano_stacc(12) recorder_soprano_sus(13) recorder_tenor_stacc(12) recorder_tenor_sus(13) recorder_tenor_vib(14) sax(23) sax_stacc(23) sax_vib(19) saxello(8) saxello_stacc(8) saxello_vib(8) shaker_large(6) shaker_small(16) siren(5) slapstick(5) sleighbells(6) slitdrum(6) snare_hi(8) snare_low(20) snare_modern(72) snare_rim(4) space(18) steinway(42) strumstick(19) super64(13) super64_acc(13) super64_vib(13) sus_cymbal(25) sus_cymbal2(23) tambourine(7) tambourine2(7) timpani(30) timpani_roll(10) timpani2(204) tom_mallet(8) tom_rim(6) tom_stick(8) tom2_mallet(8) tom2_rim(6) tom2_stick(8) trainwhistle(6) triangles(37) tubularbells(9) tubularbells2(11) vibraphone(11) vibraphone_bowed(6) vibraphone_soft(11) vibraslap(4) wind(10) wineglass(4) wineglass_slow(4) woodblock(10) xylophone_hard_ff(8) xylophone_hard_pp(8) xylophone_medium_ff(8) xylophone_medium_pp(8) xylophone_soft_ff(8) xylophone_soft_pp(8)
|
|
```
|
|
|
|
**Note**: Strudel includes hundreds of built-in synths, drum machines, and samples. See the examples/ directory for extensive usage of various sound sources including custom banks and GM instruments.
|
|
|
|
#### 8. Effects and Modulation
|
|
```javascript
|
|
// Audio effects
|
|
.gain(0.8) // volume
|
|
.lpf(800) // low-pass filter
|
|
.hpf(2000) // high-pass filter
|
|
.room(0.6) // room reverb
|
|
.delay(0.25) // delay time
|
|
.pan(-0.3) // stereo pan (-1 to 1)
|
|
|
|
// Live modulation
|
|
.gain(sine.range(0.5, 1).slow(4)) // oscillating gain
|
|
.lpf(sine.range(200, 2000).slow(8)) // filter sweep
|
|
.pan(sine.range(-0.5, 0.5).slow(6)) // auto-pan
|
|
```
|
|
|
|
## Effect Method Names
|
|
|
|
Strudel uses specific method names for effects that differ from some other audio frameworks. Use `.room()` for reverb (not `.reverb()`), `.gain()` for volume, `.delay()` for delay, `.lpf()`/`.hpf()` for filters, and `.pan()` for stereo positioning. If you encounter "is not a function" errors, verify you're using the correct Strudel effect method names from the official documentation.
|
|
|
|
#### 9. Time Manipulation
|
|
```javascript
|
|
.slow(2) // half speed (2x longer cycles)
|
|
.fast(2) // double speed (half-length cycles)
|
|
.early(0.125) // timing offset
|
|
.late(0.125) // timing delay
|
|
```
|
|
|
|
#### 10. Probability and Randomness
|
|
```javascript
|
|
.sometimes(rev) // randomly apply reverse
|
|
.often(x => x.fast(2)) // frequently apply effect
|
|
.rarely(x => x.gain(0.5)) // rarely apply effect
|
|
.mask("1 0 1 1") // rhythmic gating
|
|
```
|
|
|
|
## Advanced Pattern Features
|
|
|
|
Strudel supports several advanced features for complex live coding:
|
|
|
|
**Named Patterns**: Use `$name:` syntax to create referenceable patterns (e.g., `$bass: n("0 2 4").sound("sawtooth")`), enabling pattern manipulation and live control.
|
|
|
|
**Precise Tempo Control**: `setCps(bpm/60/4)` provides more accurate tempo setting than basic BPM values, essential for precise synchronization.
|
|
|
|
**Pattern Visualization**: `._scope()` method enables visual feedback for patterns, useful for live performance monitoring.
|
|
|
|
**Mathematical Operations**: `.sub(n)` subtracts semitones, `.seg(n)` creates segmented phrases, `irand(n)` generates random integers for algorithmic composition.
|
|
|
|
**Orbit Management**: Explicit `.orbit(n)` assignment routes patterns to specific effect chains, enabling complex audio routing and independent processing.
|
|
|
|
**Interactive Elements**: Strudel supports embedding interactive controls directly in code, allowing real-time parameter manipulation during performance.
|
|
|
|
**Custom Pattern Functions**: Use `register()` to create reusable pattern transformations and effects.
|
|
|
|
**Euclidean Rhythms**: `.euclid()` for generating complex rhythmic patterns algorithmically.
|
|
|
|
**Arrangement Tools**: `arrange()` for sequencing different sections of music.
|
|
|
|
**Advanced Pattern Manipulation**: `.pickRestart()`, `.pickOut()`, `.split()`, `.penv()` for sophisticated pattern control.
|
|
|
|
**Markov Chains**: `.markov()` for generative music using probability matrices.
|
|
|
|
**Looping and Sampling**: `.loop()`, `.loopBegin()`, `.loopEnd()`, `.speed()` for sample manipulation.
|
|
|
|
**Envelope Control**: `.attack()`, `.sustain()`, `.adsr()` for shaping sound envelopes.
|
|
|
|
**Structural Control**: `.struct()`, `.clip()`, `.segment()` for pattern structuring.
|
|
|
|
**Math Operations**: `.add()`, `.sub()`, `.mul()`, `.div()` for mathematical transformations.
|
|
|
|
**External Integration**: Support for Hydra visuals, MIDI, OSC, and other external systems.
|
|
|
|
**Interactive Controls**: `slider()`, keyboard event handlers for live parameter control.
|
|
|
|
These features enable sophisticated composition techniques beyond basic sequencing, supporting professional live coding performance.
|
|
|
|
## Additional Features from Examples
|
|
|
|
Based on analysis of the examples/ directory, here are additional Strudel features and patterns:
|
|
|
|
### Pattern Construction Functions
|
|
```javascript
|
|
// stack() - Layer multiple patterns
|
|
stack(
|
|
sound("bd*4"),
|
|
sound("~ sd ~ sd"),
|
|
sound("hh*8")
|
|
)
|
|
|
|
// arrange() - Sequence different sections
|
|
const verse = sound("bd*4")
|
|
const chorus = sound("bd*8").fast(2)
|
|
arrange([4, verse], [4, chorus]) // 4 cycles of verse, 4 of chorus
|
|
```
|
|
|
|
### Custom Pattern Functions with register()
|
|
```javascript
|
|
// Create reusable effects
|
|
const stutter = register('stutter', (times, pat) =>
|
|
pat.fast(times).segment(times).slow(times)
|
|
);
|
|
|
|
const euclidPattern = register('euclidPattern', (pulses, steps, pat) =>
|
|
pat.euclid(pulses, steps)
|
|
);
|
|
|
|
// Usage
|
|
$: sound("bd").stutter(4)
|
|
$: sound("hh").euclidPattern(3, 8)
|
|
```
|
|
|
|
### Interactive Controls
|
|
```javascript
|
|
// Slider controls for live manipulation
|
|
$: sound("bd*4").lpf(slider(1, 200, 2000)) // freq from 200-2000
|
|
|
|
// Keyboard input
|
|
window.onkeydown = (e) => {
|
|
if (e.key === ' ') setCps(getCps() * 1.1); // speed up on space
|
|
}
|
|
```
|
|
|
|
### Advanced Sound Design
|
|
```javascript
|
|
// ADSR envelopes
|
|
$: sound("piano").adsr([0.01, 0.1, 0.8, 0.2])
|
|
|
|
// Sample manipulation
|
|
$: sound("bd").loop(1).loopBegin(0.1).loopEnd(0.3).speed(0.5)
|
|
|
|
// Pitch envelopes
|
|
$: note("c4").penv([0, 1, 0.5, 0]) // pitch envelope
|
|
```
|
|
|
|
### Generative Techniques
|
|
```javascript
|
|
// Markov chains for generative music
|
|
const markov = register('markov', (id, pat) => pat.withHap((hap) => {
|
|
// Implementation for markov chain generation
|
|
}));
|
|
|
|
// Random selection
|
|
$: sound(rand.range(0, 3).pick(["bd", "sd", "hh"]))
|
|
|
|
// Euclidean rhythms
|
|
$: sound("bd").euclid(3, 8) // 3 hits in 8 steps
|
|
```
|
|
|
|
### External Integration
|
|
```javascript
|
|
// Hydra visuals integration
|
|
await initHydra()
|
|
solid(0,0,0).add(osc(10, 0.1, 10)).out()
|
|
|
|
// MIDI, OSC, etc. (depending on packages loaded)
|
|
```
|
|
|
|
### Complex Arrangement Techniques
|
|
```javascript
|
|
// pickRestart() for conditional patterns
|
|
"<a b c>".pickRestart({
|
|
a: "bd*4",
|
|
b: "~ sd ~ sd",
|
|
c: "hh*8"
|
|
})
|
|
|
|
// split() for multi-output patterns
|
|
"0 1 2".split([0, 0], parts =>
|
|
stack(
|
|
n(parts[0]).sound("piano"),
|
|
n(parts[1]).sound("bass")
|
|
)
|
|
)
|
|
```
|
|
|
|
### Live Performance Techniques
|
|
```javascript
|
|
// Hush to silence all
|
|
$: sound("bd").hush()
|
|
|
|
// Conditional muting
|
|
_$: sound("bd*4") // muted
|
|
$: sound("bd*4") // active
|
|
|
|
// Real-time parameter changes
|
|
let intensity = 1;
|
|
setInterval(() => intensity = Math.random(), 1000);
|
|
$: sound("bd*4").gain(intensity)
|
|
```
|
|
|
|
### Documentation Sources
|
|
|
|
Before providing Strudel code, agents should:
|
|
|
|
1. **Always check official documentation**: https://strudel.cc/
|
|
2. **Reference workshop tutorials**: https://strudel.cc/workshop/
|
|
3. **Analyze examples/**: Study the examples/ directory for advanced patterns and JavaScript integration
|
|
4. **Verify syntax against examples** in the Strudel REPL
|
|
|
|
### Common Mistakes to Avoid
|
|
|
|
#### ❌ Incorrect Assumptions (These are actually CORRECT in Strudel!)
|
|
```javascript
|
|
// ✅ CORRECT - JavaScript variables work fine
|
|
const pattern = sound("bd*4");
|
|
const kick = sound("bd*4");
|
|
kick.gain(0.8);
|
|
|
|
// ✅ CORRECT - Function declarations work
|
|
function createBeat() {
|
|
return sound("bd*4");
|
|
}
|
|
|
|
// ✅ CORRECT - stack() function exists and works
|
|
stack(
|
|
sound("bd*4"),
|
|
sound("~ sd ~ sd")
|
|
)
|
|
|
|
// ✅ CORRECT - All JavaScript features work
|
|
const beats = ["bd", "sd", "hh"];
|
|
beats.forEach(sound => {
|
|
$: s(sound + "*4")
|
|
});
|
|
```
|
|
|
|
#### ❌ Actual Mistakes to Avoid
|
|
```javascript
|
|
// WRONG - Missing $: prefix for anonymous patterns
|
|
sound("bd*4") // This won't play unless assigned to a variable or used in stack()
|
|
|
|
// WRONG - Incorrect mini-notation
|
|
$: sound("bd*4 sd*4") // This plays both simultaneously, not sequentially
|
|
// CORRECT: $: sound("bd sd").fast(4) // or $: sound("<bd sd>*4")
|
|
```
|
|
|
|
### ✅ Correct Patterns
|
|
|
|
#### Live Performance Setup
|
|
```javascript
|
|
// Multiple parallel patterns
|
|
$: sound("bd*4").gain(0.8)
|
|
$: sound("~ sd ~ sd").gain(0.7)
|
|
$: sound("hh*8").gain(0.3).hpf(8000)
|
|
$: n("0 ~ 2 ~ 4 ~ 6 ~").scale("C2:minor").sound("sawtooth").lpf(120)
|
|
$: n("~ 0 ~ 2 ~ 4 ~ 6").scale("C4:minor").sound("piano").room(0.6)
|
|
|
|
// Using JavaScript variables and functions
|
|
const tempo = 120;
|
|
const createDrums = () => stack(
|
|
sound("bd*4").gain(0.8),
|
|
sound("~ sd ~ sd").gain(0.7),
|
|
sound("hh*8").gain(0.3)
|
|
);
|
|
|
|
setCps(tempo/60/4);
|
|
createDrums();
|
|
```
|
|
|
|
#### Live Coding Effects
|
|
```javascript
|
|
// Instant filter sweep
|
|
$: sound("bd*4").lpf(sine.range(100, 2000).slow(4))
|
|
|
|
// Rhythmic gating
|
|
$: n("0 2 4 6").scale("C:minor").sound("piano").mask("1 0 1 1")
|
|
|
|
// Probability effects
|
|
$: sound("hh*8").sometimes(rev).often(x => x.fast(2))
|
|
|
|
// Custom functions with register()
|
|
const stutter = register('stutter', (times, pat) =>
|
|
pat.fast(times).segment(times).slow(times)
|
|
);
|
|
|
|
$: sound("bd").stutter(4) // Creates stutter effect
|
|
```
|
|
|
|
#### Advanced JavaScript Integration
|
|
```javascript
|
|
// Arrays and loops
|
|
const notes = ["c", "d", "e", "f", "g"];
|
|
notes.forEach((note, i) => {
|
|
$: note(i*2).sound("piano").delay(i*0.1)
|
|
});
|
|
|
|
// Objects for complex patterns
|
|
const instruments = {
|
|
kick: sound("bd*4").gain(0.8),
|
|
snare: sound("~ sd ~ sd").gain(0.7),
|
|
hats: sound("hh*8").gain(0.3)
|
|
};
|
|
|
|
stack(instruments.kick, instruments.snare, instruments.hats);
|
|
|
|
// Async functions for dynamic content
|
|
const loadPattern = async () => {
|
|
const response = await fetch('/api/pattern');
|
|
const data = await response.json();
|
|
return sound(data.pattern);
|
|
};
|
|
|
|
loadPattern().then(pattern => pattern.gain(0.5));
|
|
```
|
|
|
|
#### Live Coding Effects
|
|
```javascript
|
|
// Instant filter sweep
|
|
$: sound("bd*4").lpf(sine.range(100, 2000).slow(4))
|
|
|
|
// Rhythmic gating
|
|
$: n("0 2 4 6").scale("C:minor").sound("piano").mask("1 0 1 1")
|
|
|
|
// Probability effects
|
|
$: sound("hh*8").sometimes(rev).often(x => x.gain(0.5))
|
|
```
|
|
|
|
### Agent Response Protocol
|
|
|
|
1. **Read documentation first** when unsure about syntax
|
|
2. **Provide working examples** that can be copy-pasted into REPL
|
|
3. **Use `$:` prefix** for anonymous patterns or named patterns with `:`
|
|
4. **Include muting options** with `_$:` for live performance
|
|
5. **Explain mini-notation** when using complex patterns
|
|
6. **Leverage JavaScript features** including variables, functions, loops, and custom logic
|
|
7. **Use `stack()`** for layering multiple patterns
|
|
8. **Test understanding** by referring to official examples and the examples/ directory
|
|
|
|
### Git Commit Guidelines
|
|
|
|
- **Use lowercase commit messages**: All commit messages must be written in lowercase
|
|
|
|
### Development Environment Guidelines
|
|
|
|
- **Never use global npm installs**: Avoid `npm i -g` or `npm install -g` commands
|
|
- **Use NixOS shells/dev environments**: Always prefer Nix-based development environments for reproducible builds
|
|
- **Current NixOS version**: 25.05
|
|
|
|
#### Git Submodules
|
|
|
|
The Strudel codebase is managed as a git submodule in the 'src' directory. To work with the codebase:
|
|
|
|
1. Initialize submodules: `make submodules-init`
|
|
2. Update submodules: `make submodules-update`
|
|
|
|
This ensures the correct version of the Strudel repository is checked out and kept in sync.
|
|
|
|
#### Nix Development Shell
|
|
|
|
Use the following `flake.nix` for Strudel development:
|
|
|
|
```nix
|
|
{
|
|
description = "Strudel development environment";
|
|
|
|
inputs = {
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
|
flake-utils.url = "github:numtide/flake-utils";
|
|
};
|
|
|
|
outputs = { self, nixpkgs, flake-utils }:
|
|
flake-utils.lib.eachDefaultSystem (system:
|
|
let
|
|
pkgs = nixpkgs.legacyPackages.${system};
|
|
in
|
|
{
|
|
devShells.default = pkgs.mkShell {
|
|
buildInputs = with pkgs; [
|
|
nodejs_20
|
|
pnpm
|
|
git
|
|
];
|
|
|
|
shellHook = ''
|
|
echo "Strudel development environment loaded"
|
|
echo "Node.js: $(node --version)"
|
|
echo "pnpm: $(pnpm --version)"
|
|
'';
|
|
};
|
|
});
|
|
}
|
|
```
|
|
|
|
#### Usage
|
|
|
|
**Option 1: Direct Nix commands**
|
|
1. **Enter development shell**:
|
|
```bash
|
|
nix develop
|
|
```
|
|
|
|
2. **Install dependencies**:
|
|
```bash
|
|
pnpm install
|
|
```
|
|
|
|
3. **Start development server**:
|
|
```bash
|
|
pnpm dev
|
|
```
|
|
|
|
**Option 2: Using Makefile (recommended)**
|
|
The Makefile provides convenient shortcuts for common development tasks. First, ensure submodules are initialized:
|
|
|
|
```bash
|
|
# Initialize and update submodules
|
|
make update
|
|
|
|
# Install dependencies
|
|
make install
|
|
|
|
# Start development server
|
|
make dev
|
|
|
|
# Run tests
|
|
make test
|
|
|
|
# Run linter
|
|
make lint
|
|
|
|
# Format code
|
|
make format
|
|
|
|
# Run all checks
|
|
make check
|
|
|
|
# Enter Nix shell directly
|
|
make shell
|
|
|
|
# Show help
|
|
make help
|
|
```
|
|
|
|
All Makefile commands automatically run within the Nix development environment.
|
|
|
|
### Live Performance Considerations
|
|
|
|
When creating beats for live performance:
|
|
|
|
- **Each `$:` line is independently controllable**
|
|
- **Use `_$:` to mute sections during performance**
|
|
- **Include modulation for evolving sounds**
|
|
- **Provide multiple variations/sections**
|
|
- **Keep patterns readable for live modification**
|
|
|
|
### Example Response Structure
|
|
|
|
```javascript
|
|
// Using JavaScript variables and functions
|
|
const tempo = 120;
|
|
const gain = 0.8;
|
|
|
|
setCps(tempo/60/4);
|
|
|
|
// Custom function for creating beats
|
|
const createBeat = (intensity = 1) => stack(
|
|
sound("bd*4").gain(gain * intensity),
|
|
sound("~ sd ~ sd").gain(0.7 * intensity),
|
|
sound("hh*8").gain(0.3 * intensity)
|
|
);
|
|
|
|
// Named patterns for live control
|
|
kick: sound("bd*4").gain(gain)
|
|
snare: sound("~ sd ~ sd").gain(0.7)
|
|
hats: sound("hh*8").gain(0.3)
|
|
bass: n("0 ~ 2 ~ 4 ~ 6 ~").scale("C2:minor").sound("sawtooth")
|
|
|
|
// MAIN BEAT - uncomment to play
|
|
// stack(kick, snare, hats, bass)
|
|
|
|
// LIVE VARIATIONS (comment/uncomment as needed)
|
|
// createBeat(0.5).lpf(sine.range(200, 2000).slow(8)) // filter sweep
|
|
// snare.mask("1 0 1 1") // gated snare
|
|
// hats.sometimes(rev).often(x => x.fast(2)) // probability effects
|
|
```
|
|
|
|
This structure allows for immediate use and live manipulation in the Strudel REPL environment.
|