| name | strudel-music |
| description | Create Strudel live-coding music sketches and workflows, especially pop punk, grunge, and punk-inspired browser music patterns. |
| tags | ["strudel","music","live-coding","algorave","pop-punk","grunge","punk","creative"] |
| triggers | ["strudel","live coding music","make music with code","browser music pattern","algorave","pop punk beat","grunge riff","punk song sketch","code music"] |
| related_skills | ["songwriting-and-ai-music"] |
Strudel Music
Use this skill when the user wants music made with Strudel: browser-based live coding using the TidalCycles-style pattern language in JavaScript.
User taste note: lean toward pop punk, grunge, punk unless they ask otherwise. Prefer raw, hooky, energetic sketches over overly polished EDM. Think: fast drums, distorted power-chord energy, driving eighth-note bass, noisy leads, simple memorable hooks.
Main references:
Core mental model
Strudel patterns are short loops. Build from one good cycle, then layer and mutate.
Common primitives:
s("bd sd bd sd")
note("c3 eb3 g3").s("sawtooth")
stack(patternA, patternB)
setcpm(160/4)
Mini-notation essentials:
s("bd sd hh")
s("bd ~ sd ~")
s("hh*8")
s("[bd hh] sd")
s("<bd sd cp>")
s("bd(3,8)")
note("g3,b3,d4")
note("[g3,b3,d4] [a3,c4,e4]")
Useful modifiers:
.fast(2)
.slow(2)
.early(.02)
.late(.02)
.clip(.5)
.gain(.7)
.pan(.3)
.room(.2)
.delay(.125)
.lpf(1200)
.hpf(200)
.shape(.4)
.distort(.5)
.crush(6)
.bank("RolandTR909")
.n("0 1 2")
Important effects pitfall: many Strudel effects are effectively single-use in the signal chain. Repeating the same effect later can override the earlier value. Do not write .lpf(200).distort(.4).lpf(1200) expecting two filters. Use one deliberate value/pattern.
Default workflow
-
Set tempo and key/energy
- Pop punk: 150–190 BPM, major/minor power-chord movement, bright but rough.
- Punk: 170–220 BPM, simpler, faster, fewer fills.
- Grunge: 90–145 BPM, heavier, sludgier, minor/modal, more space.
-
Start with drums
- Kick/snare shape is the song’s spine.
- Add hats/ride only after the core beat hits.
-
Add bass
- Root notes, repeated eighths, octave jumps.
- Slight distortion, low-pass, short release.
-
Add guitar surrogate
- Use
sawtooth, square, or built-in GM electric guitar samples if available.
- Fake power chords with root + fifth + octave.
- Use
.shape(), .distort(), .crush(), .room() sparingly.
-
Add hook/lead
- 3–6 note motif. Repeat it. Vary it every 4th cycle.
-
Add arrangement changes
- Use
<...> to alternate sections.
- Use
.mask(), .sometimes(), .degradeBy(), .fast(), .slow() for fills and breakdowns.
-
Keep output runnable
- Give one complete Strudel block.
- Avoid imaginary APIs.
- Include comments, but not so many that they obscure the pattern.
Genre recipes
Pop punk sketch
Characteristics:
- 150–190 BPM
- kick/snare backbeat
- constant hats or ride
- root-fifth-octave power chords
- bass follows guitar roots
- bright hook, minimal jazz harmony
Chord moves that work:
- I–V–vi–IV: C G Am F
- vi–IV–I–V: Am F C G
- I–IV–V: C F G
- i–VI–III–VII for darker pop-punk: Em C G D
Starter:
setcpm(44)
stack(
s("bd [~ bd] sd [bd ~] bd [~ bd] sd [~ bd], hh*8")
.bank("RolandTR909")
.gain(.85),
note("<c2 g1 a1 f1>*8")
.s("sawtooth")
.clip(.35)
.lpf(900)
.shape(.25)
.gain(.55),
note("<[c3,g3,c4] [g2,d3,g3] [a2,e3,a3] [f2,c3,f3]>")
.s("sawtooth, square:0:.35")
.clip(.85)
.distort(.45)
.hpf(120)
.room(.18)
.gain(.45),
note("<e4 g4 a4 g4 [e4 d4] c4 d4 ~>")
.s("square")
.clip(.25)
.delay(.125)
.room(.25)
.gain(.28)
)
Punk sketch
Characteristics:
- 180–220 BPM
- simple three-chord riff
- fewer effects, more velocity/urgency
- drums should feel relentless
setcpm(50)
stack(
s("bd sd bd sd, hh*8")
.bank("RolandTR909")
.gain(.9),
note("<e2 e2 g2 a2>*8")
.s("sawtooth")
.clip(.25)
.shape(.35)
.lpf(1000)
.gain(.55),
note("<[e3,b3,e4] [e3,b3,e4] [g3,d4,g4] [a3,e4,a4]>")
.s("sawtooth")
.clip(.45)
.distort(.65)
.hpf(140)
.gain(.5),
note("<e4 ~ g4 a4>*2")
.s("square")
.clip(.18)
.crush(7)
.gain(.25)
)
Grunge sketch
Characteristics:
- 90–145 BPM
- half-time or heavy backbeat
- minor key / modal riffs
- fuzz, low-pass, noisy space
- verse can be sparse, chorus can explode
setcpm(30)
stack(
s("bd ~ ~ ~ sd ~ bd ~, hh*8")
.bank("RolandTR909")
.gain(.85),
note("<e2 e2 g2 e2 [d2 e2] ~ g1 ~>*2")
.s("sawtooth")
.clip(.5)
.lpf(650)
.shape(.5)
.gain(.6),
note("<[e3,b3,e4]@2 [g3,d4,g4] [d3,a3,d4] [c3,g3,c4]>")
.s("sawtooth, square:0:.4")
.clip(1)
.distort(.7)
.lpf(1800)
.room(.3)
.gain(.48),
note("<g4 ~ e4 [d4 e4] ~ b3>*2")
.s("triangle")
.clip(.4)
.delay(.25)
.room(.45)
.gain(.25)
)
Arrangement patterns
Use angle brackets to alternate sections across cycles:
s("<bd sd bd sd, bd ~ sd ~>")
Use section comments and masks:
stack(
s("bd [~ bd] sd [bd ~], hh*8"),
note("<c2 g1 a1 f1>*8").s("sawtooth"),
note("e4 g4 a4 g4").s("square").mask("<0 1 1 1>")
)
Useful rock arrangement template:
Practical methods:
.mask("<0 1 1 1>") to introduce a layer after the first cycle.
.sometimesBy(.25, x => x.fast(2)) for occasional fills.
.degradeBy(.2) for missing notes / human looseness.
.early(.01) or .late(.01) for feel, especially hats/snares.
.gain("<.4 .5 .7 .6>") to create section dynamics.
AI-assisted Strudel workflow
When asked to use AI to help write Strudel:
-
Ask or infer:
- genre/subgenre
- BPM
- mood
- key/chord progression
- number of sections
- whether the output should be beginner-friendly or performance-ready
-
Generate a minimal runnable seed first:
- one
setcpm
- one
stack(...)
- drums + bass + chord/riff + optional lead
-
Then produce 3 variation prompts for iteration:
- “make drums more frantic”
- “make chorus brighter”
- “make verse grungier and sparse”
-
If using an LLM to create code, constrain it:
Write runnable Strudel code only. Use core functions: setcpm, stack, s, note, n, scale, chord, voicing, fast, slow, clip, gain, bank, room, delay, lpf, hpf, shape, distort, crush, mask, sometimesBy. Avoid undocumented APIs. Keep it under 80 lines. Genre: pop punk / grunge / punk.
Debugging and cleanup
If the pattern is broken:
- Check quotes and parentheses first.
- Make sure
stack(...) items are comma-separated.
- If a melody is too busy, reduce notes before adding effects.
- If it clips/distorts badly, lower
.gain() on every layer before changing effects.
- If drums are missing, try removing
.bank(...) because some banks lack some samples.
- Strudel’s GM soundfont samples include realistic instrument names such as
gm_electric_guitar_muted, gm_overdriven_guitar, gm_distortion_guitar, and gm_electric_bass_pick. These are registered by @strudel/soundfonts; use them with note(...).s("gm_distortion_guitar") / note(...).s("gm_electric_bass_pick"). They load WebAudioFont data from https://felixroos.github.io/webaudiofontdata/sound/*.js; default usable files include 0300_FluidR3_GM_sf2_file for distortion guitar, 0290_FluidR3_GM_sf2_file for overdriven guitar, 0280/0281_* for muted guitar, and 0340_FluidR3_GM_sf2_file for picked bass. If rendering outside Strudel, these JS files contain base64 MP3 zones that can be extracted and sequenced directly.
- If guitar sample names fail, use synths (
sawtooth, square, triangle) instead of relying on sample availability.
- If modulation sounds static, add
.seg(16) before parameter modulation where appropriate, because some params are sampled only on events.
Good gain starting points:
- drums
.gain(.75-.9)
- bass
.gain(.45-.65)
- chords
.gain(.35-.55)
- lead
.gain(.2-.35)
Avoid:
- 10 layers in the first draft.
- Jazz chords unless requested.
- Too much reverb for punk.
- Over-randomizing: punk needs commitment, not generative mush.
- Fake artist-name imitation. Describe genre and production traits instead.
Response format when generating Strudel
Use this structure:
- One-sentence concept.
- Complete Strudel code block.
- “Tweak knobs” list with 3–5 obvious edits.
- Optional next variation.
Example:
Here’s a fast pop-punk Strudel sketch: backbeat drums, eighth-note bass, power-chord synth guitar, and a simple square-wave hook.
```js
...
Tweak knobs:
- Faster: raise
setcpm(44) to setcpm(48).
- Dirtier: raise
.distort(.45) on the chord layer.
- More grunge: lower tempo and change progression to
Em C G D.
---
## Educational use
For kids/teens or beginner workshops:
- Start with `s("bd sd")`.
- Add `hh*8`.
- Change one thing at a time.
- Treat code as a sequencer, not programming theory.
- Have learners remix genre knobs: tempo, drums, bass root, instrument sound.
Beginner ladder:
```js
s("bd sd")
s("bd sd, hh*8")
stack(s("bd sd, hh*8"), note("c2 g1 a1 f1").s("sawtooth"))
Then explain:
- spaces = sequence
- comma = together
*8 = repeat
~ = silence
<> = alternate