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, A@4 for four bars: 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 A C A D E F G H@3 G I@2 J K L M N K L M O A C A C P@2 E F G I@2 Q G I@2 J R@2 S T K L S U A C E C V@2 E W K L
  S T K X S N E C A C V@2 E F A C A C A C E Y A C E C A B E Z@2 ~@7
>`.pickRestart({
  A: "[eb3,g3,bb3]@5 ~ [f3,a3,c4]@8 ~@2", B: "[f3,a3,d4]@5 ~ [g3,bb3,d4]@9 ~", C: "[f3,a3,d4]@5 ~ [g3,bb3,d4]@8 ~@2",
  D: "[f3,a3,c4]@5 ~ [g3,bb3,d4]@8 ~@2", E: "[g3,bb3,eb4]@5 ~ [f3,a3,c4]@9 ~", F: "[f3,bb3,d4]@13 ~@3",
  G: "[d3,f3,bb3]@15 ~", H: "[[f3,a3]@15 [d3,g3,bb3]@8 ~, c3@7 ~@5]/3", I: "[[c3,f3,a3]@31 ~]/2",
  J: "[d3,g3,bb3]@13 ~@3", K: "[f3,a3,d4]@15 ~", L: "[f3,ab3,db4]@15 ~", M: "[eb3,ab3,c4]@7 ~",
  N: "bb3@4 a3@3 ~, c4@15 ~, f4@13 ~@3", O: "bb3@6 ~@2 a3@5 ~@3, [c4,f4]@3 ~",
  P: "[[eb3,g3,bb3]@5 ~ [f3,a3,c4]@15 ~ [g3,d4]@9 ~, ~@22 bb3@7 ~@3]/2", Q: "[d3,g3], bb3@7 ~",
  R: "[[a3,d4]@16 [ab3,db4]@15 ~, f3@31 ~]/2", S: "[eb3,ab3,c4]@15 ~", T: "bb3@8 a3@7 ~, [f3,c4]@15 ~",
  U: "bb3@7 ~ a3@5 ~@3, [c4,f4]@13 ~@3", V: "[[eb3,g3,bb3]@5 ~ [f3,a3,c4]@15 ~ [g3,bb3,d4]@9 ~]/2",
  W: "[f3,bb3,d4]@3 ~", X: "f3 ~ f3@12 ~@2, [ab3,db4]@15 ~", Y: "[f3,bb3,d4]@7 ~", Z: "[[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 C B S T C U@2 ~@6 V W X ~ Y Z AA AB AC AD AE AF R C AG AH AI
  AJ@2 AK AL AM AN AO AP AQ B C AG C AR E AS A R C D G AT AU AV C D G AW AU AX AY AZ@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]@9 ~, bb3 ~@3", 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 g3@2 bb3 ~ [f3,a3]@10, eb4 ~@3", T: "~ f3 a3 [g3,bb3]@4 ~, c4 ~@3",
  U: "[~@2 eb3@2 ~@2 d3@3 ~@5 bb3@13 ~@5, bb3@12 f3@5 ~@15, ~@10 bb2@11 ~@11]/2", V: "~@6 bb3 c4, ~ bb2, ~@5 f3@3",
  W: "~@3 d3@4 ~, d4@15 ~, ~ f3@7, ~ a3@3", X: "~@3 db4@5, db3@13 ~@3, ~ f3@6 ~, ~@4 ab3@11 ~",
  Y: "~@7 c3, ~ c3@5 ~@2, ~@2 f3@3 ~ [f3,g3]@2, ~@3 g3@2 a3@2 ~, ~@4 c4@3 ~", Z: "~@4 a3@11 ~, d4@15 ~, ~@2 f3@13 ~",
  AA: "~@4 db4@9 ~@3, bb2@7 ~, ~@2 [f3,ab3]@13 ~", AB: "~@10 bb3@5 ~, ~ eb3@6 ~, ~@6 ab3@7 ~@3",
  AC: "~@4 bb3@2 c4 ~@5 f3@4, ~ f3@4 g3@3, ~ a3", AD: "~ eb3 g3 [f3,a3]@4 ~, bb3@5 ~@11",
  AE: "~@2 f3@2 a3 ~ [g3,bb3]@8 ~@2, d4@7 ~", AF: "~ eb3 g3 [f3,a3]@4 ~", AG: "~@2 f3@2 a3@2 [g3,bb3]@9 ~, c4@5 ~@11",
  AH: "~@2 eb3@2 g3 ~ [f3,a3]@10, bb3 ~@3", AI: "f4 ~@2 [bb3,d4] ~ bb3 f3@2, ~ f3@4 ~@3, ~@4 c4@3 ~",
  AJ: "[~ a3@3 ~@4, d4 ~, ~@2 f3@23 ~@7]/2", AK: "~ bb3 ~@2, eb3@13 ~@3, ~@2 ab3@11 ~@3",
  AL: "~@3 g3 ~@3 f3, ~ c3@6 ~, ~ f3@2 g3, ~ c4, ~@5 a3@3", AM: "~ d4, ~ f3@3, ~@3 a3@5",
  AN: "~@8 db4@7 ~, ~@4 f3@11 ~, ~@6 ab3@9 ~", AO: "~@8 c4@7 ~, ~@2 eb3@5 ~, ~@3 ab3@4 ~",
  AP: "~@6 g3 f3, ~@3 f3@2 a3@2 ~, ~@8 c4@7 ~", AQ: "~ eb3 g3 [f3,a3]@4 ~, bb3@3 ~@5",
  AR: "~ f3 a3 g3@5, d4@7 ~, ~@6 bb3@7 ~@3", AS: "~@10 d4@3 ~@3, d4@3 c4@3 ~@2, ~@2 f3@11 ~@3, ~@4 bb3@9 ~@3",
  AT: "~@2 f3@2 a3 ~ [g3,bb3,d4]@10, c4@5 ~@11", AU: "~@2 g3@2 bb3 ~ [f3,a3,c4]@10, eb4 ~@3",
  AV: "~@4 c4 ~ c4 ~, d4@4 ~ d4@2 ~, ~ f3@6 ~, ~@3 bb3@2 ~@3", AW: "~@2 f3@2 a3 ~ [g3,bb3,d4]@10, d4@5 ~@11",
  AX: "~@2 f3@2 ~@2 [f3,g3] ~@3 g3@6, c4 ~ [bb3,d4]@2", AY: "~@2 g3@2 bb3 ~ [f3,a3,c4]@9 ~, eb4 ~@3",
  AZ: "[~@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 A N O P Q R S T ~@3 U ~@4 I J K L I J K L A V W P X R Y T I J K L Z AA AB L X
  N W P X R S T X N W P X R S T X N W P X R S AC ~@8
>`.pickRestart({
  A: "g4@2 eb4 ~ d5 ~ c5@2 ~@2 a4 ~ 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", // G Eb D C A G F
  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 ~ bb4 ~ c5 ~ f5 ~@7", M: "~@2 f4 ~ bb4 ~ f5 ~@9",
  N: "~@2 d4 ~ c5 ~ bb4 ~@7 f4@2", O: "g4@2 eb4 ~ d5 ~ c5@2 ~@2 a4 ~ g4 ~ a4 g4", P: "f4 ~@13 f4@2",
  Q: "g4 ~ eb4 ~ d5 ~ c5@2 ~@2 a4 ~ g4 ~ f4 ~", R: "~@2 g4 ~ a4 ~ bb4 ~@3 bb4 ~ c5 ~ d5 ~",
  S: "eb5 ~ d5 ~ c5 ~ a4 ~@3 bb4 ~ c5 ~ c5 ~", T: "~@2 bb4 ~@13", U: "~@6 a4@2 bb4 ~ f5 ~@5",
  V: "~@2 d4 ~ c5 ~ bb4 ~@7 f4 ~", W: "g4 ~ eb4 ~ d5 ~ c5 ~@3 a4 ~ g4 ~ a4 g4",
  X: "g4 ~ eb4 ~ d5 ~ c5 ~@3 a4 ~ g4 ~ f4 ~", Y: "eb5 ~ d5 ~ c5 ~ a4 ~@3 bb4 ~ c5 ~ c5@2", Z: "[a4,a5] ~@15",
  AA: "[ab4,ab5] ~@15", AB: "[g4,g5] ~@15", AC: "~@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