Strudelify

It Must Have Been Love

Roxette

KeyC majorTempo80 bpm
0:00/0:00
// It Must Have Been Love — Roxette
// 80 bpm, 4/4, key C major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: Full arrangement: all 87 bars on a 16-step grid, each part at one level. Source detail keeps the original performance.
setcpm(80/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 · piano · "Piano (upper)"
const piano = note("<A B C D ~@6 E F ~@4 G@2 ~ H ~@14 I J ~@10 K@2 ~@3 L ~@15 M N ~@15 O ~@2>".pickRestart({
  A: "c5 d5 e5 g5@5", B: "c5 d5 e5 a5@2 e5@2 c5", C: "f5@5 ~ f5@2", D: "d5 ~", E: "~@6 e5 c5", F: "f5@3 ~@5",
  G: "[~@5 g4 b4 ~ g5@3 ~@5, ~@7 e5@4 ~@5]/2", H: "b4@4 ~@2 b4@4 c5@2 d5@3 ~", I: "~@7 g5, ~ g4, ~@5 b4@3, ~@3 d5",
  J: "a5 b5@9 ~@6",
  K: "[~ a5 ~@2 a5 ~ c6 a5 ~ a5 ~@2 a5 ~@2 a5, c6@4 e5@5 ~ e5@8 ~@2 e5@5 ~ e5@6, ~@6 c6@5 ~@5 c6@5 ~ c6@5 ~ c6@4]/2",
  L: "~@3 b4@2 c5 d5@2", M: "b4@2 ~ b4@2 c5 d5@2", N: "e5@3 ~@5", O: "~ e5@2 f5 ~ c5@3, g5, ~ e5",
})).s("gm_piano").gain(0.6)

// chords · piano · "Piano (lower)"
const piano_2 = note(`<
  A B C D E F G H I J K L M N O P Q R S T U V W X Y@2 Z AA AB AC AD AE AF@2 AG@2 E F G H I J K L M N AH P Q R AI T U V W
  X AJ@2 Z AA AB AC AD AE AK AL AM AN AO AP AQ AR AS AT AU AV J AW AX@2 AY AZ BA BB BC@2 ~
>`.pickRestart({
  A: "~@6 e4@9 ~, ~@2 g3@13 ~, ~@4 c4@11 ~", B: "~@3 a3, ~ a3@4 ~@3, ~ c4@3, ~@3 e4@5",
  C: "~@2 a3@4 c4@5 ~ [a3,c4]@4, f3", D: "[g3,b3,d4]@3 ~", E: "~@6 [g3,c4]@5 ~ [g3,c4]@4, c3@13 ~@3, ~ e3@3 ~@4",
  F: "~@3 [g3,c4]@2 ~ [g3,c4]@2, c3@13 ~@3, ~@2 e3@7 ~@7", G: "~@3 e3@2 ~@2 e3, a2@7 ~, ~ c3@7, ~@5 a3@3",
  H: "~@6 [e3,a3]@3 ~@3 [e3,a3]@4, a2@3 ~, ~ c3@5 ~@2", I: "~ e3@2 g3@2 ~ [g3,c4]@2, c3@7 ~, ~@5 e3@2 ~",
  J: "~ e3@2 g3@2 e3 g3@2, c3@3 ~", K: "~@6 e3@3 ~@3 e3@3 ~, a2@7 ~, ~@2 c3@13 ~",
  L: "f3 ~ f3@2 ~@2 [c3,a3]@2, c3@3 ~, ~@5 f3@3", M: "g3 e3@2 [g3,c4]@2 ~ [g3,c4]@2, c3@13 ~@3",
  N: "~@2 e3@2 g3@5 ~ e3@2 [g3,c4]@4, c3@13 ~@3", O: "~@3 a3, a2@7 ~, ~ c3@6 ~, ~@3 e3@4 ~",
  P: "~ e3 ~ a3, a2@7 ~, ~ c3@6 ~, ~@5 e3@2 ~", Q: "~@3 b3@2 ~ g3@2, e3@4 ~ e3@2 ~, ~ g3@4 ~@3",
  R: "~ g3 ~ [g3,b3]@2 ~ [g3,b3]@2, e3", S: "~@3 c4@2 ~ c4 a3, f3@5 ~ f3@2, ~@2 a3@7 ~@7",
  T: "d4 b3@2 ~@3 g3 ~, g3@2 ~ [g3,d4]@3 ~@2, ~@5 b3@3", U: "~@4 g3@5 ~@3 g3@4, c3@3 ~, ~ e3@7",
  V: "~@4 g3@7 ~ [c3,e3]@2 ~@2, c3@5 ~@3, ~ e3@4 ~ g3@2", W: "~@6 d3@5 ~ b2@2 d3@2, g2@7 ~, ~ b2@4 ~@3",
  X: "~@6 b2 ~@5 d3@4, g2@13 ~@3, ~ b2@2 ~@2 b2@2 ~, ~@4 d3@7 ~@5",
  Y: "[~@6 a3@6 c3@2 ~@6 e3@5 ~@3 e3@4, a2@7 ~ a2@7 ~, ~@2 c3@6 ~@10 c3@7 ~@7, ~@2 e3@4 ~ a3@2 ~@7]/2",
  Z: "~@2 a3@3 ~ [f3,c4]@4 f3@2 a3@2 f3@2, f3@5 ~@11", AA: "~ a3 ~ a3, d3@6 ~@2 d3@5 ~@3, ~@2 f3@7 ~ f3@6",
  AB: "~ e3@2 [g3,c4]@2 e3 [g3,c4]@2, c3@3 ~", AC: "~ e3 ~ c4@2 ~ [g3,c4]@2, c3, ~@2 g3@3 e3@3",
  AD: "~@3 d3@3 b2 d3, g2@7 ~, ~ b2@4 ~@3", AE: "~ b2 d3@3 ~ d3@2, g2@13 ~@3, ~@5 b2@2 ~",
  AF: "[~@2 c3@4 e3@4 c3@2 ~@6 c3@4 [e3,a3]@5 ~ [e3,a3]@4, a2@6 [e3,a3]@3 ~@7, ~@16 a2@13 ~@3]/2", // A5
  AG: "[~@5 d4@9 ~@2, g2@2 b3@5 ~, ~ b2@13 ~@2, ~ d3@6 ~, ~@3 g3@11 ~@2]/2",
  AH: "~@3 a3, a2@13 ~@3, ~ c3@6 ~, ~@3 e3@4 ~", AI: "~@3 c4@2 ~ c4 a3, f3@9 ~@3 f3@4, ~@2 a3@7 ~@7",
  AJ: "[~@6 a3@6 c3@2 ~@6 e3@5 ~@3 e3@4, a2@7 ~ a2@4 ~@4, ~@2 c3@6 ~@10 c3@7 ~@7, ~@2 e3@4 ~ a3@2 ~@7]/2",
  AK: "~@2 g3@2 b3@5 ~ g3@2 b3@4, e3@3 ~", AL: "~@2 g3@2 ~@2 g3 ~ b3@2 ~@2 e3@4, e3@11 ~@5, ~@8 g3 ~ g3@4 ~@2",
  AM: "~ a3 ~ [a3,c4]@2 ~ a3 c4, f3@7 ~@3 f3@6", AN: "[g3,b3]@4 b3 ~ [g3,b3]@4 c4@2 [g3,d4]@4",
  AO: "e3 ~@2 g3@2 e3 g3@2, c3@13 ~@3, ~ e3@3 ~@4", AP: "~ e3 g3@3 e3 g3@2, c3@11 ~ c3@2 ~@2",
  AQ: "~ c3@2 e3@2 c3@2 e3, a2@15 ~", AR: "~ c3@2 e3@2 c3 [e3,a3]@2, a2@13 ~@3",
  AS: "~@6 g3@4 e3 ~ g3@4, c3@3 ~@2 c3@2 ~, ~@2 e3@8 ~ e3@5", AT: "~@2 g3@3 c3 [e3,g3]@2, c3 ~@3, ~ e3@4 ~@3",
  AU: "~ c3@2 e3@2 c3 ~ c3, a2@3 e3", AV: "~@2 a3@2 ~@2 a3 ~, c3@7 ~, ~@2 f3@5 ~@9",
  AW: "~@2 e3 ~ [e3,g3]@6 c3@2 [e3,g3]@4, c3 ~", // Em
  AX: "[~@2 c3@4 e3@4 c3@2 [e3,a3]@2 ~@4 c3@4 [e3,a3]@4 c3@2 [e3,a3]@3 ~, a2@13 ~ e3@4 ~@14, ~@16 a2@13 ~@3]/2", // A5
  AY: "~ g3@2 [e3,b3]@2 g3 e3 g3, e3 ~@3", AZ: "~@2 g3 ~ [g3,b3]@6 ~@2 [g3,b3]@4, e3@7 ~@3 e3@6",
  BA: "f3@2 a3@4 ~@2 [a3,c4]@3 ~ c4@2 a3@2, ~@3 f3@5, ~@12 a3 ~@3", BB: "~ d4@15, [g3,b3]",
  BC: "[~@7 c4@17 ~@8, c3@23 ~@9, ~@2 e3@21 ~@9, ~@4 g3@19 ~@9]/2",
})).s("gm_piano").gain(0.56)

// chords · synth strings 1 · "Chords (syn strings)"
const synth_strings_1 = note(`<
  ~@4 A@8 B@7 C@5 D@5 E F@2 G@2 H@2 A@8 B@7 C@5 D@5 E F@2 I@2 J K A@8 L@7 M@3 ~
>`.pickRestart({
  A: "[g4@2 a4@2 g4@2 ~ f4, c5, e5@7 ~, ~@3 a4]/8", B: "[g4@2 a4@2 [g4,b4]@2 [f4,a4,c5], e5@97 ~@15]/7",
  C: "[[b4,d5] [c5,e5]@2 [b4,d5]@2, g4]/5", D: "[e5@2 f4 f5 [g4,c5,e5], a4@4 ~, c5@24 d5@11 ~@5]/5",
  E: "[c5,e5]@5 ~@3, g4@7 ~", F: "[g4,b4,d5]/2", G: "[a4,c5,e5]/2", H: "[~ g4@30 ~, [b4,d5]@31 ~]/2",
  I: "[g4@23 ~ g4@8, [b4,e5]]/2", J: "[f4,a4,c5]", K: "[g4,b4,d5]",
  L: "[g4@32 a4@32 ~@3 b4@29 ~ [a4,c5]@15, e5@6 f4, ~@64 g4@33 ~@15]/7", // Am
  M: "[g4@15 ~ [c5,e5]@32, [b4,d5]@17 ~@31, ~@5 g4@11]/3", // C Bm
})).s("gm_synth_strings_1").gain(0.26)

// bass · acoustic bass · "Ac. bass"
const bass = note(`<
  ~@36 A@2 B@2 C D E F G D H I J K L M N O P@2 Q R S T G N U V J W S X Y Z AA AB AC AD AE AF G Y AG AB AH@2 AI AJ AK AL
  ~
>`.pickRestart({
  A: "[c2@5 ~ c2@7 ~ c2@18]/2", B: "[a2@5 ~ a2@15 ~@11]/2", C: "c2@3 ~", D: "c2@6 ~ c2", E: "a2@5 ~ a2 ~",
  F: "f2@5 ~ f2@2", G: "c2@12 ~@2 c2 ~", H: "a2@12 ~@2 a2 ~", I: "a2@10 ~@2 a2@3 ~", J: "e2@12 ~@2 e2 ~",
  K: "e2@6 ~ e2", L: "f2@6 ~ f2", M: "g2@5 ~ g2@5 ~@3 g2@2", N: "c2@7 ~", O: "c2@11 ~ c2@3 ~",
  P: "[g2@11 ~@3 g2@14 ~@4]/2", Q: "a2@13 ~ a2@2", R: "a2@7 ~", S: "f2@13 ~ f2@2", T: "d2@13 ~@3", U: "g2@6 ~ g2",
  V: "g2@10 ~ g2@4 ~", W: "e2@11 ~ e2@2 ~@2", X: "g2@5 ~ g2@5 ~ g2@4", Y: "c2@13 ~@3", Z: "~@7 c2", AA: "a2@13 ~ a2 ~",
  AB: "a2@11 ~ a2@4", AC: "c2@13 ~ c2 ~", AD: "c2@11 ~@3 c2@2", AE: "a2@6 ~ a2", AF: "f2@3 ~", AG: "~ a2@12 ~ a2 ~",
  AH: "[e2@13 ~ e2@10 ~@8]/2", AI: "f2@5 ~@2 f2", AJ: "g2 ~", AK: "~ e2 f2 e2, ~ g2@7 ~@8", AL: "~ c2@9 ~@6",
})).s("gm_acoustic_bass").gain(0.64)

// other · accordion · "Accordian"
const accordion = note("<~@36 A B@3 ~@2 C D@2 E ~@2 F G ~@14 F G H I@2 ~@11 F J K L ~@3>".pickRestart({
  A: "~@5 g4 c5 d5", B: "[e5@14 d5@4 c5@29 ~]/3", C: "~@7 e5", D: "[f5@6 e5@3 c5@6 d5]/2", E: "e5@15 ~",
  F: "~@5 g4 b4 e5", G: "g5", H: "e5", I: "[d5@10 e5@2 f5@6 e5@13 ~]/2", J: "g5@11 ~@5", K: "~@3 a5",
  L: "~@2 g5@9 ~@5, a5 ~@3",
})).s("gm_accordion").gain(0.39)

stack(piano, piano_2, synth_strings_1, bass, accordion)

More by Roxette