Strudelify
There Must Be Angel (Playing With My Heart) cover art

There Must Be Angel (Playing With My Heart)

Annie Lennox

KeyC majorTempo110 bpm
0:00/0:00
// There Must Be Angel (Playing With My Heart) — Annie Lennox
// 110 bpm, 4/4, key C major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: pitch bends are ignored
// note: sustain pedal (CC 64) lengthens the held notes
// note: Full arrangement: all 137 bars on a 32-step grid, each part at one level; ghost notes are separate "_soft" parts. 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 · piano
const piano = note("<~@73 A B C@2 A B C@2 A B C@2 D@2 E F G H I J G K L M@2 ~@39>".pickRestart({
  A: "[d4,f4,a#4]@3 ~@9 [d4,f4,a#4]@11 ~ [d4,f4,a#4]@3 ~@5", B: "[f#3,a3,d4]@3 ~@9 [f#3,a3,d4]@11 ~ [f#3,a3,d4]@3 ~@5",
  C: "[a#3,d4,g4]@3 ~@9 [a#3,d4,g4]@11 ~ [a#3,d4,g4]@3 ~@5", D: "[g3,c4,e4]@3 ~@9 [g3,c4,e4]@11 ~ [g3,c4,e4]@3 ~@5",
  E: "[a3,c4,f4]@3 ~@9 [a3,c4,f4]@11 ~ [a3,c4,f4]@3 ~@5", // F
  F: "[b3,d4,g4]@3 ~@25 [g4,g5]@4, ~ [g4,g5]@4 [c5,c6] [b4,b5]@2, ~ [a4,a5]@3, ~@3 [e5,e6]@5, ~ [d5,d6]", // G C B A E D
  G: "[a4,a5] [d5,d6]", H: "[b4,b5] [e5,e6]", I: "[d5,d6] [c5,c6] [a4,a5] [c5,c6]@13",
  J: "~@7 [g4,g5], ~ [g4,g5]@4 [c5,c6] [b4,b5]@2, ~ [a4,a5]@3, ~@3 [e5,e6]@5, ~ [d5,d6]", K: "[b4,b5] [d5,d6]",
  L: "[c5,c6]", M: "[~@3 g4 d4@6 ~@6, [c4,c5] ~@3]/2",
})).s("gm_piano").gain(0.46)

// bass · synth bass 1
const bass = note(`<
  ~ A B C D@2 B E F A B C D@2 B E F A G H D I B E J K L M@2 K N O@2 K N P Q K R S T A B C D@2 B E F A G H D I B E J K L
  M@2 K N O@2 K N P Q K R S T U V W X Y V Z AA U AB AC AD AE AF AG AH A B C D@2 B E F A B C D@2 B E AI A B C D@2 B E AJ
  A B C D@2 B E F A B C D@2 B E F A B C D@2 B E F
>`.pickRestart({
  A: "d1@4 ~@2 d1!2 ~@8", B: "g1@8 ~@4 g1@3 ~@17", C: "a1@8 ~@4 a1@2 a1@2 ~@8 g1@3 ~@5", D: "f1@4 ~@2 f1!2 ~@8",
  E: "d#1@11 ~ d#1@11 ~ d1@7 ~", F: "c1@7 ~@25", G: "g1@4 ~@2 g1!2 ~@8", H: "a1@8 ~@4 a1@2 a1@10 g1@3 ~@5",
  I: "f1@4 ~@2 f1 f1@7 f1 ~", J: "c1@4 ~@2 c1 ~@5 c1@2 ~@2", K: "f1@3 ~@9 f1@16 ~@4", L: "g#1@11 ~ g#1@14 ~@6",
  M: "[c2@11 ~ c2@29 ~@23]/2", N: "g#1@3 ~@9 g#1@14 ~@6", O: "[c2@3 ~@9 c2@29 ~@23]/2", P: "c2@27 ~ g1@3 ~",
  Q: "a1@3 ~@9 a1@19 ~", R: "g1@3 ~@9 g1@16 ~@4", S: "d#2@7 ~@5 d#2@12 d2@3 ~@5", T: "c2@29 ~@3",
  U: "a#1@3 ~@9 a#1@19 ~", V: "d1@3 ~@9 d1@7 ~ d1@7 ~ d1@2 f#1@2", W: "g1@3 ~@9 g1@7 ~ g1@7 ~ d1@2 f1@2",
  X: "g1@3 ~@9 g1@7 ~ g1@7 ~ a1@3 ~", Y: "a#1@3 ~@9 a#1@14 ~@2 f1@2 d#1@2", Z: "g1@3 ~@9 g1@7 ~ g1@12",
  AA: "g1@3 ~@9 g2@2 ~@2 f2@4 g2@4 f2@2 d2@2 c2@2 d2@2", AB: "d1@3 ~@9 d1@19 ~", AC: "g1@3 ~@9 g1@7 ~ g1@11 ~",
  AD: "g1@3 ~@9 g1@4 g2@2 ~@2 f2@2 ~@2 d2@2 c2@2 a#1@2 ~@2", AE: "c2@3 ~@9 c2@7 ~ g1@3 ~ c2@3 ~ g1@3 ~",
  AF: "c2@3 ~@9 c2@7 ~ c2@3 ~ a#1@3 ~ c2@3 ~", AG: "f1@3 ~@9 f1@7 ~ f1@7 ~ f1@2 f#1@2", AH: "g1@3 ~@13",
  AI: "c1@7 ~@5 c1@7 ~@3 c1@2 c1@4 e1@4", AJ: "c1@3 c1",
})).s("gm_synth_bass_1").gain(0.42)

// chords · pad choir
const pad_choir = note(`<
  ~@25 A B C D A B E@2 F G H@2 I J K L ~@16 A B C D A B E@2 F G H@2 I J K M N O P ~ N O P ~ N O P ~ Q@2 R S ~@48
>`.pickRestart({
  A: "[f4,a4,c5]", B: "[g#4,c5,d#5]", C: "[g4,c5,e5]", D: "[c5,e5,g5] [g4,c5,e5]", E: "[g4,c5,e5]/2",
  F: "[f4,a4,c5] [a4,c5,f5]", G: "[g#4,c5,d#5] [g#4,c5,d#5,g5]", H: "[[c5,e5,g5]@63 ~]/2", I: "[c5,f5,a5]",
  J: "[b4,d5,g5]", K: "[c5,d#5,g5]", L: "[g4,c5,e5]@17 ~@15", M: "[g4,c5,e5]@25 ~@7", N: "~@6 [d4,a#4,d5]@7 ~@3",
  O: "~@6 [f#4,d5,f#5]@7 ~@3", P: "~@6 [a#4,d5,g5]@7 ~@3", Q: "[[e4,e5]@63 ~]/2", R: "[f4,f5]", S: "[g4,g5]",
})).s("gm_pad_choir").gain(0.17).pan(0.6)

// other · synth strings 1
const synth_strings_1 = note(`<
  ~@25 A B C D A B E@2 F G H D I J K@2 ~@8 L M N L ~@3 O P@2 ~@2 Q R S@2 T U V W X Y Z@2 ~@16 AA AB AC AD AE AF AG@2 ~@4
  AH AI AJ@2 AK AL AM AK AN AO AP@2 AQ AB AR AS AD H@2 AT AU AV AW AX AY@2 AZ@2 AU AV AW AX AY@2 AZ@2
>`.pickRestart({
  A: "f5", B: "d#5", C: "e5", D: "g5 e5", E: "[e5@3 c5]/2", F: "~ f5, c5", G: "d#5 g5", H: "g5", I: "c5", J: "d5",
  K: "[c5@49 ~@15]/2", L: "a4", M: "b4", N: "e5@3 e4", O: "~@3 c6, c5, ~ g5@3", P: "[c6@5 ~@3]/2", Q: "[a4,a5]",
  R: "[c5,c6] [d5,d6]", S: "[[c5,c6]@57 ~@7]/2", T: "~ [a3,a4]", U: "[c4,c5] [d4,d5]", V: "[e4,e5] [g4,g5]",
  W: "[a4,a5] [c5,c6]", X: "[c5,c6]", Y: "[d5,d6]", Z: "[[c5,c6]@43 ~@21]/2", AA: "~ a3 b3 c4", AB: "d4 e4 f4 g4",
  AC: "a4 b4 c5 e5", AD: "a5", AE: "a5 d6", AF: "b5 g5", AG: "[~ c7, c6]/2", AH: "~@3 c4", AI: "d4", AJ: "c4/2",
  AK: "[a3,a4]", AL: "[b3,b4]", AM: "[e4,e5]@3 [e3,e4]", AN: "a3", AO: "b3", AP: "[~ [c5,c6], c4]/2", AQ: "a3@2 b3 c4",
  AR: "a4@3 e5", AS: "a5@27 ~ f5@3 ~", AT: "[c6,c7]", AU: "a4@2 b4 c5", AV: "d5 g5", AW: "[e5,a5]", AX: "[c5,e5]",
  AY: "e5/2", AZ: "[~ c6, c5]/2",
})).s("gm_synth_strings_1").gain(0.3).pan(0.6)

// other · pad sweep
const pad_sweep = note(`<
  ~ A B C A@2 B D@2 A B C A@2 B D@2 A B C A@2 B D@2 ~@16 A B C A@2 B D@2 A B C A@2 B D@2 ~@32 A B C A@2 B D@2 A B C A@2
  B D@2 A B C A@2 B D@2 A B C A@2 B D@2 A B C A@2 B D@2 A B C A@2 B D@2
>`.pickRestart({
  A: "f4 ~ c4 ~ a5 ~ f4!2 ~ c4 ~ a5@3 f4 ~", B: "g4 ~ d4 ~ b5 ~ g4!2 ~ d4 ~ b5@3 g4 ~",
  C: "a4 ~ e4 ~ c6 ~ a4!2 ~ e4 ~ c6@3 g4 ~", D: "c5 ~ c5 ~ c5 ~ c5!2 ~ c5 ~ c5@3 c5 ~",
})).s("gm_pad_sweep").gain(0.2).pan(0.3)

// other · harpsichord
const harpsichord = note(`<
  ~ A ~ B C D E ~ F G H I ~ J H K L M N O P Q H R ~@17 S T U C@2 V W ~ X Y U C@2 Z AA ~@33 X Y U C AB Y AC ~ X Y U C@2 Y
  AD ~ AE Y AF C AG Y AD ~ AH V AI AJ@2 AK AL ~ X V AM AN AO Y AC AP AQ V U C@2 Y AC ~
>`.pickRestart({
  A: "d2@8 g2!2 ~ g2 ~@20", B: "a2@4 e3 ~@11", C: "f2@7 ~@25", D: "f2@8 e3!2 ~ e3 ~@20", E: "d3@8 b2!2 ~ b2 ~@20",
  F: "c2@7 ~@25", G: "d2@8 f3!2 ~ f3 ~@20", H: "g2 ~@3", I: "a2@8 c4!2 ~ c4 ~@20", J: "f2@8 ~@16 a3!2 ~ a3 ~@4",
  K: "d#2 ~@3", L: "c2 ~@3", M: "d2@8 a3!2 ~ a3 ~@20", N: "g2@4 g3!2 ~ g3 ~@8", O: "a2 ~@2 g2", P: "f2 ~@3",
  Q: "f2@8 e3!2 ~@22", R: "~@8 d#3!2 ~@6 d#4@2 c4@2 g#3@2 d#3@2 g3@2 ~@6", S: "d2@8 e3!2 ~ e3 ~@20",
  T: "g2@8 e3!2 ~ e3 ~@20", U: "a2@7 ~@17 g2@7 ~", V: "g2@7 ~ g3!2 ~ g3 ~@20",
  W: "~@8 d#3!2 ~@6 d#4@2 a#3@2 g3@2 d#3@2 g3@2 d#3@2 c3@2 ~@2", X: "d2@7 ~@25", Y: "g2@7 ~@25",
  Z: "g2@8 g3!2 ~ g3 ~@20", AA: "d#2@8 d#3!2 ~@6 d#4@2 a#3@2 g3@2 d#3@2 g3@2 d#3@2 c3@2 ~@2",
  AB: "~@6 a2@4 a2@2 a2 ~@5 f3@3 ~ f3@2 f3 ~@7",
  AC: "d#2@7 ~ d#3!2 ~ d#3 ~@4 d#4@2 a#3@2 g3@2 d#3@2 g3@2 d#3@2 c3@2 ~@2",
  AD: "d#2@8 d#3!2 ~ d#3 ~@4 d#4@2 a#3@2 g3@2 d#3@2 g3@2 d#3@2 c3@2 ~@2", AE: "d2@7 ~ e3!2 ~ e3 ~@20",
  AF: "a2@7 ~@15 e4@2 ~@2 c4@2 a3@2 e3@2", AG: "f2@7 ~@9 a4@2 f4@2 c4@2 a3@2 f4@2 c4@2 a3@2 f3@2",
  AH: "d2@7 ~ a3!2 ~ a3 ~@4 a3!2 ~ a3 ~@12", AI: "a2@7 ~ a3!2 ~ a3 ~@4 a3!2 ~ a3 ~@12",
  AJ: "f2@7 ~ a3!2 ~ a3 ~@4 a3!2 ~ a3 ~@12", AK: "g2@7 ~ g3!2 ~ g3 ~@4 g3!2 ~ g3 ~@12",
  AL: "d#2@7 ~ d#3!2 ~ d#3 ~@4 d#4@2 a#3@2 g3@2 d#3@2 g3@2 d#3@2 ~@4", AM: "a2@7 ~ a3!2 ~ a3 ~@20",
  AN: "~@12 a3!2 ~@2 a3!2 ~@14", AO: "f2@7 ~ a3!2 ~ a3 ~@20", AP: "~@24 d4!2 ~ d4 ~@4", AQ: "d2@7 ~ a3!2 ~ a3 ~@20",
})).s("gm_harpsichord").gain(0.31)

// other · orchestral harp
const orchestral_harp = note("<~@24 A B ~@2 A C ~ D ~@7 D ~@16 A B ~@2 A C ~ D ~@7 D ~@65>".pickRestart({
  A: "~@24 a4 b4 [c5,d5] e5 f5 g5 a5 [d5,e5]", B: "f5 g5 a5 b5 c6@2 ~@26",
  C: "f5 g5 a5 b5 [e5,c6] f5 g5 [a5,b5] c6@2 ~@22", D: "c6@2 ~@2 c6 b5 [g5,a5] f5 e5 d5 c5 [a4,b4] ~@20",
})).s("gm_orchestral_harp").gain(0.18).pan(0.4)

// other · orchestral harp · soft notes
const orchestral_harp_soft = note("<~@31 A ~@7 A ~@23 A ~@7 A ~@65>".pickRestart({
  A: "~@12 g4 f4 e4 d4 [b3,c4] a3 g3 f3 e3 [c3,d3] b2 a2 ~@8", // Cmaj7 Csus2
})).s("gm_orchestral_harp").gain(0.06).pan(0.4)

// other · orchestral harp
const orchestral_harp_2 = note("<~@25 A ~@3 B ~ C ~@7 C ~@17 A ~@3 B ~ C ~@7 D ~@65>".pickRestart({
  A: "a4 b4 [c5,d5] e5 f5 g5 a5 [d5,e5] f5 g5 a5 b5 c6@2 ~@18", // Csus2 Dsus2
  B: "a4 b4 [c5,d5] e5 f5 g5 a5 [d5,e5] f5 g5 a5 b5 [e5,c6] f5 g5 [a5,b5] c6@2 ~@14", // Csus2 Dsus2 C Asus2
  C: "~@8 c6@2 ~@2 c6 b5 [g5,a5] f5 e5 d5 c5 [a4,b4] g4 f4 e4 d4 [b3,c4] a3 g3 f3 e3 [c3,d3] b2 a2", // Gsus2 Asus2 Cmaj7 Csus2
  D: "~@8 c6@2 ~@2 c6 b5 [g5,a5] f5 e5 d5 ~@14", // Gsus2
})).s("gm_orchestral_harp").gain(0.11).pan(0.6)

// other · orchestral harp · soft notes · Asus2 Cmaj7 Csus2
const orchestral_harp_soft_2 = note("<~@71 [~@18 c5 [a4,b4] g4 f4 e4 d4 [b3,c4] a3 g3 f3 e3 [c3,d3] b2 a2] ~@65>")
  .s("gm_orchestral_harp").gain(0.04).pan(0.6)

// other · pad sweep
const pad_sweep_2 = note(`<
  ~ A B C A@2 B D@2 A B C A@2 B D@2 A B C A@2 B D@2 ~@16 A B C A@2 B D@2 A B C A@2 B D@2 ~@32 A B C A@2 B D@2 A B C A@2
  B D@2 A B C A@2 B D@2 A B C A@2 B D@2 A B C A@2 B D@2 A B C A@2 B D@2
>`.pickRestart({
  A: "~ f5 ~ c5 ~ a5 ~ f5!2 ~ c5 ~ a5@3 f5", B: "~ g5 ~ d5 ~ b5 ~ g5!2 ~ d5 ~ b5@3 g5",
  C: "~ a5 ~ e5 ~ c6 ~ a5!2 ~ e5 ~ c6@3 g5", D: "~ c6 ~ c6 ~ c6 ~ c6!2 ~ c6 ~ c6@3 c6",
})).s("gm_pad_sweep").gain(0.14).pan(0.6)

// drums · kick
const kick = s("bd").struct("<~ A B@38 C B@31 C B@3 D B@3 D B@7 C B@24 A B@7 A B@7 A B@7>".pickRestart({
  A: "x ~@6 x ~@8", B: "x ~@2 x ~@4", C: "x", D: "x ~@2 x ~ x ~@2",
})).gain(0.59)

// drums · clap
const clap = s("cp").struct("<~@73 [~ x ~ x]!15 ~@49>").gain(0.39)

// drums · snare
const snare = s("sd").struct("<~ A@23 B A@15 B A@15 ~ A@15 B A@15 B A@15 ~ A@7 C A@15 ~ A@8>".pickRestart({
  A: "~@8 x!2 ~@14 x!4 ~@4", B: "~@8 x!2 ~@22", C: "~@8 x!2 ~@14 x!2 ~@2 x!4",
})).gain(0.26)

// drums · hihat
const hihat = s("hh").struct(`<
  A B@2 C D@2 C E F G C@2 D C G D H I J K L M N O P Q@3 R Q@3 R Q@3 R Q@3 S G C@2 D C G D H I J K L M N O P Q@3 R Q@3 R
  Q@3 R Q@3 S T U V W T U V W X Y Z U AA AB W@2 G C@2 D C G D H G C@2 D C G D H G C@2 D C G D H B@2 C D@2 C E F B@2 C
  D@2 C E F B@2 C D@2 C E F
>`.pickRestart({
  A: "~@28 x!2 ~ x", B: "x!5 ~ x!2 ~ x ~ x ~@2 x!2", C: "x ~ x!3 ~ x!2 ~ x ~ x ~@2 x!2",
  D: "x ~@3 x ~ x ~ x ~@3 x ~ x ~@3 x ~@3 x ~@5 x!2 ~ x", E: "x ~ x!3 ~ x!2 ~ x ~@3 x!3", F: "x!5 ~ x!2 ~ x ~ x!3 ~@2",
  G: "x ~ x!3 ~ x!2 ~ x ~ x ~ x!3", H: "x!5 ~@3 x ~ x!4 ~@2",
  I: "x ~@3 x ~ x ~ x ~@3 x ~ x ~@3 x ~@3 x ~@3 x ~ x!2 ~ x",
  J: "x ~ x ~ x ~@3 x ~@3 x ~ x ~@3 x ~ x ~ x ~ x ~ x ~ x!2 ~ x", K: "x ~ x!3 ~ x!2 ~ x ~@3 x ~ x",
  L: "x ~ x!3 ~ x!4 ~@4 x!2", M: "x ~ x ~ x ~ x ~ x ~@3 x ~ x ~@3 x ~@3 x ~ x ~ x ~ x!2 ~ x",
  N: "x ~ x!3 ~ x!2 ~ x ~@2 x!2 ~@2", O: "x ~ x!3 ~ x!2 ~ x ~ x!2 ~ x!2", P: "x ~ x!3 ~ x!2 ~ x ~ x!3 ~@2",
  Q: "x ~ x!3 ~@2 x!2 ~ x!3 ~@2 x", R: "x ~ x!3 ~@2 x!6 ~@3", S: "x ~@3 x!2 ~@2 x!5 ~@3",
  T: "x ~@5 x ~ x ~@9 x ~@5 x ~@3 x!2 ~ x", U: "x ~@3 x ~@4 x ~ x!2 ~ x!2", V: "x ~@2 x!2 ~@2 x ~ x ~ x!2 ~ x!2",
  W: "x ~@2 x!2 ~@2 x ~ x ~ x!2 ~@3", X: "x ~@2 x!2 ~@2 x ~ x ~ x ~@3 x", Y: "x ~@3 x ~@5 x!3 ~@2 x",
  Z: "x ~@2 x!2 ~@2 x ~@3 x!2 ~@3", AA: "x ~@7 x ~@5 x ~@3 x ~@3 x ~ x ~@4 x ~ x",
  AB: "x ~@2 x!2 ~@2 x ~ x ~ x!2 ~@2 x",
})).gain(0.26)

// drums · hihat · soft notes
const hihat_soft = s("hh").struct(`<
  ~@25 A@3 B A@3 B A@3 B A@3 C ~@16 A@3 B A@3 B A@3 B A@3 C D E F@2 D E F@2 G H D I J K L F ~@48
>`.pickRestart({
  A: "~ x ~@3 x!2 ~@2 x ~@3 x!2 ~", B: "~ x ~@3 x!2 ~@6 x ~@2", C: "~@2 x ~ x!2 ~ x ~@18 x ~@5",
  D: "~ x!2 ~@5 x ~@4 x ~@2", E: "~ x ~@5 x ~@5 x ~@2", F: "~ x!2 ~@2 x!2 ~ x ~ x ~@2 x ~@2",
  G: "~ x!2 ~@2 x!2 ~ x ~ x ~@3 x ~", H: "~ x!2 ~@4 x!2 ~@4 x!2 ~", I: "~@14 x ~ x ~@3 x ~@4 x ~ x ~@4",
  J: "~@3 x ~@2 x ~ x ~ x ~@2 x!2 ~", K: "~@2 x ~@3 x ~ x ~ x ~@2 x!2 ~", L: "~ x!2 ~@3 x ~ x ~ x ~@2 x!2 ~",
})).gain(0.07)

// drums · low tom
const low_tom = s("lt").struct("<~@56 [~@11 x!2 ~ x!2] ~@80>").gain(0.33)

// drums · open hat
const open_hat = s("oh").struct(`<
  ~@8 A ~@7 A ~@5 A ~ A ~@3 A ~@3 A ~@3 A ~@3 A ~@7 A ~@5 A ~ A ~@3 A ~@3 A ~@3 A ~@3 A ~@3 A ~@3 A ~ B A C ~@3 A ~@7 A
  ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A
>`.pickRestart({
  A: "~@7 x", B: "~@3 x ~@12", C: "~ x!2 ~@13",
})).gain(0.39)

// drums · mid tom
const mid_tom = s("mt").struct("<~@24 A ~@15 B ~@15 C ~@15 D ~@15 B ~@15 C ~@7 E ~@15 F ~@8>".pickRestart({
  A: "~@9 x ~ x ~@4", B: "~@11 x!2 ~@3", C: "~@4 x ~@4 x ~@6", D: "~@11 x ~@4", E: "~@9 x ~ x ~@2 x ~",
  F: "~@4 x ~@4 x ~ x ~@4",
})).gain(0.39)

// drums · high tom
const high_tom = s("ht").struct("<~@24 A ~@15 B ~@15 C ~@15 B ~@15 B ~@15 C ~@7 D ~@15 C ~@8>".pickRestart({
  A: "~@6 x!2 ~@8", B: "~ x", C: "~@2 x ~@3 x!2 ~@8", D: "~@3 x ~@2 x ~",
})).gain(0.39)

stack(
  piano, bass, pad_choir, synth_strings_1, pad_sweep, harpsichord, orchestral_harp, orchestral_harp_soft,
  orchestral_harp_2, orchestral_harp_soft_2, pad_sweep_2, kick, clap, snare, hihat, hihat_soft, low_tom, open_hat,
  mid_tom, high_tom
)

More by Annie Lennox