# 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 "" // 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 "".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("*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.