Strudel
After several sleepless nights, I managed to put together the opening bars of Laufey's Lover Girl in strudel as part of an ongoing goal to learn strudel.
I'm out of practice on general javascript, music composition and ear training but was able to pull it through from a few sleepless nights from reading through the docs.
// Sounds right-ish
setcpm(88 / 4);
// Instrumentals
let main = "piano";
let vocal = "gm_pizzicato_strings";
// Common rhythms
let r_bossanova = "x@1 x@2 x@1 x@2 x@1 x@1 ~@1 x@1 x@2 x@2 x@2";
// Measure 1
let m1 = stack(
// Instrumentals
note("a#5@1 a#5@2 a5@1 a5@2 g#5@1 g#5@1 ~@1 g5@1 g5@2 f#5@2 f#5@2").gain(0.5),
note("[c#5,d#5]").struct(r_bossanova).gain(0.5),
).s(main);
// Measure 2
let m2 = stack(
// Vocal
note("~@13 c#4@2 d#4@3").s(vocal).gain(0.7),
// Instrumentals
s("clap").struct(r_bossanova).gain(0.5),
);
// Measure 3
let c1 = note("[d#4,b3,g#3,e3]");
let c2 = note("[c#3,a#3,g#3,e3]");
let m3 = stack(
// Vocal
note("~@3 c#4@2 b3@2 a#3@6 b3@2 a#3@2").s(vocal).gain(0.7),
// Instrumental
cat(c1, c2).struct("x@1 x@2 x@3 x@2").fast(2)
.s(main)
.gain(0.5),
);
// Measure 4
let m4 = stack(
// Vocal
note("~@1 b3@2 d#4@8 ~@1 b3@2 d#4@2").s(vocal).gain(0.7),
// Instrumental
stack(
note(
"~@1 [c#3,a#3,g#3,e3]@2 [c#3,a#3,g#3,e3]@3 [c#3,a#3,g#3,e3]@2 [c#3,a#3,g#3,e3]@1 [c#3,a#3,g#3,e3]@2 [c#3,a#3,g#3,e3]@3 [c#3,a#3,g#3,e3]@2",
),
note("b2@4!4"),
)
.s(main)
.gain(0.5),
);
// Use arrange to stitch the bars together with a rest at the end since this doesn't end at a loopable point
arrange(
[1, m1], [1, m2],
[1, m3],
[1, m4],
[2, note("~@16")],
);
Out of curiosity, I wanted to know if LLM assisted learning could be useful like it is with traditional software. Unsurprisingly, Opus 4.7 can't actually reproduce trademarked or copyrighted works which is how I personally learn a lot of music (replicate > recreate > strike out on your own.) It however is undeterred from producing some form of odd cacophony. No amount of prompting could get the bossanova rhythm correct either.
// Laufey — "Lover Girl" • Intro (mm. 1–2)
// Source: Vingolf Publishing piano/vocal score, arr. Ted Case (2025)
// B major • 4/4 • Bossa Nova ♩ = 88
// Two bars of BMaj7 vamping under claps + piano comp before Verse 1
setcpm(88/4)
stack(
// Claps — the ¿ x-noteheads in the top staff
s("cp")
.struct("1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0")
.gain(0.45)
.room(0.25),
// Piano right hand — BMaj7 voicing (B, D#, F#, A#) in bossa comping
note("d#4,f#4,a#4,b4")
.struct("1 0 1 1 0 1 0 1 0 1 1 1 0 1 1 0")
.s("piano")
.gain(0.55)
.room(0.3),
// Piano left hand — root B in bass with chromatic neighbor (the
// accidentals in the LH staff suggest passing tones between B and F#)
note("b2 ~ ~ [a#2 b2] f#3 ~ ~ a2 b2 ~ ~ [a#2 b2] f#3 ~ ~ a2")
.s("piano")
.gain(0.75)
)
Opus 4.7 does seem to do a bit better when asked to synthesize original works. e.g. use a current song as a base with some very well documented structural format (like an aria)
// ✦ Lover Girl × Bach ✦ (lullaby setting)
// Chord progression: Laufey's "Lover Girl" verse → chorus tail (transposed to G major)
// Melody: original Bach-aria-style line over those changes
// Tempo: bossa q=88 slowed to a cradle-rocking ~50 bpm
setcps(0.32)
// ─── BASS: chord roots, one per bar, sustained ───
let bass = note("<a2 d2 g2 g2 a2 d2 g2 e2>")
.sound("gm_acoustic_grand_piano")
.gain(0.55)
.room(0.55)
.attack(0.04)
.release(2.2)
// ─── INNER VOICES: jazz chord tones with Bach-style smooth voice leading ───
// Am7 → D7 → Gmaj7 → Gmaj7 → Am7 → D7 → Gmaj7 → E7
let pad = note("<[c4,e4,g4] [c4,d4,f#4] [b3,d4,f#4] [b3,d4,f#4] [c4,e4,g4] [c4,d4,f#4] [b3,d4,f#4] [b3,d4,g#4]>")
.sound("gm_music_box")
.gain(0.22)
.room(0.75)
.lpf(2500)
.attack(0.1)
// ─── MELODY: Bach-aria lyrical line, lullaby 6/8 feel ───
// Mostly stepwise. Arches up across phrase 1, descends across phrase 2.
// ~ = rest (breathing space)
let melody = note("<[b4 ~ c5 b4 a4 ~] [a4 ~ g4 f#4 ~ ~] [g4 ~ a4 b4 ~ ~] [d5 ~ b4 ~ g4 ~] [c5 ~ e5 d5 c5 ~] [b4 ~ a4 g4 ~ ~] [f#4 ~ g4 a4 ~ ~] [b4 ~ g#4 ~ e4 ~]>")
.sound("gm_celesta")
.gain(0.55)
.room(0.85)
.lpf(4500)
.attack(0.05)
.release(0.6)
stack(bass, pad, melody)