Strudelify
Two Hearts cover art

Two Hearts

Phil Collins

KeyA majorTempo157 bpm
0:00/0:00
// Two Hearts — Collins Phil
// 157 bpm, 4/4, key A major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: Full arrangement: all 136 bars on a 24-step grid, each part at one level. Source detail keeps the original performance.
setcpm(157/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 · "BASS"
const bass = note(`<
  ~@2 A B C D E B C F G@3 H G@3 I J G@2 K G@3 L M@4 N@4 E B C D E B C O G@3 H G@3 I J G@2 K G@3 L M@4 N@4 P B C D E B C
  O E B C Q A B C R S T U V W X Y Z AA AB U V W X Y AC AD AE E B C D E B C O A AF C AG E AH C Q AI AJ C AK E B C Q AI AJ
  C AK E B C AL S AM AN AO
>`.pickRestart({
  A: "d2 ~ d2!2 ~ d2!2 ~ d2!2 ~ d1", B: "d1 ~ d1!2 ~ d1 d1@3 f#1@3", C: "e1 ~ e1!2 ~ e1!2 ~ e1!2 ~ a1",
  D: "a1 ~ a1!2 ~ a1 b1@3 a1@2 b1", E: "d1 ~ d1!2 ~ d1!2 ~ d1!2 ~ d1", F: "a1 ~ a1!2 ~ a1 b1 ~ a1 f#1@2 a1",
  G: "~@2 a1 ~@2 a1 a1@2 a1 a1@2 a1", H: "~@2 a1 ~@2 a1 f#1@3 e1@2 a1", I: "~@2 a1 ~@2 a1 f#1@3 e1@3",
  J: "a1@2 a1 ~@2 a1 a1@2 a1 a1@2 a1", K: "~@2 a1 ~@2 a1 f#1@3 e1@2 f#1", L: "a1 g1 a1 a#1",
  M: "[b1 ~ b1!2 ~ b1!2 ~ b1!2 ~ c#2@2 ~ c#2!2 ~ c#2!2 ~ c#2!2 ~ d2@3 d2!2 ~ d2!2 ~ d2!2 ~ e2@3 e1!2 ~ e1 a1@3 a#1@3]/4",
  N: "[b1 ~ b1!2 ~ b1!2 ~ b1!2 ~ c#2@3 c#2!2 ~ c#2!2 ~ c#2!2 ~ d2@3 d2!2 ~ d2!2 ~ d2!2 ~ e2@3 e1!2 ~ e1 e2 ~ e1 e2@2 ~]/4",
  O: "a1 ~ a1!2 ~ a1 b1@2 a1 f#1@2 a1", P: "~@2 d1!2 ~ d1!2 ~ d1!2 ~ d1", Q: "a1 ~ a1!2 ~ a1 b1@3 c#2@3",
  R: "a1 ~ a1!2 ~ a1!2 ~ a1 a1@3", S: "a1 f1 a1 a#1@3", T: "b1@3 c2 d2@2", U: "c#2 ~ c#2!2 ~ c#2 a#1@3 g#1@3",
  V: "a#1 ~ a#1!2 ~ a#1 a#1@3 b1@3", W: "c2 ~ c2!2 ~ c2!2 ~ c2!2 ~ f2", X: "f2@3 d#2@3 c2@3 f1@2 a#1",
  Y: "a#1 ~ a#1!2 ~ a#1!2 ~ a#1!2 ~ a#1", Z: "a#1 ~ a#1!2 ~ a#1!2 ~ a#1 b1 ~ b1", AA: "c2 ~ c2!2 ~ c2!2 ~ c2!2 ~ c2",
  AB: "c2 ~ c2!2 ~ c2!2 ~ c2@4", AC: "a#1 ~ a#1!2 ~ a#1!2 ~ a#1!2 c#2 a#1", AD: "b1 ~ b1!2 ~ b1!2 ~ b1 ~@3",
  AE: "e2!3 b1", AF: "d1 ~ d1!2 ~ d1!2 ~ d1 f#1@3", AG: "a1 ~ a1!2 ~ a1 b1@3 a1@3", AH: "d1 ~ d1 c#1@3 d1@3 d#1@3",
  AI: "d2 ~ d2!2 ~ d2!2 ~ d2!2 ~ a1", AJ: "d2 c#2 b1 a1", AK: "a1 ~ a1!2 ~ a1 b1 ~ a1 f#1 ~ e1",
  AL: "a1 ~ a1!2 ~ a1 a1@2 a1 a1@3", AM: "b1 g1 b1 c2@3", AN: "c#2 a1 c#2 d2 e2@2", AO: "a1 ~@11",
})).s("gm_electric_bass_finger").gain(0.19)

// chords · epiano2 · "PIANO"
const epiano2 = note(`<
  ~@2 A@2 B@2 C@2 D@2 E@4 F@4 G@4 H@4 I@8 J@2 K@2 L@2 D@2 F@4 M@8 N@4 I@8 J@2 O@2 C@2 P@2 J@2 Q@2 L@2 R@2 S T U V W X Y
  Z AA AB AC Z W AD Z@2 AE AF J@2 K@2 L@2 AG@2 J@2 AH@2 AI@2 AJ@2 A@2 AK@2 AL@2 AJ@2 A@2 AM@2 C@2 R@2 S AN AO AP
>`.pickRestart({
  A: "[[d4,f#4,a4,c#5]@8 ~@2 [d4,f#4,a4,b4]@22 ~@4 [f#4,a4]@5 ~ g#4@4 ~@2, ~@18 d4@5 ~]/2", // Dmaj7 Bm7 F#m
  B: "[[e4,g#4,b4]@12 [e4,g#4,b4]@7 ~@3 [c#4,e4,a4]@14 a4@3 ~ b4@2 [a4,c#5]@6]/2", // E A
  C: "[[d4,f#4,a4,c#5]@8 ~@2 [d4,f#4,a4,b4]@24 ~@2 [f#4,a4]@6 g#4@5 ~, ~@36 d4@11 ~]/2", // Dmaj7 Bm7 F#m
  D: "[[e4,g#4,b4]@6 [g#4,b4,e5]@4 ~ [e4,a4,c#5]@7 a4@2 b4 [a4,c#5]@2 ~]/2", // E A
  E: "[[e4,a4,c#5]@9 [e4,a4,c#5]@2 [f#4,b4,d#5]@9 ~ [b4,d#5,f#5]@2 [a4,c#5,e5]@10 [a4,c#5,e5]@2 [f#4,b4,d#5]@13]/4", // A B A B
  F: "[[e4,a4,c#5]@18 [e4,a4,c#5]@4 [f#4,b4,d#5]@18 ~@2 [b4,d#5,f#5]@4 [a4,c#5,e5]@20 [a4,c#5,e5]@3 ~ [f#4,b4,d#5]@26]/4", // A B A B
  G: "[[e4,a4,c#5]@18 [e4,a4,c#5]@4 [f#4,b4,d#5]@17 ~@3 [b4,d#5,f#5]@4 [a4,c#5,e5]@20 [a4,c#5,e5]@4 [f#4,b4,d#5]@26]/4", // A B A B
  H: "[[e4,a4,c#5]@17 ~ [e4,a4,c#5]@4 [f#4,b4,d#5]@18 ~@2 [b4,d#5,f#5]@4 [a4,c#5,e5]@20 [a4,c#5,e5]@4 [f#4,b4,d#5]@26]/4", // A B A B
  I: "[[b3,d4,f#4,a4]@21 ~ [c#4,e4,g#4,b4]@23 ~ [d4,f#4,a4,c#5]@23 ~ [f#4,a4,d5]@25 ~]/4", // Bm7 C#m7 Dmaj7 D
  J: "[[d4,f#4,a4,c#5]@4 ~ [d4,f#4,a4,b4]@11 ~@2 [f#4,a4]@3 g#4@2 ~, ~@18 d4@5 ~]/2", // Dmaj7 Bm7 F#m
  K: "[[e4,g#4,b4]@6 [e4,g#4,b4]@4 ~ [c#4,e4,a4]@7 a4@2 b4 [a4,c#5]@3]/2", // E A
  L: "[[d4,f#4,a4,c#5]@4 ~ [d4,f#4,a4,b4]@12 ~ [f#4,a4]@3 g#4@3, ~@3 d4]/2", // Dmaj7 Bm7 F#m
  M: "[[e4,a4,c#5]@18 [e4,a4,c#5]@3 ~ [f#4,b4,d#5]@18 ~@2 [b4,d#5,f#5]@4 [a4,c#5,e5]@20 [a4,c#5,e5]@4 [f#4,b4,d#5]@26]/4", // A B A B
  N: "[[e4,a4,c#5]@18 [e4,a4,c#5]@4 [f#4,b4,d#5]@18 ~@2 [b4,d#5,f#5]@4 [a4,c#5,e5]@20 [a4,c#5,e5]@4 [f#4,b4,d#5]@25 ~]/4", // A B A B
  O: "[[e4,g#4,b4]@12 [e4,g#4,b4]@7 ~@3 [c#4,e4,a4]@14 a4@3 ~ b4@2 [a4,c#5]@5 ~]/2", // E A
  P: "[[e4,g#4,b4]@11 ~ [g#4,b4,e5]@7 ~@3 [e4,a4,c#5]@14 a4@4 b4@4 c#5@3 ~]/2", // E A
  Q: "[[e4,g#4,b4]@12 [e4,g#4,b4]@8 ~@2 [c#4,e4,a4]@14 a4@3 ~ b4@2 [a4,c#5]@6]/2", // E A
  R: "[[e4,g#4,b4]@6 [g#4,b4,e5]@4 ~ [e4,a4,c#5]@13]/2", S: "[c4,f4,a4] [d4,f4,a#4]",
  T: "[d4,g4,b4]@6 [e4,g4,c5] ~ [d4,f4,a#4]@4", U: "[c4,f4,g#4]", V: "[c#4,f4,g#4]@2 c#4 f4", W: "[a#3,d#4,g4]",
  X: "[d#4,g4,a#4] d#4", Y: "[c#4,f4,g#4]@23 ~", Z: "[c#4,f4,g#4]", AA: "[d#4,g4,a#4]@11 ~",
  AB: "[d#4,g4,a#4]@10 ~@2 [d#4,a#4] ~@3 [d#4,g4,a#4]@8, ~@6 g4 ~@5", AC: "[c4,f4,g#4]@23 ~",
  AD: "[d#4,g4,a#4] [a#3,d#4,g4]", AE: "[d4,f#4,a4]", AF: "[f#4,a4,c#5]!2",
  AG: "[[e4,g#4,b4]@12 [g#4,b4,e5]@8 ~@2 [e4,a4,c#5]@13 ~ a4@4 b4@3 ~ c#5@4]/2", // E A
  AH: "[[e4,g#4,b4]@12 [e4,g#4,b4]@8 ~@2 [c#4,e4,a4]@14 a4@4 b4 ~ [a4,c#5]@6]/2", // E A
  AI: "[[d4,f#4,a4,c#5]@8 ~@2 [d4,f#4,a4,b4]@24 ~@2 [f#4,a4]@5 ~ g#4@6, ~@3 d4]/2", // Dmaj7 Bm7 F#m
  AJ: "[[e4,g#4,b4]@12 [g#4,b4,e5]@8 ~@2 [e4,a4,c#5]@14 a4@4 b4 ~ [a4,c#5]@4 ~@2]/2", // E A
  AK: "[[e4,g#4,b4]@12 [e4,g#4,b4]@8 ~@2 [c#4,e4,a4]@14 a4@4 b4@2 [a4,c#5]@5 ~]/2", // E A
  AL: "[[d4,f#4,a4,c#5]@4 ~ [d4,f#4,a4,b4]@12 ~ [f#4,a4]@3 g#4@3, ~@36 d4@11 ~]/2", // Dmaj7 Bm7 F#m
  AM: "[[e4,g#4,b4]@12 [e4,g#4,b4]@8 ~@2 [c#4,e4,a4]@14 a4@4 b4 ~ [a4,c#5]@5 ~]/2", AN: "[d4,g4,b4] [e4,g4,c5]",
  AO: "[e4,a4,c#5]@6 [a4,d5] ~ [g#4,b4,e5]@3 ~, ~@12 f#4 ~@11", AP: "[c#5,e5,a5] ~@23",
})).s("gm_epiano2").gain(0.17)

// chords · electric guitar clean · "GUITAR"
const electric_guitar_clean = note(`<
  ~@2 A B C D A B C D@2 E F E G H D H D E D E D E G E I J K B I J K B@3 C F B@2 C D@2 E D E G E D E D E D E D E D E L J
  K B I J K B@3 C D B@2 C D B M C D B M C G N O ~@16 B A C D B A C D B A P D M B P Q M B P D M B C Q B@2 C D A B R Q N S
  T U
>`.pickRestart({
  A: "~@6 [d4,f#4,a4]@2 ~@10 [d4,f#4,a4] ~@5", B: "~@3 [d4,f#4,a4] ~@5 [d4,f#4,a4] ~@2",
  C: "~@3 [b3,e4,g#4] ~@5 [b3,e4,g#4] ~@2", D: "~@3 [c#4,e4,a4] ~@5 [c#4,e4,a4] ~@2",
  E: "~@3 [d#4,f#4,b4] ~@5 [d#4,f#4,b4] ~@2", F: "~@6 [c#4,e4,a4]@2 ~@10 [c#4,e4,a4] ~@5",
  G: "~@6 [c#4,e4,a4] ~@11 [c#4,e4,a4]@2 ~@4", H: "~@6 [d#4,f#4,b4] ~@11 [d#4,f#4,b4]@2 ~@4",
  I: "~@3 [d4,f#4,b4] ~@5 [d4,f#4,b4] ~@2", J: "~@3 [e4,g#4,b4] ~@5 [e4,g#4,b4] ~@2",
  K: "~@3 [f#4,a4,c#5] ~@5 [f#4,a4,c#5] ~@2", L: "~@6 [d4,f#4,b4] ~@11 [d4,f#4,b4]@2 ~@4",
  M: "~@6 [d4,f#4,a4] ~@11 [d4,f#4,a4]@2 ~@4", N: "[c4,f4,a4] [d4,f4,a#4]",
  O: "[b3,d4,g4]@6 [c4,e4,g4] ~ [d4,f4,a#4]@4", P: "~@6 [b3,e4,g#4] ~@11 [b3,e4,g#4]@2 ~@4",
  Q: "~@6 [c#4,e4,a4]@2 ~@10 [c#4,e4,a4]@3 ~@3", R: "~@6 [b3,e4,g#4]@2 ~@10 [b3,e4,g#4] ~@5",
  S: "[b3,d4,g4] [c4,e4,g4]", T: "[c#4,e4,a4]@6 [d4,f#4,a4] ~ [e4,g#4,b4]@4", U: "[e4,a4,c#5] ~@11",
})).s("gm_electric_guitar_clean").gain(0.16).pan(0.4)

// other · string ensemble 1 · "STRINGS"
const string_ensemble_1 = note(`<
  ~ A B@2 C@2 D@2 E@2 F@8 ~@16 G@2 H@2 I@2 J@2 K@8 ~@16 G@2 H@2 I@2 L@2 M@2 H@2 M@2 N@2 O P Q R S@2 T U@3 V R W X T Y Z
  AA G@2 H@2 I@2 L@2 AB@2 AC@2 AB@2 AD@2 AB@2 AC@2 AB@2 AD@2 AB@2 AC@2 AB@2 AE@2 O AF AG AH
>`.pickRestart({
  A: "~@8 e4 f#4 a4 b4", B: "[c#5@5 b4@13 a4@3 g#4@3]/2", C: "[b4@12 b4@10 a4@12 ~@2 a4@4 b4@2 c#5@4 ~ b4]/2",
  D: "[c#5@5 b4@12 ~ a4@3 g#4@3]/2", E: "[b4@11 d5 e5@10 c#5@14 a4 g#4 g4 f#4 f4 e4 d#4 d4 c#4 c4 b3 a#3]/2",
  F: "[e6@16 c#6@2 a5@4 d#6@8 b5@4 c#6@2 d#6@4 e6@2 f#6@4 e6@11 ~ a5 b5 c#6@4 d6@2 e6@4 d#6@22 a5 a#5 b5 c6 c#6@18 e6@4 d#6@8 b5@4 c#6@2 d#6@4 e6@2 f#6@4 e6@8 a5@4 b5@2 c#6@4 d6@2 e6@2 ~@2 [d#6,a6]@20 ~@6, a3@31 ~]/8", // D#dim
  G: "[c#6@5 b5@12 ~ a5@3 g#5@3]/2", H: "[b5@11 c#6@7 a5@2 b5 c#6@3]/2", I: "[c#6@9 ~ b5@24 ~@2 a5@6 g#5@6]/2",
  J: "[b5@12 e6@10 c#6@13 ~ a5 g#5 g5 f#5 f5 e5 d#5 d5 c#5 c5 b4 ~]/2",
  K: "[~@43 e5 f#5 g#5 a5 b5 c#6@9 e6@2 d#6@4 b5@2 c#6 d#6@2 e6 f#6@2 e6@3 ~ a5@2 b5 c#6@2 d6 e6@2 a6@10 ~@3, a4@31 ~]/8",
  L: "[b5@12 e6@10 c#6@13 ~ a5@4 b5@4 c#6@4]/2", M: "[c#6@5 b5@13 a5@3 g#5@3]/2", N: "[b5@6 e6@4 ~ c#6@13]/2",
  O: "f5 c5 a4!2 c5 f5!2 d5 a#4 d5 f5 a#5", P: "b5@2 a5@2 g5@2 g5@2 a5@2 b5@2 c6@2 g5@2 c6@2 ~@2 a#5 c6 d6 e6",
  Q: "[f5,f6]@9 [d#5,d#6] [c#5,c#6]@2 [c5,c6]@4 [c#5,c#6]@4 [d#5,d#6]@4", R: "[f5,f6]",
  S: "[[g5,g6]@11 ~ [a#5,a#6]@12, ~@11 [g#5,g#6]@2 ~@11]/2", T: "[f5,f6]@3 [c6,c7]",
  U: "[[a#5,a#6]@6 [g#5,g#6]@2 ~ [g5,g6]@2 ~ [f5,f6]@24 [d#5,d#6]@22 ~@2 [d#5,d#6]@4 [c5,c6]@2 [a#4,a#5]@3 [c5,c6] [c#5,c#6] [d#5,d#6]]/3", // A# G# G F D# C A# C …
  V: "[f5,f6]@3 [c5,c6] [c#5,c#6] [d#5,d#6]", W: "[g5,g6]@11 [g#5,g#6]", X: "[a#5,a#6]",
  Y: "[a#5,a#6]@2 [g#5,g#6] [g5,g6] [f5,f6]@4", Z: "[f#5,f#6]@3 [d6,d7]", AA: "[c#6,c#7]@2 [b5,b6] [a5,a6] [f#5,f#6]@4",
  AB: "[[c#5,c#6]@5 [b4,b5]@12 ~ [a4,a5]@3 [g#4,g#5]@3]/2", // C# B A G#
  AC: "[[b4,b5]@6 [b4,b5]@5 [c#5,c#6]@7 [a4,a5]@2 [b4,b5] [c#5,c#6]@3]/2", // B C# A B C#
  AD: "[[b4,b5]@6 [e5,e6]@5 [c#5,c#6]@6 ~ [a4,a5]@2 [b4,b5] [c#5,c#6]@2 ~]/2", // B E C# A B C#
  AE: "[[b4,b5]@12 [e5,e6]@10 [c#5,c#6]@25 ~]/2", AF: "b5 a5 g5!2 a5 b5 c6 g5 e5!2 g5 c6",
  AG: "c#6@2 b5@2 a5@2 a5@2 b5@2 c#6@2 d6@2 ~@2 e6@7 ~", AH: "[c#6,a6] ~@11",
})).s("gm_string_ensemble_1").gain(0.22)

// chords · brass section · "BRASS"
const brass_section = note(`<
  ~@34 A@2 ~@2 B@2 ~@26 A@2 ~@2 B@2 ~@2 A@2 ~@2 B@2 ~@2 C D ~@16 A@2 ~@2 B@2 ~@2 A@2 ~@2 B@2 ~@2 A@2 ~@2 B@2 ~@2 A@2 ~@2
  B@2 ~@2 C E F G
>`.pickRestart({
  A: "[~@9 [a4,d5,f#5]@2 [d5,f#5,a5]@7 ~@6]/2", B: "[~@9 [a4,d5,f#5]@2 [d5,f#5,a5]@8 ~@5]/2",
  C: "[c5,f5,a5] [d5,f5,a#5]", D: "[d5,g5,b5]@6 [e5,g5,c6] ~ [d5,f5,a#5]@4", E: "[d5,g5,b5] [e5,g5,c6]",
  F: "[e5,a5,c#6]@6 [f#5,a5,d6] ~ [g#5,b5,e6]@3 ~", G: "[c#6,e6,a6] ~@5",
})).s("gm_brass_section").gain(0.21).pan(0.4)

// drums · kick
const kick = s("bd").struct("<~@2 A@81 B A@7 B A@7 C A@35 D>".pickRestart({
  A: "x!2", B: "x ~ x", C: "x!4", D: "x",
})).gain(0.35)

// drums · snare
const snare = s("sd").struct(`<
  ~ A B@7 C B@7 D B@7 C B@7 C B@7 C B@7 D B@7 C B@7 C B@7 C B@7 C B E B@7 F B@7 G B@7 C B@7 C B@7 C B@7 C B@2 E H
>`.pickRestart({
  A: "~@8 x!4", B: "~ x ~ x", C: "~@3 x ~@5 x!3", D: "~ x ~@2", E: "~@2 x!5 ~@5", F: "~@3 x!4 ~@5",
  G: "~@3 x!4 ~ x ~@3", H: "x",
})).gain(0.45)

// drums · clap
const clap = s("cp").struct("<~@2 [~ x ~ x]!133 ~>").gain(0.45)

// drums · hihat
const hihat = s("hh").struct(`<
  A B C@7 D C@7 D C@7 D C@15 D C@7 D C@7 D C@15 D C@17 E C@15 D C@7 D C@19 F
>`.pickRestart({
  A: "x!2", B: "x!3 ~", C: "x ~ x!2 ~ x!2 ~ x!2 ~ x", D: "x ~ x!2 ~ x!2 ~@2 x ~ x", E: "x ~ x!2 ~ x!2 ~ x ~@3", F: "x",
})).gain(0.3)

// drums · low tom
const low_tom = s("lt").struct("<~@17 [~@11 x] ~@31 [~@11 x] ~@49 [~@11 x] ~@36>").gain(0.4)

// drums · mid tom
const mid_tom = s("mt").struct("<~@17 [~@5 x] ~@31 [~@5 x] ~@49 [~@5 x] ~@36>").gain(0.4)

// drums · crash
const crash = s("cr").struct(`<
  ~@2 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 B C A ~@6 D ~@8 A ~@7 A ~@7 A ~@7 A ~@7 B@2 C ~
>`.pickRestart({
  A: "x", B: "x!2", C: "x ~ x", D: "~@2 x",
})).gain(0.4)

// drums · high tom
const high_tom = s("ht").struct("<~@17 [~@3 x] ~@31 [~@3 x] ~@49 [~@3 x] ~@36>").gain(0.5)

// drums · tambourine
const tambourine = s("tb").struct("<~@2 [x ~ x!2 ~@2 x ~ x!2 ~@2]!133 x>").gain(0.45)

stack(
  bass, epiano2, electric_guitar_clean, string_ensemble_1, brass_section, kick, snare, clap, hihat, low_tom, mid_tom,
  crash, high_tom, tambourine
)

More by Phil Collins