Strudelify

Some Kind of Wonderful

Grand Funk Railroad

KeyE♭ majorTempo144 bpm
0:00/0:00
// Some Kind of Wonderful — Grand Funk Railroad
// 144 bpm, 4/4, key D# major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: pitch bends are ignored
// note: Full arrangement: all 76 bars on a 16-step grid, each part at one level. Source detail keeps the original performance.
setcpm(144/4)

// Notation: c3@3 lasts 3 steps · ~ is a rest · [c3,e3] is a chord · "a, b" plays two voices at once.
// A part's distinct bars are riffs (A, B, C...) played in order: edit a riff to change every repeat.

// bass · electric bass finger
const bass = note(`<
  ~@2 A B A C A D A C E F E G A B A C H I E J A K A G A F A L A B A C A B A L E F E J A B A C H M E J A F A G A F A L A
  B A B A B A N A K E D A F E D O P
>`.pickRestart({
  A: "eb2@2 ~ eb2 eb2@2 ~ eb2 eb2@2 ~ eb2 eb2@2 ~ eb2", B: "eb2@2 ~ eb2 eb2@2 ~ eb2 db2@2 ~ db2 bb1@2 ~ bb1",
  C: "eb2@2 ~ eb2 eb2@2 ~ eb2 bb2@2 ~ eb2 eb3@2 ~ eb2", D: "eb2@2 ~ eb2 eb2@2 ~ eb2 eb2@2 ~ eb2 bb1@2 ~ bb1",
  E: "ab2@2 ~ ab2 ab2@2 ~ ab2 ab2@2 ~ ab2 ab2@2 ~ ab2", F: "ab2@2 ~ ab2 ab2@2 ~ ab2 gb2@2 ~ gb2 eb2@2 ~ eb2",
  G: "ab2@2 ~ ab2 ab2@2 ~ ab2 eb3@2 ~ ab2 gb3@2 ~ gb3", H: "bb1@2 ~ bb1 bb1@2 ~ bb1 bb1@2 ~ bb1 bb1@2 ~ bb1",
  I: "bb1@2 ~ bb1 bb1@2 ~ bb1 ab1@2 ~ ab1 f1@2 ~ f1", J: "ab2@2 ~ ab2 ab2@2 ~ ab2 eb3@2 ~ ab2 ab3@2 ~ ab2",
  K: "ab2@2 ~ ab2 ab2@2 ~ ab2 c3@2 ~ c3 db3@2 ~ eb3", L: "eb2@2 ~ eb2 eb2@2 ~ eb2 bb2@2 ~ eb2 eb3@2 ~ eb3",
  M: "bb1@2 ~ bb1 bb1@2 ~ bb1 d2@2 ~ d2 eb2@2 ~ f2", N: "eb2@2 ~ eb2 eb2@2 ~ eb2 g2@2 ~ g2 ab2@2 ~ bb2",
  O: "eb2@2 ~ bb1@2 b1@2 ~ c2@2 ~ db2@2 d2@2 ~", P: "eb2 ~@3 [eb2,eb3] ~@3",
})).s("gm_electric_bass_finger").gain(0.45)

// chords · distortion guitar
const distortion_guitar = note("<~@22 A B A B A B A@2 ~@20 A B A B A B A@2 ~@16 C D>".pickRestart({
  A: "~ [eb2,g3] ~ [eb2,g3]", B: "~ [ab2,ab3] ~ [ab2,ab3]", C: "eb3@2 ~ bb2@2 b2@2 ~ c3@2 ~ db3@2 d3@2 ~",
  D: "eb3 ~@3 [eb3,bb3] ~@3", // Eb5
})).s("gm_distortion_guitar").gain(0.2)

// chords · overdriven guitar
const overdriven_guitar = note(`<
  ~@2 A B A B C D C D E F E F A G C H I J K L A M A N A O P Q A G A G A G A G R M S N C H A B I J E T A M A N A M A G P
  Q P Q A G A G A O E Q A F E G U V
>`.pickRestart({
  A: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3]!2 ~@2 [eb2,bb2,eb3] [eb2,bb2,eb3]@2 ~ [eb2,bb2,eb3] [eb2,bb2,eb3]@2 ~ [eb2,bb2,eb3]", // Eb5
  B: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3] [eb2,bb2,eb3]@2 ~ [eb2,eb3]@3 ~ [eb2,eb3] [eb2,eb3]@2 ~ [eb2,eb3]", // Eb5 Eb
  C: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3] [eb2,bb2,eb3]@2 ~ [eb2,bb2,eb3]!2 ~@2 [eb2,bb2,eb3]!2 ~@2 [eb2,bb2,eb3]", // Eb5
  D: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3] [eb2,bb2,eb3]@2 ~ [eb2,bb2,eb3] [eb4,g4,bb4]@2 ~@2 [eb4,g4,bb4]@2 ~ [eb3,bb3,eb4]", // Eb5 Eb Eb5
  E: "[eb2,ab2] ~@2 [eb2,ab2] [eb2,ab2]@2 ~ [eb2,ab2] [eb2,ab2]@2 ~ [eb2,ab2] [eb2,ab2]@2 ~ [eb2,ab2]", // Ab5
  F: "[eb2,ab2] ~@2 [eb2,ab2] [eb2,ab2]@2 ~ [gb2,ab2]@3 ~ [gb2,ab2] [gb2,ab2]@2 ~ ab2", // Ab5 Gbsus2
  G: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3] [eb2,bb2,eb3]@2 ~ [eb2,db3,eb3]@3 ~ [eb2,db3,eb3] [eb2,db3,eb3]@2 ~ [eb2,eb3]", // Eb5 Eb7 Eb
  H: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3] [eb2,bb2,eb3]@2 ~ [eb2,bb2,eb3] [eb3,g3,bb3]@2 ~@2 [eb3,g3,bb3]@2 ~ [eb2,bb2,eb3]", // Eb5 Eb Eb5
  I: "[bb1,f2,bb2] ~@2 [bb1,f2,bb2]!2 ~@2 [bb1,f2,bb2] [bb1,f2,bb2]@2 ~ [bb1,f2,bb2] [bb1,f2,bb2]@2 ~ [bb1,f2,bb2]", // Bb5
  J: "[bb1,f2,bb2] ~@2 [bb1,f2,bb2] [bb1,f2,bb2]@2 ~ [bb1,ab2,bb2]@3 ~ [bb1,ab2,bb2] [bb1,ab2,bb2]@2 ~ [bb1,bb2]", // Bb5 Bb7 Bb
  K: "[ab1,eb2,ab2] ~@2 [ab1,eb2,ab2]!2 ~@2 [ab1,eb2,ab2] [ab1,eb2,ab2]@2 ~ [ab1,eb2,ab2] [ab1,eb2,ab2]@2 ~ [ab1,eb2,ab2]", // Ab5
  L: "[ab1,eb2,ab2] ~@2 [ab1,eb2,ab2] [ab1,eb2,ab2]@2 ~ [ab1,gb2,ab2]@3 ~ [ab1,gb2,ab2] [ab1,gb2,ab2]@2 ~ [ab1,ab2]", // Ab5 Ab7 Ab
  M: "[eb2,ab2] ~@2 [eb2,ab2]!2 ~@2 [eb2,ab2] [c2,gb2,c3] ~@2 [c2,gb2,c3] [db2,ab2,db3]@2 ~ [eb2,eb3]", // Ab5 Cdim Db5 Eb
  N: "[eb2,ab2] ~@2 [eb2,ab2] [eb2,ab2]@2 ~ [eb2,ab2] [gb2,c3,eb3]@2 ~@2 [gb2,c3,eb3]@2 ~ [eb2,ab2]", // Ab5 Cdim Ab5
  O: "[eb2,ab2] ~@2 [eb2,ab2] [eb2,ab2]@2 ~ [eb2,ab2] [gb3,c4,eb4]@2 ~@2 [gb3,c4,eb4]@2 ~ [ab2,eb3,ab3]", // Ab5 Cdim Ab5
  P: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3]!2 ~@2 [eb2,bb2,eb3]!2 ~@2 [eb2,bb2,eb3]!2 ~@2 [eb2,bb2,eb3]", // Eb5
  Q: "[eb2,bb2,eb3] ~@2 [eb2,bb2,eb3]!2 ~@2 [eb2,bb2,eb3] [g2,eb3,g3] ~@2 [g2,eb3,g3] [ab2,eb3,ab3]@2 ~ [bb2,bb3]", // Eb5 Cm Ab5 Bb
  R: "[eb2,ab2] ~@2 [eb2,ab2]!2 ~@2 [eb2,ab2]!2 ~@2 [eb2,ab2]!2 ~@2 [eb2,ab2]", // Ab5
  S: "[eb2,ab2] ~@2 [eb2,ab2] [eb2,ab2]@2 ~ [eb2,ab2]!2 ~@2 [eb2,ab2]!2 ~@2 [eb2,ab2]", // Ab5
  T: "[eb2,ab2] ~@2 [eb2,ab2] [eb2,ab2]@2 ~ ab2@3 ~ ab2 ab2@2 ~ ab2", U: "eb4@2 ~ bb3@2 b3@2 ~ c4@2 ~ db4@2 d4@2 ~",
  V: "eb4 ~@3 [eb4,g4,bb4] ~@3", // Eb
})).s("gm_overdriven_guitar").gain(0.24)

// chords · overdriven guitar
const overdriven_guitar_2 = note("<~@22 A B C B D E F G ~@20 C H I H J H K L ~@18>".pickRestart({
  A: "[g4,bb4]@8 g4 bb4 ~ g4 bb4 g4@2 bb4", B: "[ab4,c5,f5]@6 ~@2 [c5,f5,ab5]@2 ~@2 [eb5,ab5,bb5]@2 ~ [c5,f5,ab5]",
  C: "~@3 bb3 [g4,bb4]@2 ~ [g4,bb4] ~@3 bb3 [g4,bb4]@2 ~ [g4,bb4]", // Gm
  D: "eb5 ~@2 bb3 [bb4,eb5,g5]@2 ~ [bb3,g4] [eb4,bb4]@2 ~ [bb3,g4] [eb4,bb4]@3 [bb3,g4]", // Eb Eb5 Eb Eb5 Eb
  E: "[ab4,eb5]@2 ~ [g4,eb5]@3 ~ [ab4,eb5]@4 [c5,eb5]@3 ~@2", // Ab5 Cm Ab5 Cm
  F: "eb2@2 ~ [g4,bb4] bb3@2 ~ [g4,bb4] [eb2,g4,bb4,eb5]@2 ~@2 [bb3,g4,bb4,eb5]@2 ~ [eb4,g4,bb4]", // Gm Eb
  G: "eb2 ~@2 bb3 [gb4,bb4] g4 ~ [g4,bb4]@9", // Gb Gm
  H: "gb5 ~@2 eb4 [c5,gb5,ab5]@2 ~ [eb4,ab4] [gb4,c5]@2 ~ [eb4,ab4] [gb4,c5]@3 [eb4,ab4]", // Ab7 Ab5 Gbdim Ab5 Gbdim Ab5
  I: "~@3 bb3 [g4,bb4]@3 bb3 gb5 g5 ~ bb5 gb5 g5 ~ bb5, ~@8 bb4@3 ~ bb4@3 ~", // Gm
  J: "~@3 bb3 [bb4,eb5,g5]@2 ~ [bb4,eb5,g5] ~@3 bb3 [bb4,eb5,g5]@2 ~ [bb4,eb5,g5]", // Eb
  K: "~@3 bb3 [g4,bb4]@2 ~ bb3 [eb5,bb5] [bb4,g5] ~ [eb5,bb5] [bb4,g5] [eb5,bb5] ~ [bb4,g5]", L: "[g4,bb4,d5]",
})).s("gm_overdriven_guitar").gain(0.24)

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

// drums · rim
const rim = s("rim").struct("<[x!2] [x!4] ~@74>").gain(0.42)

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

// drums · low tom
const low_tom = s("lt").struct("<~@16 A B ~@3 B ~@7 C ~@19 B ~@25 D>".pickRestart({
  A: "~@15 x", B: "~@13 x ~ x", C: "~@4 x ~@6 x ~@3 x", D: "~@3 x ~ x ~@2 x ~@7",
})).gain(0.54)

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

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

// drums · open hat
const open_hat = s("oh").struct(`<
  ~@12 A B ~@2 A ~@4 A ~ C ~@4 A ~@8 B ~@2 A ~@3 A ~@3 A ~@11 A ~@3 A ~@4 B ~@2 A ~@3
>`.pickRestart({
  A: "~@3 x ~@12", B: "~@11 x ~@4", C: "~@15 x",
})).gain(0.36)

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

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

// drums · ride
const ride = s("rd").struct("<~@2 A B@15 A B@3 C D@7 A B@15 A B E B D@8 A B@7 A B@7 F G>".pickRestart({
  A: "~ x!3", B: "x!4", C: "~ x", D: "x!2", E: "x ~ x!2", F: "~@3 x ~ x ~@5 x ~ x ~@2", G: "~@3 x ~ x ~@10",
})).gain(0.54)

stack(
  bass, distortion_guitar, overdriven_guitar, overdriven_guitar_2, kick, rim, snare, low_tom, hihat, mid_tom, open_hat,
  high_tom, crash, ride
)

More by Grand Funk Railroad