Strudelify
Together Forever cover art

1987 · Whenever You Need Somebody

Together Forever

Rick Astley

KeyF majorTempo118 bpm
0:00/0:00
// Together Forever — Rick Astley
// 118 bpm, 4/4, key F major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: Full arrangement: all 101 bars on a 16-step grid, each part at one level. Source detail keeps the original performance.
setcpm(118/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 · piano · "STRINGS"
const bass = note("<db-1 ~@100>").s("gm_piano").gain(0.05)

// chords · string ensemble 1 · "STRINGS"
const string_ensemble_1 = note(`<
  ~@5 A B C D A E F G H I@3 J K@2 L M N O P M N O Q C D C D R@2 S G J T@2 U J V@2 L W@2 X Y M N X Z A B F D AA@2 S AB M
  N X Y M AC X AD S D C D AE@2 S G C D C D C B S AF C B S D A B S AG@2 ~@7
>`.pickRestart({
  A: "[eb3,g3,bb3]@5 ~ [f3,a3,c4]@9 ~", B: "[f3,a3,d4]@5 ~ [g3,bb3,d4]@9 ~", C: "[eb3,g3,bb3]@5 ~ [f3,a3,c4]@8 ~@2",
  D: "[f3,a3,d4]@5 ~ [g3,bb3,d4]@8 ~@2", E: "[f3,a3,c4]@5 ~ [g3,bb3,d4]@8 ~@2", F: "[g3,bb3,eb4]@5 ~ [f3,a3,c4]@8 ~@2",
  G: "[f3,bb3,d4]@13 ~@3", H: "[d3,f3,bb3]@7 ~", I: "[[f3,a3]@15 [d3,g3,bb3]@8 ~, c3@7 ~@5]/3", J: "[d3,f3,bb3]@15 ~",
  K: "[[c3,f3,a3]@31 ~]/2", L: "[d3,g3,bb3]@13 ~@3", M: "[f3,a3,d4]@15 ~", N: "[f3,ab3,db4]@15 ~",
  O: "[eb3,ab3,c4]@7 ~", P: "bb3@4 a3@3 ~, c4@15 ~, f4@13 ~@3", Q: "bb3@6 ~@2 a3@5 ~@3, [c4,f4]@3 ~",
  R: "[[eb3,g3,bb3]@5 ~ [f3,a3,c4]@15 ~ [g3,d4]@9 ~, ~@22 bb3@7 ~@3]/2", S: "[g3,bb3,eb4]@5 ~ [f3,a3,c4]@9 ~",
  T: "[[f3,a3], c3@29 ~@3]/2", U: "[d3,g3], bb3@7 ~", V: "[[f3,a3], c3@15 ~]/2",
  W: "[[a3,d4]@16 [ab3,db4]@15 ~, f3@31 ~]/2", X: "[eb3,ab3,c4]@15 ~", Y: "bb3@8 a3@7 ~, [f3,c4]@15 ~",
  Z: "bb3@7 ~ a3@5 ~@3, [c4,f4]@13 ~@3", AA: "[[eb3,g3,bb3]@5 ~ [f3,a3,c4]@14 ~@2 [g3,bb3,d4]@9 ~]/2",
  AB: "[f3,bb3,d4]@3 ~", AC: "f3 ~ f3@12 ~@2, [ab3,db4]@15 ~", AD: "bb3@4 a3@3 ~, [c4,f4]@7 ~",
  AE: "[[eb3,g3,bb3]@5 ~ [f3,a3,c4]@15 ~ [g3,bb3,d4]@8 ~@2]/2", AF: "[f3,bb3,d4]@7 ~", AG: "[[f3,bb3,d4]@9 ~@7]/2",
})).s("gm_string_ensemble_1").gain(0.4)

// other · brass section · "BRASS"
const brass_section = note(`<
  ~@4 A ~@3 B ~@3 C ~@11 D ~@3 E ~@3 F ~@3 C ~@11 D ~@3 G ~@3 H ~@3 C ~@3 D ~@3 E ~@3 H ~@3 C ~@3 H ~@3 C ~@3 H ~@3 I J
  ~@7
>`.pickRestart({
  A: "[bb4,c5,f5]!5 ~ [bb4,c5,f5]!5 ~ [bb4,c5,f5]!4", // Bbsus2
  B: "~ [d4,d5] [f4,f5] [d4,d5] [g4,d5,g5] d4 ~ [bb4,bb5] ~ [bb4,bb5] [g4,g5] ~@5", // D F D G5 Bb G
  C: "~@9 [bb4,bb5] ~@2 [bb4,bb5] ~@3", D: "~@9 [f4,f5] ~@2 [f4,f5] ~@3", E: "~@10 [f4,f5] ~ [f4,f5]!3 ~",
  F: "~ [d4,d5] [f4,f5] [d4,d5] [g4,g5] [d4,d5] ~ [bb4,bb5] ~ [bb4,bb5] [g4,g5] ~@5", // D F D G D Bb G
  G: "~@10 [f4,f5] ~ [f4,f5] ~ [f4,f5] ~", // F
  H: "~ [d4,d5] [f4,f5] [d4,d5] [g4,g5] [d4,d5] ~ [bb4,bb5] ~ [bb4,bb5] [g4,g5] ~ [f4,f5] [g4,g5] ~@2", // D F D G D Bb G F …
  I: "~@9 [bb4,bb5] ~@2 [g4,g5] [f4,f5] [d4,d5] ~", J: "[bb3,bb4]@3 ~@13",
})).s("gm_brass_section").gain(0.5)

// chords · electric guitar clean · "E.GUITAR"
const electric_guitar_clean = note(`<
  ~@5 A B C D E F G H@2 I J K@3 ~@2 L M ~ N O P ~ Q A R S T U V W X@2 ~@6 Y Z AA ~ AB AC AD AE AF AG AH AI R AJ AK C AL
  AM@2 AN AO AP AQ AR AS AT B AJ AK AJ AU AV AW AX AY W D G AZ BA BB BC D G BD BA BE BF BG@2 ~@7
>`.pickRestart({
  A: "~@2 eb3@2 g3@2 [f3,a3]@9 ~, bb3@3 ~@5", B: "~@2 f3@2 a3 ~ [g3,bb3]@8 ~@2, d4@13 ~@3",
  C: "~@2 eb3@2 g3 ~ [f3,a3]@10, bb3@5 ~@11", D: "~@2 f3@2 a3 ~ [g3,bb3]@10, d4",
  E: "~@2 g3@2 bb3 ~ [f3,a3]@10, eb4@5 ~ c4@8 ~@2", F: "~@2 f3@2 a3 ~ [g3,bb3]@10, c4@5 ~@11",
  G: "~@2 g3@2 bb3 ~ [f3,a3]@10, eb4@5 ~@11", // F
  H: "[~@10 c4@2 d4@5 ~@15, ~@4 bb2@13 ~@15, ~@6 f3@11 ~@15, ~@8 bb3@19 ~@5]/2", I: "~@7 d3",
  J: "f3@2 d3@2 f3@2 d3@2 f3@2 a3 ~@5", K: "[a3@2 ~@8 a3@2 ~@2 d4@23 ~@11, ~ g3@18 ~@5, ~@12 bb3@25 ~@11]/3",
  L: "~@4 d4@11 ~, bb2@7 ~, ~ [f3,a3]@7", M: "~@4 db4@11 ~, bb2@15 ~, ~ [f3,ab3]@7",
  N: "~@3 f3, ~@2 f3@8 g3@5 ~, ~@4 g3@4 a3@7 ~, ~@6 c4@9 ~", O: "~@3 d4@4 ~, ~ f3@7, ~@4 a3@11 ~",
  P: "~@8 db4@7 ~, ~ bb2@6 ~, ~@4 f3@11 ~, ~@3 ab3@5",
  Q: "~@6 g3 f3, ~ c3@5 ~@2, ~ f3@2 ~, ~@6 g3@4 a3@5 ~, ~@4 c4@3 ~", R: "~@2 f3@2 a3@2 [g3,bb3]@9 ~, d4@7 ~",
  S: "~@2 eb3@2 g3 ~ [f3,a3]@8 ~@2, bb3 ~@3", T: "~@2 f3@2 a3 ~ [g3,bb3]@8 ~@2, d4@7 ~",
  U: "~@2 g3@2 bb3 ~ [f3,a3]@10, eb4 ~@3", V: "~ f3 a3 [g3,bb3]@4 ~, c4 ~@3", W: "~@2 eb3@2 g3 ~ [f3,a3]@9 ~, bb3 ~@3",
  X: "[~@2 eb3@2 ~@2 d3@3 ~@5 bb3@13 ~@5, bb3@12 f3@5 ~@15, ~@10 bb2@11 ~@11]/2", Y: "~@6 bb3 c4, ~ bb2, ~@5 f3@3",
  Z: "~@3 d3@4 ~, d4@15 ~, ~ f3@7, ~ a3@3", AA: "~@3 db4@5, db3@13 ~@3, ~ f3@6 ~, ~@4 ab3@11 ~",
  AB: "~@7 c3, ~ c3@5 ~@2, ~@2 f3@3 ~ [f3,g3]@2, ~@3 g3@2 a3@2 ~, ~@4 c4@3 ~", AC: "~@4 a3@11 ~, d4@15 ~, ~@2 f3@13 ~",
  AD: "~@4 db4@9 ~@3, bb2@7 ~, ~@2 [f3,ab3]@13 ~", AE: "~@10 bb3@5 ~, ~ eb3@6 ~, ~@6 ab3@7 ~@3",
  AF: "~@4 bb3@2 c4 ~@5 f3@4, ~ f3@4 g3@3, ~ a3", AG: "~ eb3 g3 [f3,a3]@4 ~, bb3@5 ~@11",
  AH: "~@2 f3@2 a3 ~ [g3,bb3]@9 ~, d4@7 ~", AI: "~ eb3 g3 [f3,a3]@4 ~", AJ: "~@2 eb3@2 g3 ~ [f3,a3]@10, bb3 ~@3",
  AK: "~@2 f3@2 a3@2 [g3,bb3]@9 ~, c4@5 ~@11", AL: "f4 ~@2 [bb3,d4] ~ bb3 f3@2, ~ f3@4 ~@3, ~@4 c4@3 ~",
  AM: "[~ a3@3 ~@4, d4 ~, ~@2 f3@23 ~@7]/2", AN: "~ bb3 ~@2, eb3@13 ~@3, ~@2 ab3@11 ~@3",
  AO: "~@3 g3 ~@3 f3, ~ c3@6 ~, ~ f3@2 g3, ~ c4, ~@5 a3@3", AP: "~ d4, ~ f3@3, ~@3 a3@5",
  AQ: "~@8 db4@7 ~, ~@4 f3@11 ~, ~@6 ab3@9 ~", AR: "~@8 c4@7 ~, ~@2 eb3@5 ~, ~@3 ab3@4 ~",
  AS: "~@6 g3 f3, ~@3 f3@2 a3@2 ~, ~@8 c4@7 ~", AT: "~ eb3 g3 [f3,a3]@4 ~, bb3@3 ~@5",
  AU: "~ f3 a3 g3@5, d4@7 ~, ~@6 bb3@7 ~@3", AV: "~@2 g3@2 bb3 ~ [f3,a3,c4]@9 ~, eb4 ~@3",
  AW: "~@10 d4@3 ~@3, d4@3 c4@3 ~@2, ~@2 f3@11 ~@3, ~@4 bb3@9 ~@3", AX: "~ eb3 g3 [f3,a3]@5, bb3@5 ~@11",
  AY: "~ f3 a3 [g3,bb3]@4 ~, d4@7 ~", AZ: "~@2 f3@2 a3 ~ [g3,bb3,d4]@10, c4@5 ~@11",
  BA: "~@2 g3@2 bb3 ~ [f3,a3,c4]@10, eb4 ~@3", BB: "~@4 c4 ~ c4 ~, d4@4 ~ d4@2 ~, ~ f3@6 ~, ~@3 bb3@2 ~@3",
  BC: "~@2 eb3@2 g3 ~ [f3,a3]@9 ~, bb3@5 ~@11", BD: "~@2 f3@2 a3 ~ [g3,bb3,d4]@10, d4@5 ~@11",
  BE: "~@2 f3@2 ~@2 [f3,g3] ~@3 g3@6, c4 ~ [bb3,d4]@2", BF: "~@2 g3@2 bb3 ~ [f3,a3]@8 ~@2, eb4@5 ~ c4@10",
  BG: "[~@10 eb4@2 ~@2 c4 ~ [bb2,d3,f3]@5 ~@11, [bb2,f3]@15 ~@17, [bb3,d4]@5 ~ d4@2 ~@8, ~@2 d3@11 ~ bb3@7 ~@11]/2", // Bb Bb5 Bb
})).s("gm_electric_guitar_clean").gain(0.5)

// other · string ensemble 1 · "STRINGS"
const string_ensemble_1_2 = note(`<
  ~@5 A B C D E F G H ~@8 I J K L I J K M N O P Q R S T U ~@3 V ~@4 I J K W I J K W N X Y Q Z S AA U I J K AB AC AD AE W
  Z O Y Q Z S AA U AF O AG Q Z S T U Z O Y AH Z S T AI ~@8
>`.pickRestart({
  A: "g4@2 eb4 ~ d5 ~ c5@3 ~ a4@2 g4 ~ f4 ~", B: "~@2 d4 ~ f4 ~ g4 ~@7 f4@2", C: "g4 ~ eb4 ~ d5 ~ c5@2 ~@2 a4 ~ g4 ~@3",
  D: "g4 ~@3 f4 ~@9 [f4,f5] ~", E: "[g4,g5] ~ [eb4,eb5] ~ [d5,d6] ~ [c5,c6]@3 ~ [a4,a5] ~ [g4,g5] ~ [f4,f5]@2",
  F: "~@2 [g4,g5] ~ [a4,a5] ~ [bb4,bb5] ~@3 [bb4,bb5] ~ [c5,c6] ~ [d5,d6] ~", // G A Bb C D
  G: "[eb5,eb6] ~ [d5,d6] ~ [c5,c6] ~ [a4,a5] ~@3 [bb4,bb5] ~ [c5,c6] ~@3", H: "[bb4,bb5]@5 ~@3", I: "a4 ~@15",
  J: "ab4 ~@15", K: "g4 ~@15", L: "~@2 f4@2 bb4 ~ c5 ~ f5 ~@7", M: "~@2 f4 ~ bb4 ~ f5 ~@9",
  N: "g4@2 eb4 ~ d5 ~ c5@2 ~@2 a4 ~ g4 ~ f4 ~", O: "~@2 d4 ~ c5 ~ bb4 ~@7 f4@2",
  P: "g4@2 eb4 ~ d5 ~ c5@2 ~@2 a4 ~ g4 ~ a4 g4", Q: "f4 ~@13 f4@2", R: "g4 ~ eb4 ~ d5 ~ c5@2 ~@2 a4 ~ g4 ~ f4 ~",
  S: "~@2 g4 ~ a4 ~ bb4 ~@3 bb4 ~ c5 ~ d5 ~", T: "eb5 ~ d5 ~ c5 ~ a4 ~@3 bb4 ~ c5 ~ c5 ~", U: "~@2 bb4 ~@13",
  V: "~@6 a4@2 bb4 ~ f5 ~@5", W: "~@2 f4 ~ bb4 ~ c5 ~ f5 ~@7", X: "~@2 d4 ~ c5 ~ bb4 ~@7 f4 ~",
  Y: "g4 ~ eb4 ~ d5 ~ c5 ~@3 a4 ~ g4 ~ a4 g4", Z: "g4 ~ eb4 ~ d5 ~ c5 ~@3 a4 ~ g4 ~ f4 ~",
  AA: "eb5 ~ d5 ~ c5 ~ a4 ~@3 bb4 ~ c5 ~ c5@2", AB: "~@2 f4 ~ bb4@2 c5@2 f5 ~@7", AC: "[a4,a5] ~@15",
  AD: "[ab4,ab5] ~@15", AE: "[g4,g5] ~@15", AF: "g4@2 eb4 ~ d5 ~ c5 ~@3 a4 ~ g4 ~ f4 ~",
  AG: "g4@2 eb4 ~ d5 ~ c5 ~@3 a4 ~ g4 ~ a4 g4", AH: "f4 ~@13 f4 ~", AI: "~@2 [bb3,bb4] ~@8 bb4 [bb3,bb5] ~@3",
})).s("gm_string_ensemble_1").gain(0.5)

// bass · synth bass 1 · "SYNTH BASS"
const bass_2 = note(`<
  ~@4 A B C B C B D B E F@8 G H I J E K L J B C B C B D B M F@8 N O L J P O L J B C B C B Q B E R K I S N K T S B C B C
  B D B E B C B C B D B U B C B C B V B E W ~@7
>`.pickRestart({
  A: "f2!5 ~ f2!5 ~ f2!4", B: "eb2 ~ eb2 ~ eb2 ~ eb2!2 f2 ~ f2 ~ f2 ~ f2!2",
  C: "d2 ~ d2 ~ d2 ~ d2!2 g2 ~ g2 ~ g2 ~ g2!2", D: "f2 ~ f2 ~ f2 ~ f2!2 g2 ~ g2 ~ g2 ~ g2!2",
  E: "bb1 ~ bb1 ~ bb1 ~ bb1!3 ~ bb1 ~ bb1 ~ bb1!2", F: "g1 ~ g2 ~ g1 ~ g2 ~ g1 ~ g2 ~ g1 ~ g2!2",
  G: "bb1 ~ bb2 ~ bb1 ~ bb2 ~ bb1 ~ bb2 ~ bb1 ~ bb2!2", H: "db2 ~ db2 ~ db2 ~ db2!3 ~ db2 ~ db2 ~ db2!2",
  I: "ab1 ~ ab1 ~ ab1 ~ ab1!3 ~ ab1 ~ ab1 ~ ab1!2", J: "f2 ~ f2 ~ f2 ~ f2!3 ~ f2 ~ f2 ~ f2!2",
  K: "db2 ~ db2 ~ db2 ~ db2!3 ~ db2 ~ db2 ~ db2 ~", L: "ab1 ~ ab1 ~ ab1 ~ ab1 ~ ab1 ~ ab1 ~ ab1 ~ ab1!2",
  M: "bb1 ~ bb1 ~ bb1 ~ bb1!3 ~ bb1 ~ bb1 ~ bb1 ~", N: "bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1!2",
  O: "db2 ~ db2 ~ db2 ~ db2 ~ db2!3 ~ db2 ~ db2!2", P: "[ab1,bb1] ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1!2",
  Q: "f1 ~ f1 ~ f1 ~ f1!2 g2 ~ g2 ~ g2 ~ g2!2", R: "[bb1,eb2] ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1!2",
  S: "f2 ~ f2 ~ f2 ~ f2!3 ~ f2 ~ f2!3 ~", T: "ab1 ~ ab1 ~ ab1 ~ ab1!3 ~ ab1 ~ ab1!3 ~",
  U: "bb1 ~ bb1 ~ bb1 ~ bb1!3 ~ bb1 ~ bb1 g1 f1!2", V: "f1 ~ f1 ~ f1 ~ f1!2 f2 ~ g2 ~ g2 ~ g2!2", W: "bb1 ~@15",
})).s("gm_synth_bass_1").gain(0.51)

// drums · kick
const kick = s("bd").struct("<~@5 [x!4]!88 x ~@7>").gain(0.6)

// drums · clap
const clap = s("cp").struct("<~@5 A@8 ~@16 A@8 ~@16 A@8 ~@8 A@24 ~@8>".pickRestart({
  A: "~ x ~ x",
})).gain(0.3)

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

// drums · hihat
const hihat = s("hh").struct(`<
  ~@4 A B@8 C D C D@2 C D C D C D@2 C@2 D C D B@7 C D@3 C D C D C D C D C D C D B@13 D B D B@16 D B@7 E ~@7
>`.pickRestart({
  A: "~@3 x", B: "x ~ x ~ x ~ x!3 ~ x ~ x ~ x ~", C: "x ~ x ~ x ~ x ~ x ~ x ~ x ~ x!2", D: "x!8", E: "x",
})).gain(0.24)

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

// drums · bongos
const bongos = s("bongo:4").struct("<~@5 A@8 ~@16 A@8 B ~@15 A@8 C ~@7 A@3 D A@18 E A B ~@7>".pickRestart({
  A: "x ~@2 x!3 ~@2 x ~@2 x!3 ~@2", B: "x", C: "x ~@2 x ~@12", D: "x ~@2 x!2 ~@3 x ~@2 x!3 ~@2",
  E: "x ~@2 x!3 ~@2 x ~@2 x!4 ~",
})).gain(0.79)

// drums · bongos
const bongos_2 = s("bongo:18").struct("<~@5 A@8 ~@16 A@8 ~@16 A@8 ~@8 A@3 B A@18 C A ~@8>".pickRestart({
  A: "~@3 x ~@3 x", B: "~@7 x", C: "~@3 x ~@4",
})).gain(0.79)

// drums · congas
const congas = s("conga:13").struct("<~@5 A ~@7 A@11 B A@4 ~@8 A@16 ~@8 A@7 B C ~@31>".pickRestart({
  A: "x ~@2 x ~@12", B: "x ~@2 x ~@4 x ~@2 x ~@4", C: "~ x ~@14",
})).gain(0.96)

// drums · cabasa
const cabasa = s("cabasa:4").struct(`<
  ~@5 A ~ A ~ A ~ A ~@9 A ~@3 A ~@3 A ~ A ~ A ~ A ~ A ~@7 A ~@3 A ~@3 A ~ A ~ A ~ A ~ A ~@3 A ~@3 A ~ A ~ A ~ A ~ A ~ A
  ~ A ~ A ~ A ~ A ~ A ~ A ~@9
>`.pickRestart({
  A: "~@2 x!2 ~@12",
})).gain(1.52)

// drums · shaker
const shaker = s("sh").struct(`<
  ~@4 A B C B C D C D C B D@14 C E@3 F G F E F D@11 C D@3 C E F H E@2 F E F H D@4 ~@2 F E F E F E F E F E@3 F E F E F
  E@3 F E@3 F ~@8
>`.pickRestart({
  A: "x!5 ~ x!5 ~ x!4", B: "x ~@13 x!2", C: "~@12 x!4", D: "~@14 x!2", E: "~@6 x!2 ~@6 x!2", F: "~@6 x!2 ~@4 x!4",
  G: "x ~@5 x!2 ~@6 x!2", H: "~@6 x!2 ~@8",
})).gain(0.3)

stack(
  bass, string_ensemble_1, brass_section, electric_guitar_clean, string_ensemble_1_2, bass_2, kick, clap, snare, hihat,
  crash, bongos, bongos_2, congas, cabasa, shaker
)

More by Rick Astley