Strudelify
It Must Have Been Love (live studio) cover art

It Must Have Been Love (live studio)

Roxette

KeyD♭ majorTempo86 bpm
0:00/0:00
// It Must Have Been Love (live studio) — Roxette
// 86 bpm, 4/4, key C# major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: duplicate parts dropped: ch 4 "OVERDRIVE" overdriven guitar (copy of ch 3 "MUTED GTR" electric guitar muted)
// note: Full arrangement: all 91 bars on a 16-step grid, each part at one level. Source detail keeps the original performance.
setcpm(86/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.

// bass · electric bass finger · "FINGERDBAS"
const bass = note(`<
  ~@2 A B C D E F C G A H C I A C J K L M N O P Q R S T Q R U A H C I A C J K V M W X P Y Z S AA AB P AC AD AE AF AG AH
  AI AJ AK AL AM AJ AN AO AP AJ AN AO AP AJ AN AO AQ AJ AR AS AT AU AV AJ AN AO AP AJ AN AO AP AO ~@4
>`.pickRestart({
  A: "db2@7 db2 ~ bb1 db2@5 ~", B: "db2@6 ~ db2 ~ bb1 db2@5 eb2", C: "gb1@6 ~ gb1 ~ eb1 gb1@5 ~",
  D: "gb1@7 gb1 ~ eb1 gb1@4 gb1 ab1", E: "db2@7 db2 ~ db2 db2@5 ~", F: "db2@6 ~ db2 ~ db2 db2@5 ~",
  G: "gb1@6 db2 gb2 ~ db2 gb1@4 gb1 ab1", H: "db2@6 ~ db2 ~ bb1 db2@5 ~", I: "ab1@7 ab1 ~ ab1 ab1@2 ab1@2 gb1 ab1",
  J: "eb2@6 ~ eb2 ~@2 eb2@5 ~", K: "ab1@7 ab1 ~ ab1 ab1@3 ~ ab1 a1", L: "bb1@7 bb1 ~ bb1 bb1@5 c2",
  M: "db2@6 ~ db2 ~ db2 db2@5 ab1", N: "gb1@6 ~ gb1 ~ gb1 gb1@4 gb1 g1", O: "ab1@7 ab1 ~ ab1 ab1@2 ab1@2 ab1!2",
  P: "db2@7 db2 ~ db2 db2@6", Q: "gb1@6 ~ gb1 ~ gb1 gb1@4 gb1 ab1", R: "eb2@6 ~ bb1 ~ bb1 bb1@6",
  S: "ab1@7 ab1 ~ ab1 ab1@4 ab1 gb1", T: "db2@7 db2 ~@2 db2@6", U: "ab1@7 ab1 ~ ab1 ab1@2 ab1!2 gb1 ab1",
  V: "bb1@7 bb1 ~ ab1 bb1@5 c2", W: "gb1@6 ~ gb1 ~ eb1 gb1@4 gb1 g1", X: "ab1@7 ab1 ~ ab1 ab1@4 gb1 ab1",
  Y: "gb1@6 ~ gb1 ~ gb1 gb1@6", Z: "eb2@6 ~ bb1 ~ bb1 bb1@5 bb1", AA: "db2@7 db2 ~@2 db2@4 db2!2",
  AB: "ab1@7 ab1 ~@2 ab1@4 ab1 bb1", AC: "db2@7 db2 ~ db2 db2@4 db2 eb2", AD: "b1@7 b1 ~ gb1 b1@6",
  AE: "b1@7 ~@5 b1!2 ab1 b1", AF: "eb2@7 eb2 ~ bb1 eb2@6", AG: "db2@6 ~ db2 ~ db2 db2@4 db2 eb2",
  AH: "b1@6 ~ b1 ~ b1 b1@4 b1 db2", AI: "eb2@7 eb2 ~ eb2 eb2@5 db2", AJ: "gb1@7 gb1 ~ gb1 gb1@4 gb1 ab1",
  AK: "db2@6 ~ db2 ~ db2 db2@6", AL: "b1@7 b1 ~ b1 b1@4 b1 db2", AM: "eb2@7 db2 ~ db2 db2@4 db2 eb2",
  AN: "b1@6 ~ b1 ~ gb1 b1@6", AO: "ab1@6 ~ eb2 ~@2 eb2@6", AP: "db2@7 db2 ~ db2 db2@3 db2 b1 db2",
  AQ: "db2@7 db2 ~ db2 db2@3 ~ db2 eb2", AR: "db2@6 ~ db2 ~@2 db2@4 db2 b1", AS: "gb1@6 ~ gb1 ~@2 gb1@4 gb1@2",
  AT: "gb1@6 ~ gb2@2 db2 gb1@4 gb1 ab1", AU: "e1@6 ~ b1 e2@2 e1@6", AV: "e1@7 e1 ~ e1 e1@3 e1!2 f1",
})).s("gm_electric_bass_finger").gain(0.4)

// chords · electric guitar muted · "MUTED GTR"
const electric_guitar_muted = note(`<
  ~ A B@2 C@2 D@2 E@2 F ~ G ~ F ~@3 H I J K L M ~ N O@2 ~ P Q R Q R S T U R H I J V L M ~ N O W X@2 Y@2 ~@8 Z AA AB AC
  AD AE AB AC AD AE AF AC AD AG AH@2 AI AJ AK AL AM AN AK AO AM AN AP ~@4
>`.pickRestart({
  A: "~@8 [gb3,gb4]@3 ~ [f3,f4]@3 ~", B: "[[ab4,f5]@18 ~@10 [ab3,ab4]@3 ~, [db4,db5]@15 ~@17]/2",
  C: "[bb4@2 ~ ab4 bb4!2 ab4 bb4@5 ~@12 [gb4,gb5]@4 [f4,f5]@3 ~, [gb4,db5,gb5]@11 ~@5, bb3@7 ~@9]/2", // Gb F Gb5
  D: "[[ab4,f5]@18 ~@6 [db4,db5]@3 ~ [ab3,ab4]@3 ~, [db4,db5]@15 ~@17]/2", // Db Ab Db
  E: "[[gb4,db5,gb5]@22 ~@2 [gb4,gb5]@4 [f4,f5]@3 ~, [bb3,bb4]@7 ~@9]/2", F: "~@3 ab4 db5 ~ ab4@8 ~@2, ~@5 db5@9 ~@2",
  G: "~@3 ab4 db5 ~ ab4@9 ~, ~@5 db5@9 ~@2", H: "[bb4,f5]@7 ~", I: "[ab4,db5]@7 ~", J: "[bb4,db5]@7 ~",
  K: "[ab4,eb5]@13 ~@3", L: "~@4 db5 ~ ab4@8 ~@2, ~@3 ab4@2 db5@9 ~@2", M: "~@4 db5 ~ ab4@7 ~@3, ~@3 ab4@2 db5@8 ~@3",
  N: "[ab3,eb4]@7 ~", O: "~@4 db5 ~ ab4@9 ~, ~@3 ab4@2 db5@10 ~", P: "[ab3,eb4]@15 ~",
  Q: "[db4,ab4] db4!2 [db4,ab4] [db4,ab4,db5] ~ [db4,ab4]!2 ~@8, ~@5 db5@9 ~@2", // Db5
  R: "[db4,ab4] db4!3 [db4,ab4] ~ db4 [db4,ab4] ~@8", // Db5
  S: "[db4,ab4] db4!2 [db4,ab4] [db4,ab4,db5] ~ [db4,ab4]!2 [db4,db5]@3 ~ [ab3,ab4]@3 ~, ~ ab3 ~@2, ~@5 db5@3 ~@8", // Db5 Db Ab
  T: "[db4,ab4] db4!3 [db4,ab4] ~ db4 [db4,ab4] ~@8, [bb3,bb4]@7 ~", // Db5 Bb
  U: "[db4,ab4] db4!2 [db4,ab4] [db4,ab4,db5] ~ [db4,ab4]!2 ~@8, ~@4 [gb4,gb5]@11 ~, ~@5 db5@9 ~@2", // Db5 Gb
  V: "ab4 ~ eb5@13 ~, ~ ab4@14 ~", W: "[ab3,eb4]@3 ~", X: "[[db3,ab3]@15 ~]/2",
  Y: "[~@2 ab4 ~ gb5 db5 ab4!2 ~@2 ab4 ~ gb5 db5 ab4!2 ~@2 ab4 ~ gb5 db5 ab4!2 ~@2 ab4 ~@2 db5 ab4!2, [b2,gb3]@31 ~, f5@3 ~@5 f5@3 ~@5 f5@3 ~@5 f5@3 ~ gb5@3 ~, ~ db5@2 ab4@2 ~@4 db5@2 ab4@2 ~@4 db5@2 ab4@2 ~@4 db5@2 ab4@2 ~@3]/2", // B5
  Z: "[gb2,db3]@7 ~", AA: "[b2,gb3]", AB: "[ab2,eb3]@6 ~ [eb3,bb3]@8 ~", AC: "[db3,ab3]@15 ~", AD: "[gb2,db3]@15 ~",
  AE: "[b2,gb3]@15 ~", AF: "[ab2,eb3]@6 ~ bb3@8 ~, ~@7 eb3 ~@8", AG: "[db3,ab3]", AH: "[gb2@31 ~, db3 ~@31]/2",
  AI: "~@2 db5 ~ b5 gb5 db5!2 ~@2 db5 ~ b5 gb5 db5!2, bb5@3 ~@5 bb5@3 ~@5, ~ gb5@2 db5@2 ~@4 gb5@2 db5@2 ~@3",
  AJ: "~@2 db5 ~ b5 gb5 db5 [e3,b3,db5] ~@2 db5 ~@2 gb5 db5!2, bb5@3 ~@5 bb5@2 [e3,b3]@5 ~, ~ gb5@2 db5@2 ~@4 gb5@2 db5@2 ~@3, ~@12 b5@3 ~", // Dbm7 E5
  AK: "[gb2,db3]@6 ~ [gb2,db3] ~@2 [gb2,db3]@5 ~", AL: "[b2,gb3]@7 [b2,gb3] ~@2 gb3@5 ~, ~@10 b2@3 ~@3",
  AM: "[ab2,eb3]@6 ~ [eb3,bb3] ~@2 [eb3,bb3]@5 ~", AN: "[db3,ab3]@6 ~ [db3,ab3] ~@2 [db3,ab3]@5 ~",
  AO: "[b2,gb3]@6 ~ [b2,gb3] ~@2 [b2,gb3]@5 ~", AP: "~@7 [eb3,bb3] ~@2 [eb3,bb3]@5 ~",
})).s("gm_electric_guitar_muted").gain(0.3).pan(0.7)

// chords · string ensemble 1 · "STRINGS"
const string_ensemble_1 = note(`<
  ~@2 A@8 B@3 C D@4 E@3 C F@3 G@4 C B@3 C D@4 E@3 C H@3 I@3 J@2 K@3 L M@4 N@2 O@3 P@4 L O@3 Q R@2 S@2 T@2 O@3 P@4 L U
  ~@4
>`.pickRestart({
  A: "[[ab3,f4] [bb3,gb4], db4]/4", B: "[[ab3,f4]@2 [bb3,gb4], db4]/3", C: "[ab3,c4,eb4]",
  D: "[[ab3,f4] ~@2 [ab3,c4], db4 eb4, ~ [bb3,gb4]@2 ~]/4", E: "[bb3@16 ab3@15 ~ [bb3,gb4]@16, db4, f4@2 ~]/3",
  F: "[[ab3,f4]@16 ~@16 eb4@7 [db4,f4]@9, db4@2 ~, ~@16 bb3@31 ~, ~@16 gb4@23 ~@9]/3", // Db
  G: "[[c4,eb4]@16 f4@16 ~@16 eb4@7 [db4,f4]@9, ab3@31 ~ bb3@31 ~, ~@16 db4@32 ~@7 eb4 ~@8, ~@32 gb4@23 ~@9]/4", // Cm Db
  H: "[[ab3,f4]@16 ~@16 eb4@7 [db4,f4]@9, db4@2 ~, ~ bb3@2, ~@16 gb4@23 ~@9]/3", // Db
  I: "[[c4,eb4] [db4,f4] [b3,eb4], ab3@47 ~]/3", J: "[ab3,db4,f4]/2", K: "[[b3,eb4]@2 [bb3,eb4], gb3, ~@32 gb4 ~@15]/3",
  L: "[ab3,db4,f4]", M: "[[gb3,b3] ~@2 [ab3,f4], eb4 db4, ~ [bb3,gb4]@2 ~]/4",
  N: "[[gb3,b3]@16 [bb3,gb4]@7 [ab3,db4,f4]@8 ~, eb4@23 ~@9]/2", // B5 Ebm Db
  O: "[[bb3,db4]@16 ~@16 ab4@7 [bb3,gb4]@9, gb4@2 ~, ~ eb4@2, ~@16 b3@23 ~@9]/3", // Bbm Ebm
  P: "[[ab3,f4]@16 bb3@16 ~@16 ab4@7 [bb3,gb4]@9, db4 eb4, ~ gb4@2 ~, ~@32 b3@23 ~@9]/4", Q: "[ab3,f4]",
  R: "[[bb3,gb4]@15 [ab3,e4]@16 ~]/2", S: "[bb3,gb4]/2", T: "[ab3,b3,e4]/2", U: "ab4@7 [bb3,gb4]@9",
})).s("gm_string_ensemble_1").gain(0.3)

// chords · piano · "A.PIANO"
const piano = note("<~@52 A B C D E F G H ~@31>".pickRestart({
  A: "[eb1,eb2]@2 [bb4,f5] [gb4,db5], ~@8 eb5 ~@7", B: "[f4,ab4,eb5]@5 ~ gb4 f4@7 db4 eb4, ~@5 db5@10 ~",
  C: "f4 ~ db4 [b3,eb4]@9 ~@2 db4 eb4, b3 ~@7, ~ gb4@6 ~@9", D: "[eb3,gb3,bb3]@11 ~@3 gb3 ab3, ab3 ~@15",
  E: "[gb3,bb3,db4]@4 [db4,ab4] bb4 ~@2 ab4@4 db5 db4 gb4 ab4, ~@3 db4@3 ~@2, ~@3 gb4 ~@4, ~@7 db5@5 ~@4", // Gb Db5
  F: "f4 gb4 f4 eb4@2 f4@2 db4@5 ~@2 db4 eb4, db4@5 ~@11", G: "f4 ~ db4 [b3,eb4]@10 ~ gb3 ab3, b3 ~@7, ~ gb4@7 ~@8",
  H: "bb3 ab3 gb3 ab3@2 gb3 ab3@6 ~@4, [db3,db4]@3 db4@9 ~@4", // Db
})).s("gm_piano").gain(0.5).pan(0.6)

// drums · kick
const kick = s("bd").struct(`<
  [x ~@6 x ~ x!2 ~@5]!16
  [x ~@6 x ~@2 x ~@5]
  [x ~@6 x ~ x!2 ~@5]!29
  [x ~@6 x ~@2 x ~@5]!2
  [x ~@6 x ~ x!2 ~@5]!39
  ~@4
>`).gain(0.5)

// drums · snare
const snare = s("sd").struct("<A B A@19 B A@7 B A@11 B A@17 B A@7 B A@17 B A ~@4>".pickRestart({
  A: "~ x ~ x", B: "~@4 x ~@7 x ~ x!2",
})).gain(0.5)

// drums · hihat
const hihat = s("hh").struct("<A B C@3 D C@3 D C@3 D C@11 D C@7 D C@11 D C@9 D C@15 D C@14 E ~@4>".pickRestart({
  A: "x!5 ~ x!5 ~ x ~ x!2", B: "x!3 ~ x ~ x!7 ~ x ~", C: "x!8", D: "x!7 ~", E: "x!6 ~@2",
})).gain(0.35)

// drums · open hat
const open_hat = s("oh").struct("<~@5 A ~@3 A ~@3 A ~@11 A ~@7 A ~@11 A ~@9 A ~@15 A ~@19>".pickRestart({
  A: "~@7 x",
})).gain(0.35)

// drums · crash
const crash = s("cr").struct(`<
  ~@2 A ~@7 A ~@3 A ~@3 A ~@3 A ~@7 A ~@3 A ~@3 A ~@3 A ~@13 A ~@3 A ~@3 A ~@3 A ~@7 A ~ A ~@3 A ~@8
>`.pickRestart({
  A: "x",
})).gain(0.45)

// drums · shaker
const shaker = s("sh").struct("<~ [~@3 x] [~ x!2 ~@2 x!2 ~@2 x!2 ~@2 x!2 ~]!84 [~ x!2 ~@2 x!2 ~@2 x!2 ~@5] ~@4>")
  .gain(0.2)

stack(bass, electric_guitar_muted, string_ensemble_1, piano, kick, snare, hihat, open_hat, crash, shaker)

More by Roxette