Strudelify

My Love My Life

ABBA

KeyG majorTempo73 bpm
0:00/0:00
// My Love My Life — ABBA
// 73 bpm, 4/4, key G 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 64 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(73/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 · fretless bass · "Bass"
const bass = note("<~@7 [d2 f2 g2 g#2] [a2 d2] [g2@7 ~] ~@54>").s("gm_fretless_bass").gain(0.46)

// chords · string ensemble 2 · "String"
const string_ensemble_2 = note("<A@4 B C@2 D@3 E@6 ~@18 B C@2 D@3 E@6 ~@18>".pickRestart({
  A: "[f#4@15 ~ g4@15 ~ f#4@15 ~ g4@13 ~@3, [c4,e4]@31 ~]/4", B: "[g3,c4,e4]@15 ~",
  C: "[[g3,b3,d4]@15 [g3,c4,e4]@17]/2", // G C
  D: "[[a3,c4,f4]@7 [b3,d4,g4]@4 [b3,d4,g#4]@4 [c4,e4,a4]@8 [a3,f#4]@8 [b3,g4]@15 ~@2, ~@23 d4@23 ~@2]/3", // F G G#dim Am D Em
  E: "[[c4,e4]@7 f#4@8 ~ f#4@7 ~@8 a4@8 ~@9 f#4@7 f#4@8 ~ b3@32, a3@15 ~ [b3,g4]@15 c4@16 d4@48 ~, ~@7 d4@17 e4@23 ~ a3@15 ~ f#4@7 ~@25, ~@39 g4@16 ~@8 g4@32 ~]/6", // C Em
})).s("gm_string_ensemble_2").gain(0.31)

// chords · piano
const piano = note(`<
  A B A C@2 D E F G H I J K@2 L M N O P Q R S T@3 U V W X Y Z AA AB@2 AC D E F G H I J K@2 L M N AD P Q R S T@3 U V W X
  Y Z AA AB@2
>`.pickRestart({
  A: "f#4 c4 f#4 c4 f#4 c4 f#4 c4", B: "g4 c4 g4 c4 g4 c4 g4 c4",
  C: "[g4@2 c4@2 g4@2 c4@2 g4@2 c4@2 g4@2 c4 ~ c5@8 c5@3 ~ c5@3 ~, ~@15 g4@7 ~@10, ~@16 e5@11 e5@4 ~]/2",
  D: "~@7 b4 b4@3 ~ b4@2 d5 ~, [b4,d5]@4 d5@3 ~, ~@6 g4@5 g4@3 ~@2", E: "c5@3 c5@3 ~ c5@4 [g4,c5]@5, e5@3 e5@4 ~",
  F: "c5@4 c5@2 f5 ~ g5@6 [b4,d5] ~, f5@3 ~@5", G: "~@3 a5 f#5@3 d5, a5@3 ~@5, ~ c5@3 ~@4, ~ e5 ~@2",
  H: "~@6 g5@2 d5@3 d5@4 ~, g5@6 ~@2 g5@7 ~, d5!2 ~@2, ~ b4@4 ~@3",
  I: "~@2 a5@2 [e5,a5]@2 c5 ~@5 d5@2 f#5 ~, g5@7 ~ f#5@6 ~@2", J: "[d5,g5]@4 [b4,d5,g5]@3 ~@9",
  K: "[~@13 c5@2 e5@8 ~@5 d5@2 f#5 ~, ~@7 d5@8 ~@8 d5@5 ~@4, ~@11 b4@4 ~@11 a4@5 ~]/2",
  L: "[d5,g5]@6 g5 ~@4 g5@5, ~@7 f#5@9", M: "d5 ~ b4@4 [b4,d5,g5]@2 [b4,d5,g5]@8, g5@3 ~@5",
  N: "d5@2 d5 [b4,d5,g5] b4 ~@2 g5, g3 [g3,g4], g5@3 ~ g5@3 ~, b4 ~@3 d5@2 d5@2, ~@5 b4@3", // G
  O: "[g4,c5,e5]@5 ~ g4 ~ [a4,f5]@3 ~ [a4,c5,f5]@3 ~, ~@7 c5@4 ~@5", // C Dm F
  P: "b4 ~@5 g5!2 ~@6 g5@2, g5@3 ~ g5@3 ~, d5!2 [g3,g4]@2, ~ b4@4 b4@3, ~@2 d5!2", // G
  Q: "~@2 c5!2 g4 ~@2 e5, [c3,c4,e5] [c3,c4], c5@2 ~@2 e5@3 ~, ~ g4@3 c5@2 c5@2, ~@5 g4@3", // C
  R: "~@2 [a4,d5]@2 [f#4,a4]@3 ~@3 d5@2 f#4@2 f#4@2, d3, d4@6 ~ f#4@5 ~@4, ~@2 d5@3 ~@3, ~@2 a4 [a4,d5]", // D5 F#m D5
  S: "[g4,a4] ~ g4@2 g4@2 g4@2 ~@2 [e4,g4,b4]@2 ~@3 e4, [g2,g3] e2, [b4,d5]@2 [b4,d5]@2 e3@3 e3, ~@3 [e4,g4,b4]", // Gsus2 Em G Bm Em
  T: "[[g2,g3] ~ e4@2 ~@2 a4@2 a4@2 ~@2 c5@2 ~@4 g5@2 ~@8 g5@2 [g5,b5]@2 d5@2 ~@4 d5@2 ~@6 d5@2, a3@5 [g3,g4]@3 [g3,b5]@4, a2@8 ~@2 a4@10 ~@3 d5@3 d5@6 g4@10 ~@2 b4@4, ~ c5@3 e5@6 [d5,g5]@2 g5@2 ~@2 g5@4 g5@4, ~ a4 e4@2 c5@2 ~ [c5,d5]@3 ~ b4@7 ~@2 d5@3 ~]/3", // G G5 Csus2
  U: "[g3,g4,d5,g5] ~@2 e5 ~@4, ~ c5 ~@2", // G5
  V: "d5 ~@3 d5@2 [d5,g5]@2 ~@6 g5@2, [g3,g4]@5 [g3,g4]@3, g5@3 ~ g5@3 ~, ~@8 [b4,d5]@3 b4@5, ~@3 d5", // G5 G Bm
  W: "c5@2 ~ e5@3 ~ e5, [c3,c4], e5@3 ~@5, ~ c5@2 c5", X: "[d3,d4], [d5,f#5] ~@15",
  Y: "g3@6 c3 ~@7 e5@2, ~ [c3,c4], ~@4 e5@3 ~, ~@2 c5!2, ~@5 g4@3", // C
  Z: "[d3,d4]@3 ~@3 a3@2 [c4,f4]@2 ~ b3 [g#3,b3,e4]@2 g#3 ~, ~@4 [f2,f3,c4,f4]@4 [f2,f3]@7 ~, ~@8 [g#3,e4] ~ d#4@5 ~, ~@5 g#3 ~@2", // D F5 E F5 F C#m
  AA: "~@4 [b3,e4]@2 g#3 ~@9, ~@4 g#3 ~@11", // E5
  AB: "[~@8 e4@2 ~@11 e5@2 ~@4 c5@3 ~@2, ~@4 g3@21 g4@5 ~@2, ~@3 c4@2 c4@10 ~, ~@11 e4@19 ~@2, ~@13 g4@2 e5@2 g4@2 c5@4 e5@7 ~@2]/2",
  AC: "e5@3 ~@5 c5@2 ~@2 c5 ~@3, c5 ~@10 e5@3 ~@2",
  AD: "~@3 [d#5,e5] f5 ~@2 g5, [c3,c4] [d3,d4], e5@3 ~@3 d5@2, c5@2 c5@2 ~ b4@3, ~ g4@3 ~@4", // Emaj7 C D
})).s("gm_piano").gain(0.32)

// chords · piano · soft notes
const piano_soft = note(`<
  ~@4 A B C D E F E ~ G ~ H ~ I ~@3 J ~@3 K L M N O P ~@2 Q@2 R B C D E F E ~ G ~ H ~ I ~@3 J ~@3 K L M N O P ~@2 Q@2
>`.pickRestart({
  A: "~@6 g4@9 g4", B: "~@14 g4 ~", C: "~@2 g4@7 g4@2 ~@3 e5@2", D: "~@2 a4@5 ~ f#5 ~ b4@4 ~@2", E: "~@10 a4@5 ~",
  F: "~@10 b4@5 ~", G: "~@2 g4@2 g4@6 g4@5 ~, d5@7 ~@9", H: "~@6 d5 ~@9", I: "~ b4@2 ~@5, g4 ~", J: "~@3 d4@5",
  K: "~@5 g4@3, ~ d5@2 ~@5, ~ b4@2 ~", L: "~@7 b4", M: "~ b4@3 ~@4", N: "~ g4@4 ~ e5 ~, ~@5 g4@3", O: "~ [f#4,d5]@3",
  P: "g4@6 [c4,c5,e5] ~ g4@2 ~@6", Q: "[~ [c2,c3]@14 ~]/2", R: "~@6 g4@2 ~@7 g4",
})).s("gm_piano").gain(0.16)

// other · pad new age · "New Age"
const pad_new_age = note("<[f#6 ~@15] [g6 ~@15] [f#6 ~@15] [g6 ~@15] ~@60>").s("gm_pad_new_age").gain(0.67)

// chords · string ensemble 2 · "String"
const string_ensemble_2_2 = note(`<
  ~@4 A B C@4 D E@3 F G H I J@2 K H L M@2 I N O@2 P Q R S@2 ~@12 H I J@2 K H L M@2 I N O@2 P Q R S@2
>`.pickRestart({
  A: "c3", B: "b2", C: "[c3@15 d3@7 f3@2 g3@4 g#3@3 a3@8 d3@8 g2@16 ~]/4", D: "a2@8 d3@7 ~",
  E: "[g2@7 e2@8 a2@8 g2@8 d3@17]/3", F: "g2@6 d3 f3@5 e3@4, ~@7 e3 ~@8", G: "d3@15 ~", H: "[g3,b3,d4]@15 ~",
  I: "[g3,e4]@7 ~ [a3,f4]@7 ~, c4@15 ~", J: "[[b3,d4,g4]@15 [g3,c4,e4]@16 ~]/2", K: "[f#3,a3,d4]",
  L: "[a3,c4,e4] [a3,d4,f#4]", M: "[b3,d4,g4]", N: "[b3,d4,g4]@7 ~",
  O: "[[g3,e4]@15 ~ [a3,f4]@7 ~ [b3,d4,g4]@8, c4@23 ~@9]/2", P: "[g3,c4,e4]@15 a3",
  Q: "[a3,c4,f4]@6 ~@2 [g#3,b3,e4]@7 ~", R: "[a3,e4]@7 ~ [a3,f4]@8, c4", S: "[g3,c4,e4]",
})).s("gm_string_ensemble_2").gain(0.51)

// other · string ensemble 2 · "String"
const string_ensemble_2_3 = note("<~@9 A ~ B ~@20 C@2 ~@5 A ~ B ~@8 D E F G ~@8 C@2>".pickRestart({
  A: "~@4 g5@2 f#5 ~@5 f#5@2 e5 ~", B: "~@4 f#5@2 e5 ~@5 e5@2 d5 ~", C: "c7/2", D: "d6@3 a6", E: "g6@2 e6 b6", F: "a6",
  G: "g6",
})).s("gm_string_ensemble_2").gain(0.22)

// bass · electric bass finger · "Bass"
const bass_2 = note(`<
  ~@16 A B C D E F G H A I J K L M N O P@2 Q R S T U F U V W X Y Z A B C D E F G H A I J K L M N O P@2
>`.pickRestart({
  A: "g1@4 ~@2 g1 a1 b1@5 ~ b1@2", B: "c2@2 f1 d1", C: "g1@4 ~@3 g1 g1@4 ~@2 g1@2", D: "c1@5 ~@2 c1 c1@5 ~ c1@2",
  E: "d1@7 ~ d1@5 ~ d1@2", F: "g1@3 f#1 e1@4", G: "a1@4 ~@2 a1@2 d1@5 ~ d1@2", H: "g1@15 f1", I: "c1@8 d1@5 ~ d1@2",
  J: "g1@7 ~ g1@5 ~ g1@2", K: "c1@7 ~ c1@3 ~@3 c1@2", L: "f1@5 ~ f1@2 g1@5 ~ g1@2", M: "c1@7 ~ c1@5 ~ c1@2",
  N: "f1@5 ~ f1@2 e1@5 ~ e1@2", O: "a1@3 g1 f1@4", P: "[c1@11 ~@5]/2", Q: "c1 ~ c1@2", R: "g1@4 ~@2 g1 ~ g1@5 ~ g1@2",
  S: "c1@4 ~@2 c1 ~ c1@4 ~@2 c1@2", T: "d1@4 e1@2 f1 ~ g1@4 g#1@4", U: "a1@2 ~ a1 d1@2 ~ d1", V: "g1 e1",
  W: "a1@4 ~@2 a1 ~ a1@4 g1@4", X: "d2@6 ~ d2 d1@8", Y: "g1@4 ~@2 d1 e1 f1@4 e1@4", Z: "g1@7 ~",
})).s("gm_electric_bass_finger").gain(0.5).pan(0.4)

// other · string ensemble 2 · "Sting"
const string_ensemble_2_4 = note("<~@12 A@2 B@3 ~@17 C D E F G H ~@2 A@2 B@3 ~@17>".pickRestart({
  A: "[a5@15 d6@17]/2", B: "[g6@3 ~]/3", C: "c6 ~@3 c6 ~@3 c6 ~@3 c6@4", D: "b5 ~@3 b5 ~@3 g5 ~@3 g5@4",
  E: "c6 ~@3 c6 ~@3 c6 ~@3 c6 ~@3", F: "d6", G: "e6 ~@3 e6 ~@3 d6 ~@3 d6 ~@3", H: "b5 ~@3 b5 ~@3 g5 ~@7",
})).s("gm_string_ensemble_2").gain(0.12)

// other · pan flute
const pan_flute = note(`<
  ~@20
  [~@4 e5 ~ e5 ~ e5@2 d5@6]
  [~@4 f#5 ~ f#5 ~ f#5@2 d5@6]
  ~@28
  [~@4 e5 ~ e5 ~ e5@2 d5@6]
  [~@4 f#5 ~ f#5 ~ f#5@2 d5@6]
  ~@12
>`).s("gm_pan_flute").gain(0.38).pan(0.6)

// other · flute
const flute = note("<~@24 A B C D ~@22 E F ~@12>".pickRestart({
  A: "~@4 g5 a5 g5@5 ~ g5 a5 g5@2", B: "e5@3 ~@3 e5@2 f5@6 g5 ~", C: "g5@3 ~ g5 a5 g5@5 ~ g5 a5 g5@2", D: "c5",
  E: "~@4 g5 ~ g5 ~ g5@2 f#5@6", F: "~@4 a5 ~ a5 ~ a5@2 g5@6",
})).s("gm_flute").gain(0.6)

// drums · kick
const kick = s("bd").struct("<~@16 A@7 B A@8 ~@2 A@2 C A@8 B A@7 B A@8 ~@2>".pickRestart({
  A: "x!2", B: "x", C: "~ x",
})).gain(0.5).pan(0.4)

// drums · rim
const rim = s("rim").struct("<~@34 [~ x ~ x]!11 ~@19>").gain(0.5).pan(0.4)

// drums · snare
const snare = s("sd").struct("<~@16 A@3 B A@3 C A@8 ~@14 A@3 B A@3 C A@8 ~@2>".pickRestart({
  A: "~ x ~ x", B: "~@4 x ~@7 x ~ x!2", C: "~ x ~@2",
})).gain(0.5).pan(0.4)

// drums · hihat
const hihat = s("hh").struct("<~@4 A@11 ~ B@16 ~@2 B@11 C B@16 ~@2>".pickRestart({
  A: "~ x ~ x", B: "x!8", C: "x!2 ~@6",
})).gain(0.5).pan(0.4)

// drums · mid tom
const mid_tom = s("mt").struct("<~@15 [~@12 x ~ x!2] ~@29 [~@12 x ~ x!2] ~@18>").gain(0.5).pan(0.4)

// drums · open hat
const open_hat = s("oh").struct("<~@15 [~ x ~@2] ~@17 [~@3 x] ~@11 [~ x ~@2] ~@18>").gain(0.5).pan(0.4)

// drums · high tom
const high_tom = s("ht").struct("<~@15 [~@3 x] ~@29 [~@3 x] ~@18>").gain(0.5).pan(0.4)

// drums · crash
const crash = s("cr").struct("<~@20 A ~@3 A ~@7 A ~@17 A ~@3 A ~@7 A ~>".pickRestart({
  A: "x",
})).gain(0.5).pan(0.4)

stack(
  bass, string_ensemble_2, piano, piano_soft, pad_new_age, string_ensemble_2_2, string_ensemble_2_3, bass_2,
  string_ensemble_2_4, pan_flute, flute, kick, rim, snare, hihat, mid_tom, open_hat, high_tom, crash
)

More by ABBA