Take the shape of Lewis’s Blue Monday Strudel template: two kicks, two hat
patterns, a layered snare, two bass parts, and a final stack of arrange calls.
Move it toward Heat Waves by Glass Animals with a slower pulse, soft chord
plucks, spaces between the bass notes, and a hook that opens up in the chorus.
This is an instrumental adaptation with its own melody and a shortened song form.
In Dave Bayley’s breakdown of Heat Waves, he describes leaving space for the voice between pitched guitar layers and keeping the verse intimate before enlarging the chorus. That change in density is the idea to borrow here.
Press Play for the whole arrangement. Drum samples load from GitHub on first play; the chords, bass, and lead are synthesized.
/*
@title Heat Waves inspired instrumental
@by BoWen Chai
Arrangement structure adapted from Lewis's Blue Monday cover / remix.
*/
await samples('https://raw.githubusercontent.com/felixroos/dough-samples/main/tidal-drum-machines.json')
setcpm(91/4)
const kick1 = sound("bd ~ [~ bd] ~").bank("LinnDrum").decay(.15).gain(.55)
const kick2 = sound("bd [~ bd] [~ bd] [bd ~]").bank("LinnDrum").decay(.18).gain(.6)
const hats1 = sound("hh*8").bank("OberheimDMX").decay(.045).gain("[.09 .05]*4")
const hats2 = stack(
hats1,
sound("~ oh ~ [~ oh]").bank("OberheimDMX").decay(.12).gain(.07)
)
const snare = stack(
sound("~ sd ~ sd").bank("LinnDrum").decay(.12).gain(.28),
sound("~ cp ~ cp").bank("LinnDrum").decay(.1).gain(.09)
)
const drums1 = stack(kick1, hats1, snare)
const drums2 = stack(kick2, hats2, snare)
const drums3 = stack(kick1, hats1.gain(.04))
const fill = stack(
kick1, hats2,
sound("~ sd ~ [sd sd*2]").bank("LinnDrum").decay(.1).gain(.2)
)
// Emaj7 -> D#7 -> G#m7 -> F#add9, one chord per bar.
const harmony = note("<[e3,g#3,b3,d#4] [d#3,g3,a#3,c#4] [g#3,b3,d#4,f#4] [f#3,a#3,c#4,g#4]>")
const chords1 = harmony.struct("x ~ x [~ x]").sound("triangle")
.attack(.005).decay(.22).sustain(0).release(.12).lpf(1500).gain(.12)
const chords2 = stack(
chords1.lpf(2800),
harmony.sound("sawtooth").attack(.12).sustain(.35).release(.3).lpf(900).gain(.035)
)
const roots = note("<e2 d#2 g#1 f#1>")
const bass1 = roots.struct("x ~ [~ x] ~").sound("sine")
.attack(.01).decay(.2).sustain(.3).release(.08).gain(.32)
const bass2 = roots.struct("x [~ x] [~ x] x").sound("sine, triangle")
.attack(.01).decay(.25).sustain(.45).release(.1).lpf(450).gain(.2)
const synth = note("<[b4 ~ g#4 [~ f#4]] [a#4 ~ g4 [~ d#4]] [b4 d#5 ~ [b4 g#4]] [a#4 ~ g#4 f#4]>")
.sound("triangle").attack(.02).decay(.2).sustain(.15).release(.18)
.lpf(2400).gain(.13)
// Each row: intro, verse, lift, chorus, verse, breakdown, chorus, outro, rest.
stack(
arrange(
[4,silence], [8,drums1], [3,drums1], [1,fill], [8,drums2],
[8,drums1], [4,drums3], [7,drums2], [1,fill], [4,silence], [1,silence]
).room(.08).orbit(0),
arrange(
[4,chords1.lpf(700)], [8,chords1], [4,chords1.lpf(2200)], [8,chords2],
[8,chords1], [4,chords1.lpf(700)], [8,chords2], [4,chords1.lpf(700)], [1,silence]
).room(.22).orbit(1),
arrange(
[4,silence], [8,bass1], [4,bass1], [8,bass2],
[8,bass1], [4,silence], [8,bass2], [4,silence], [1,silence]
).orbit(2),
arrange(
[4,silence], [8,silence], [4,synth.gain(.06)], [8,synth],
[8,silence], [4,silence], [8,synth], [4,silence], [1,silence]
).delay(.18).delaytime(60/91/2).room(.18).orbit(3)
)
Follow the arrangement
One cycle is one four-beat bar: setcpm(91/4) sets this arrangement to 91 BPM.
Each arrange entry gives a
duration in bars and the pattern to play during it.
| Bars | Section | What changes |
|---|---|---|
| 1–4 | Intro | Filtered chord plucks establish the harmony. |
| 5–12 | Verse | Sparse kick, closed hats, snare, and short bass enter. |
| 13–16 | Lift | The plucks brighten, a quiet hook enters, and a fill leads into the chorus. |
| 17–24 | Chorus | Extra kick notes, open hats, sustained chords, and thicker bass support the hook. |
| 25–32 | Verse | The hook and sustained chords drop away. |
| 33–36 | Breakdown | Bass and snare disappear; dark plucks sit over a quiet beat. |
| 37–44 | Final chorus | The full stack returns, with a fill in its last bar. |
| 45–48 | Outro | Only filtered chord plucks remain. |
| 49 | Rest | No new notes; effect tails decay before the arrangement repeats. |
The full pass lasts about 2 minutes 9 seconds, including the rest. Press
Stop to end playback; the final silence is a pause inside the loop.
Change the feel
Keep the snare on beats two and four and let the kick move around it. The slower
tempo and gaps in kick1 and bass1 create the relaxed pocket. bass2 adds a
triangle layer for a more audible chorus bass, while chords2 fills the space
behind the short plucks.
Try setcpm(86/4) for a heavier sway or setcpm(96/4) for more forward motion;
match the 91 in delaytime(60/91/2) to the new tempo to keep the echo on eighth
notes. Lower the chorus pad’s .gain(.035) if it masks the plucks. To hear only
the chorus while editing, replace the final stack with
stack(drums2, chords2, bass2, synth).
The explicit sample load and full bank names make the Linn and DMX drums work
in this page’s player. See Strudel’s
sample and bank reference.
Keep the sample URL in single quotes: double quotes and backticks are parsed
as musical mini-notation, while single quotes pass a plain string.
The template’s ._pianoroll() is an editor visualization; this page uses its
own Play and Stop controls, so the runnable block ends with the pattern itself.