Strudelify

Lili Was Here

David A. Stewart

KeyE minorTempo110 bpm
0:00/0:00
// Lili Was Here — David A. Stewart
// 110 bpm, 4/4, key E minor. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: ch 1 "guitar" named as a guitar, played on electric guitar clean (its harpsichord patch is not one)
// note: duplicate parts dropped: ch 5 acoustic guitar steel (copy of ch 1 "guitar" electric guitar clean)
// note: Full arrangement: all 116 bars on a 16-step grid, each part at one level. Source detail keeps the original performance.
setcpm(110/4)

// Notation: c3@3 lasts 3 steps · ~ is a rest · [c3,e3] is a chord · "a, b" plays two voices at once · [...]/2 spreads a riff over 2 bars.
// A part's distinct bars are riffs (A, B, C...) played in order: edit a riff to change every repeat.

// chords · electric guitar clean · "guitar"
const electric_guitar_clean = note(`<
  ~@13 A@2 ~@2 B@4 C@2 ~@2 D@4 E@2 ~@2 F@3 ~ G@3 ~ H@4 I J K ~ L@2 M N@2 O P Q R S T U V W X Y Z AA AB@2 A@2 ~@2 AC@4
  A@2 ~@2 AC@4 AD@2 ~@2 AE@3 AF G@3 ~ H@4 AG@2 ~ AH AI AJ AK ~ AL@2 AM@2 ~@3
>`.pickRestart({
  A: "[~@4 b3@2 g3@6 a3@2 e3@17 ~]/2", B: "[~@4 b3@2 g3@6 a3@2 e3 f#3@8 ~@3 g3@2 f#3@2 e3@21 ~@13]/4",
  C: "[~@2 b3 g3@3 a3 e3@8 ~]/2", D: "[~@4 b3@2 g3@6 a3@2 e3@12 g3@2 f#3@2 e3@27 ~@7]/4",
  E: "[~@2 e4@2 g4@2 d5@4 e4@4 g4@17 ~]/2", F: "[~@2 e4@2 g4@2 d5@4 e4@4 a4@8 b4@25 ~]/3",
  G: "[~@2 b4@2 g5@2 g5@4 f#5@4 b4@19 ~@15]/3", H: "[~@2 b4@2 g5@2 g5@4 f#5@4 f#5@4 e5@4 e5@4 d5@3 ~ d5@27 ~@7]/4",
  I: "~@4 [e4,g4,d5] ~ [e4,g4,d5] ~@9", J: "~@10 [a3,d4] [b3,e4] [d4,g4]@2 [a3,d4]@2", K: "[b3,e4]@3 ~@13",
  L: "[f#4@2 ~@4 d5@8 [d4,a4]@13 ~@5, ~@2 d4@11 ~@19, ~@4 f#4@23 ~@5]/2", M: "[e4,g4,d5]@2 [e4,g4,d5]@11 ~@3",
  N: "[~@14 [e4,g4,d5]@14 ~@2 [e4,g4,d5] ~]/2", O: "[e4,g4,d5]@9 ~ [e4,g4,d5] ~ [e4,g4,d5] [e4,g4,d5]@2 ~",
  P: "~@4 [a3,c4,g4] ~ [a3,c4,g4]@8 ~@2", Q: "~ [a3,c4,g4]@2 ~", R: "[b3,d4,a4]@10 ~@4 [b3,d4,a4] ~",
  S: "[b3,d4,a4]@7 ~@9", T: "~@2 [e4,g4,d5]@4 ~@2 [e4,g4,d5]@7 ~",
  U: "~@2 [e4,g4,d5] ~ [e4,g4,d5] ~ [e4,g4,d5] ~ [e4,g4,d5] ~ [e4,g4,d5] ~ [e4,g4,d5] ~ [e4,g4,d5]!2", // Em7
  V: "~@4 [e4,g4,d5] ~ [e4,g4,d5] ~@5 [e4,g4,d5] ~@3", W: "~@4 [e4,g4,d5] ~@7 [e4,g4,d5] ~@3",
  X: "~@4 [a3,c4,g4] ~ [a3,c4,g4] ~@5 [a3,c4,g4] ~@3", Y: "~@4 [a3,c4,g4] ~@7 [a3,c4,g4] ~@3",
  Z: "~@4 [b3,d4,a4] ~ [b3,d4,a4] ~@5 [b3,d4,a4] ~@3", AA: "~@4 [b3,d4,a4] ~@7 [b3,d4,a4] ~@3",
  AB: "[e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~", // E5
  AC: "[~@4 b3@2 g3@6 a3@2 e3@12 g3@2 f#3@2 e3@21 ~@13]/4", AD: "[~ e4 g4 d5@2 e4@2 g4@8 ~]/2",
  AE: "[~@2 e4@2 g4@2 d5@4 e4@4 a4@8 ~@10 [e3,b3,e4] ~ [e3,b3,e4]@3 ~ [e3,b3,e4]@3 ~ [e3,b3,e4]@3 ~ [e3,b3,e4]@2, ~@22 b4@25 ~]/3", // E5
  AF: "~@2 [e3,b3,e4]@3 ~ [e3,b3,e4]@3 ~ [e3,b3,e4] ~ [e3,b3,e4]@3 ~", AG: "[~@4 g4 e4 d4 e4 g4 e4@12 ~@11]/2",
  AH: "~@10 [e4,f#4,a4,b4] ~ [f#4,b4,e5]!4", AI: "[f#4,b4,e5] ~@6 e4", AJ: "g4 ~ b4@2 e4@2 ~@10",
  AK: "~@10 d5 e5 e5@3 ~", AL: "e5 e5@4 ~@3", AM: "[~@2 a4 g4 e4 ~ e4 ~ a4 g4 e4 ~ e4@8 ~@12]/2",
})).s("gm_electric_guitar_clean").gain(0.4).pan(0.4)

// bass · fretless bass · "bass"
const bass = note(`<
  ~@2 A B C B C B D E C F G E H B I J C K L E M E C J C J N B H O M P H J Q B H P C P H J R E S T C U G V W B X Y Z E G
  AA AB E G AC E@2 G AD B E C J C J G E AE E H J E@2 G E AF E C P D J E J AG AH AI AJ AK AL AK AM AN AO AK AJ AK AL AK
  AM AP AQ AR AJ AS ~@3
>`.pickRestart({
  A: "~@5 b1 d2@2", B: "e2@2 e2 ~@3 e2 ~@3 e2 ~ g2 ~ e2 ~", C: "d2@2 e2 ~@3 e2 ~@3 e2 ~ d2 ~ e2 ~",
  D: "d2@2 e2 ~@3 e2 ~@3 b1@2 d2@2 b1@2", E: "d2@2 e2 ~@3 e2 ~@3 e2 ~ g2 ~ e2 ~",
  F: "g2 ~ b2 ~@3 e2 ~@3 e2 ~ g2 ~ b2 ~", G: "d2@2 e2 ~@3 e2 ~@3 e2 ~ g2 ~ b2 ~",
  H: "a2@2 e2 ~@3 e2 ~@3 e2 ~ d2 ~ e2 ~", I: "d2@2 e2 ~@3 e2 ~@3 e2 ~ a2 ~ e2 ~",
  J: "b2@2 e2 ~@3 e2 ~@3 e2 ~ g2 ~ e2 ~", K: "g2@2 b2 ~@3 e2 ~@3 e2 ~ g2 ~ b2 ~",
  L: "d2@2 e2 ~@3 b1@2 d2@2 b1@2 e2@2 b1 ~", M: "a2@2 e2 ~@3 e2 ~@3 e2 ~ a2 ~ e2 ~",
  N: "e2 ~ e2@2 d2@2 b1@2 d2@2 b1@2 d2@2 d2@2", O: "b2 ~ e2 ~@3 b2 ~@3 e2 ~ g2 ~ e2 ~",
  P: "g2@2 e2 ~@3 e2 ~@3 e2 ~ g2 ~ e2 ~", Q: "d2@2 e2 ~@3 b1 ~ d2@2 b1@2 d2@3 ~", R: "d2@2 e2 ~@3 e2 ~@3 b1 ~ d2@3 ~",
  S: "d2@2 e2 ~@3 e2 ~@3 e2 ~ g2 ~ d2 ~", T: "e2 ~ e2 ~@3 e2 ~@3 e2 ~ g2 ~ e2 ~",
  U: "b2@2 e2 ~@3 e2 ~@3 e2 ~ g2 ~ b2 ~", V: "e3@2 e3@2 g2 ~ e2 ~@3 e2 ~ d2 ~ e2 ~",
  W: "d2@2 e2 ~@3 e2 ~@3 b1 ~ d2@2 d#2 ~", X: "d2@2 e2 ~@3 e2 ~@3 e2 ~ g2@2 e2@2",
  Y: "a2 ~ a2 ~@3 e2 ~@3 e2 ~ d2 ~ e2 ~", Z: "d2@2 e2 ~@3 b2 ~@3 e2 ~ d2@2 e2 ~",
  AA: "e3 ~ e3@2 ~@2 e2 ~@3 e2 ~ g2 ~ e2 ~", AB: "d2 ~ e2 ~@3 e2 ~@3 e2 ~ g2 ~ e2 ~",
  AC: "a2@2 a2 ~@3 a2 ~@3 a2 ~ g2 ~ e2 ~", AD: "e3 ~ e3 ~@3 e2 ~@3 e2 ~ g2 ~ e2 ~",
  AE: "d2 ~ e2 ~@3 b1@2 d2@2 b1@2 d2@2 d#2 ~", AF: "d2@2 e2 ~@3 e2 ~ g2@2 e2@2 f#2@2 e2 ~",
  AG: "d2@2 e2 ~@3 b1@2 d2@2 b1@2 d2@2 e2 ~", AH: "d2@2 e2 ~@3 e2@2 d2@2 e2 ~ e2 ~ e2 ~", AI: "~ e2 g2 e2 b2 e2 g2 e2",
  AJ: "g2@2 e2 ~@3 e2 ~@3 e2@2 g2@2 e2@2", AK: "d2@2 e2 ~@3 e2 ~@3 e2@2 d2@2 e2@2",
  AL: "b2@2 e2 ~@3 e2 ~@3 e2@2 g2@2 e2@2", AM: "g2@2 b2 ~@3 e2 ~@3 e2@2 g2@2 b2@2",
  AN: "d2@2 e2 ~@3 e2@2 g2@2 e2@2 f#2@2 e2 ~", AO: "d2@2 e2 ~@3 e2@2 g2@2 e2@2 g2@2 e2@2",
  AP: "d2@2 e2 ~@3 e2@2 b2@2 e2@2 g2@2 e2 ~", AQ: "d2@2 e2 ~ e2 ~ e2 ~@3 e2 ~@3 e2 ~",
  AR: "e2 ~ e2 ~@3 e2@2 g2@2 e2@2 f#2@2 e2@2", AS: "d2@2 e2 ~@3 e2 ~ e2 ~ e2 ~ d2@2 ~@2",
})).s("gm_fretless_bass").gain(0.45)

// chords · string ensemble 1 · "strings"
const string_ensemble_1 = note("<~@3 A@2 B@8 C@96 D@7>".pickRestart({
  A: "[e4,g4,b4,e5]/2", B: "[[g4,b4] c5 [f#4,d5] [e4,g4,b4,e5], [e4,e5]@64 f#5@31 ~@33, ~@32 a4@65 ~@31]/8",
  C: "[[g4,b4] c5 [f#4,d5] [e4,g4,b4,e5], e5@64 f#5@31 ~@33, ~@32 a4@65 ~@31]/8", // G D Em
  D: "[[g4,b4]@32 a4@65 ~@15, e5@4 ~@3, ~@2 c5@2 ~@3]/7", // G
})).s("gm_string_ensemble_1").gain(0.2)

// drums · kick
const kick = s("bd").struct("<~ [x!2]!112 ~@3>").gain(0.45)

// drums · rim
const rim = s("rim").struct(`<
  A ~ B ~ B C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D
  C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D C D ~@3
>`.pickRestart({
  A: "x!4", B: "~ x ~@2 x ~@3", C: "x!2", D: "x!2 ~@2 x ~@3",
})).gain(0.35)

// drums · clap
const clap = s("cp").struct("<~@45 A B@15 A B@15 A B@15 A B@15 A B@3 ~@3>".pickRestart({
  A: "~@3 x", B: "~ x ~ x",
})).gain(0.45)

// drums · snare
const snare = s("sd").struct("<~ [~ x ~ x]!112 ~@3>").gain(0.45)

// drums · low tom
const low_tom = s("lt").struct("<~@44 [~@3 x] ~@71>").gain(0.45)

// drums · hihat
const hihat = s("hh").struct("<~ [~ x ~ x ~ x ~ x]!112 ~@3>").gain(0.45)

// drums · mid tom
const mid_tom = s("mt").struct("<~@44 [~@5 x ~@2] ~@71>").gain(0.45)

// drums · open hat
const open_hat = s("oh").struct(`<
  ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~
  A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~@4
>`.pickRestart({
  A: "~ x ~@2",
})).gain(0.45)

// drums · crash
const crash = s("cr").struct("<~@5 A ~@15 A ~@15 A ~@14 B ~@16 A ~@6 B ~@8 A ~@6 B ~@8 A ~@6 B ~@7>".pickRestart({
  A: "x", B: "~@7 x",
})).gain(0.45)

stack(electric_guitar_clean, bass, string_ensemble_1, kick, rim, clap, snare, low_tom, hihat, mid_tom, open_hat, crash)