Strudelify

Hurts So Good

John Mellencamp

KeyA majorTempo128 bpm
0:00/0:00
// Hurts So Good — John Mellencamp
// 128 bpm, 4/4, key A major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: Tempo changes preserved in elapsed time; displayed bars use the dominant tempo.
// note: pitch bends are ignored
// note: Full arrangement: all 113 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
// note: Guitar parts that double another keep only their own notes (fills, solos): od guitar 1.
setcpm(128/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(`<
  ~@6 A B@4 C@2 D E F G H I F J H K F L F J M N O P F I F Q R S T U V D I F G H I F J H K F W F X Y N O K Z AA F Q H AB
  AC K H K Y AD H I AE N AF@2 AG@2 AH AI AJ AI I AK AL F AM H F AL I F I F AM H S AN AO AN D AN AO AN AP AN AO AN AQ ~@4
>`.pickRestart({
  A: "a1@4 ~@2 a1 ~@2 a1@5 ~@2", B: "[a1@4 ~@2 a1 ~ a1@2 e1@2 f#1@2 a1@6 ~@2 a1 ~ a1@6 ~@2]/2",
  C: "[a1@5 ~ a1 ~ a1@2 e1@2 f#1@2 a1@7 ~ a1 ~ a1@6 ~@2]/2", D: "a1@5 ~ a1 ~ a1@2 e1@2 f#1@2 a1 ~",
  E: "~ a1@5 a1 ~ a1@5 ~ a1@2", F: "e2@5 ~ e2 ~ e2@5 ~ e2@2", G: "f#1@5 ~ f#1 ~ f#1@5 ~ f#1@2",
  H: "d2@5 ~ d2 ~ d2@5 ~ d2@2", I: "a1@5 ~ a1 ~ a1@5 ~ a1@2", J: "f#1@5 ~ f#1 ~ f#1@4 ~@2 f#1@2",
  K: "a1@4 ~@2 a1 ~ a1@5 ~ a1@2", L: "a1@5 ~ a1 ~ a1@4 ~@2 a1@2", M: "d2@4 ~@2 d2 ~ d2@5 ~ d2 ~",
  N: "e2@5 ~ e2 ~ e2@5 ~ e2 ~", O: "e2 ~ e2 ~ e2 ~ e2 ~ e2 ~ e2 ~ e2 ~ e2 ~", P: "a1@4 ~@2 a1 ~ a1@8", Q: "d2@3 f#2@5",
  R: "d2@4 ~@2 d2 ~ d2@4 ~@2 d2@2", S: "e2@5 ~ e2 ~ e2@7 ~", T: "a1@4 ~@2 a1 ~ a1@6 ~@2",
  U: "a1 a1@4 ~ a1 ~ a1@2 e1@2 f#1@2 a1@2", V: "~ a1@4 ~ a1 ~ a1@6 ~@2", W: "a1@4 ~@2 a1 ~ a1@4 ~@2 a1@2",
  X: "f#1@4 ~@2 f#1 ~ f#1@4 ~@2 f#1@2", Y: "d2@5 ~ d2 ~ d2@5 ~ d2 ~", Z: "e2@4 ~@2 e2 ~ e2@5 ~ e2@2", AA: "a1@7 ~ a1@8",
  AB: "e2@6 e2 ~ e2@8", AC: "a1 a1@5 a1 ~ a1@8", AD: "f#2@5 ~ f#2@2 a1@5 ~ a1@2", AE: "e2@5 ~ e2 ~ e2@6 e2 ~",
  AF: "[e2@3 ~ e2 ~@9 e2@5 ~ e2 ~@9 e2 ~]/2", AG: "[e2@4 e2 ~@9 e2@5 ~ e2 ~@9 e2 ~]/2", AH: "e2@3 ~ e2 ~@9 e2@2",
  AI: "~@2 e2 ~ e2 ~ e2 ~ e2 ~ e2 ~ e2 ~ e2 ~", AJ: "e2@4 e2 ~@9 e2@2", AK: "e2@4 ~@2 e2@2 e2 e2@5 e2 ~",
  AL: "a1@5 ~ a1 ~ a1@5 ~ a1 ~", AM: "d2@5 ~ f#2@7 ~ f#2@2", AN: "a1@5 ~ a1 ~ a1@6 ~@2",
  AO: "a1@4 ~@2 a1 ~ a1@2 e1@2 f#1@2 a1 ~", AP: "a1@5 ~@2 a1 a1@2 e1@2 f#1@2 a1 ~",
  AQ: "a1@5 ~ a1 ~ a1@2 e1 ~ f#1@2 g1 ~",
})).s("gm_fretless_bass").gain(0.59)

// other · electric guitar clean · "cl guitar"
const electric_guitar_clean = note("<~@7 A@8 ~@23 A@4 ~@56 A@6 ~@9>".pickRestart({
  A: "[~@5 e2 f#2 a2@3 ~@6]/2",
})).s("gm_electric_guitar_clean").gain(0.4)

// other · electric guitar clean · "cl guitar" · soft notes
const electric_guitar_clean_2 = note("<~@106 A@4 ~@3>".pickRestart({
  A: "[~@5 e2 f#2 a2@3 ~@6]/2",
})).s("gm_electric_guitar_clean").gain(0.13)

// chords · overdriven guitar · "od guitar 2"
const overdriven_guitar = note(`<
  ~ A@2 B@2 C ~@17 D@2 E F G H I J K L M N O P ~@13 D@2 E F G H I J K L M N O P ~ Q R S T@2 U@2 V@2 W@2 X@2 Y@2 Z@2 J K
  L M N O P ~ J K L M N O AA ~@7 AB ~@8
>`.pickRestart({
  A: "[~@12 [a3,c#4,e4,a4]@2 [a3,c#4,e4,a4]@13 ~ [e3,g#3,b3,e4]@2 [e3,g#3,b3,e4]@2]/2", // A E
  B: "[~@6 [a3,c#4,e4,a4] [a3,c#4,e4,a4]@7 ~ [d3,f#3,a3,d4]]/2", // A D
  C: "[e3,g#3,b3,e4]!3 ~ [e3,g#3,b3,e4]@2 ~@2 [e2,b2] ~ [e3,g#3,b3,e4]@6", // E E5 E
  D: "[[e3,b3,e4] ~@13 [a2,e3,a3]@5 ~ [a2,e3,a3] ~@5 a3 ~@3 a2@2, ~@6 [a2,e3] ~]/2", // E5 A5
  E: "[e2,b2,e3]@4 [e3,b3,e4]@3 ~ [e3,b3]@4 [e3,a3,c#4]@3 ~", F: "f#3@3 ~ [f#2,c#3,f#3] ~@5 [f#2,c#3,f#3] ~@3 c#3 ~",
  G: "d3@3 ~ [d3,a3,d4] ~@5 [d3,a3,d4]@2 ~@2 [d3,a3,d4] ~", H: "[b3,e4], e3 ~@15",
  I: "[e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~", // E5
  J: "[e3,a3]@3 ~ [e3,a3,c#4] ~@5 [e3,a3,c#4]@4 ~@2", // A5 A
  K: "e3@3 ~ [e3,b3,e4] ~@3 [e3,b3] ~ [e3,b3] ~ [e3,b3,e4] ~ [a2,e3,a3] ~", // E5 A5
  L: "[a2,e3,a3]@3 ~ [a2,e3,a3] ~@5 [a2,e3,a3]@5 ~", // A5
  M: "[e3,b3,e4]@3 ~ [e3,b3,c#4,e4] ~@3 [e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,c#4,e4] ~@3", // E5 C#m7 E5 C#m7
  N: "d3@2 [a3,d4]@3 ~ [f#3,a3,c#4]@5 ~ [f#3,a3,c#4]@2 ~@2", // D5 F#m
  O: "[d3,a3,d4]@5 ~ [d3,a3,d4]@3 ~ [d3,a3,d4] ~ [d3,a3,d4] ~@3", P: "e3@4 [b3,e4] ~@5 [b3,e4]@6, ~ e3",
  Q: "~@10 [e3,a3]@2 [e3,a3] ~ [e3,a3]@2", R: "[d3,a3,d4]@3 ~ [d3,a3,d4] ~@9 [a2,e3,a3]@2",
  S: "~@2 [a2,e3,a3] ~ [a2,e3,f#3] ~@3 [a2,e3,a3] ~ [a2,e3,a3] ~ [a2,e3,f#3] ~ [a2,e3] ~", // A5 F#m7 A5 F#m7 A5
  T: "[[d3,a3,d4]@3 ~ [d3,a3,d4] ~@5 [d3,a3,d4] ~@3 [c#3,f#3,c#4]@7 ~ [e3,a3]@4 a2@2 [e3,a3]@2 [a2,e3,a3] ~, ~@22 a2@3 ~@7]/2", // D5 F#5 A5
  U: "[[d3,a3,d4]@3 ~ [d3,a3,d4] ~@5 [d3,a3,d4] ~@3 [e3,a3]@5 ~ [e3,f#3] ~@3 [e3,a3] ~ [e3,a3]@2 f#3@2 e3 ~, ~@14 a2@6 ~@4 a2@7 ~]/2", // D5 A5 Esus2 A5
  V: "[[b2,e3,b3]@3 ~ [c#3,e3,b3] ~@9 [b2,b3]@4 [e3,b3] ~ [c#3,e3,b3] ~@3 [d3,e3,b3] ~ [c#3,e3,b3] ~@3 [b2,e3,b3]@2, ~@14 e3@3 ~@15]/2", // E5 C#m7 B E5 C#m7 E7 C#m7 E5
  W: "[[b2,e3,b3]@3 ~ [c#3,e3,b3] ~@9 [e3,b3]@3 ~ [e3,b3] ~ [c#3,e3,b3] ~@3 [d3,e3,b3] ~ [c#3,e3,b3] ~@3 [b2,e3,b3] ~, ~@7 b2@2 ~@7]/2", // E5 C#m7 E5 C#m7 E7 C#m7 E5
  X: "[[b2,e3,b3]@3 ~ [c#3,e3,b3] ~@9 [e3,b3]@3 ~ [e3,b3] ~ [c#3,e3,b3] ~@3 [d3,e3,b3]@2 [c#3,e3,b3] ~@3 [b2,e3,b3] ~, ~@7 b2@2 ~@7]/2", // E5 C#m7 E5 C#m7 E7 C#m7 E5
  Y: "[[b2,e3,b3]@3 ~ [c#3,e3,b3] ~@9 [e3,b3]@3 ~ [e3,b3] ~ [c#3,e3,b3] ~@3 [d3,e3,b3]@2 [c#3,e3,b3] ~@3 [b2,e3,b3] ~, ~@7 b2@3 ~@6]/2", // E5 C#m7 E5 C#m7 E7 C#m7 E5
  Z: "[[b2,e3,b3]@3 ~ [c#3,e3,b3] ~@9 [e3,b3]@3 ~ [e3,b3] ~ [c#3,e3,b3] ~@3 [d3,e3,b3,e4]@2 [c#3,e3,b3,e4] ~ [e3,b3,e4] ~ [e3,b3,e4] ~, ~@7 b2@3 ~@6]/2", // E5 C#m7 E5 C#m7 E7 C#m7 E5
  AA: "[e3,b3,e4] ~@7", AB: "~@10 [e3,a3,e4] ~@3 [e3,a3,e4] ~",
})).s("gm_overdriven_guitar").gain(0.45)

// chords · rock organ · "hmd organ"
const rock_organ = note("<~@65 A@5 B@2 C@4 ~@6 D E D E F G H D@2 E D E F G ~@4 I@8 ~@5>".pickRestart({
  A: "[~@16 a5@14 [c#5,e5]@16 d5@15 ~@9 e5@10, ~@14 a4@16 a4 ~@31 c#5@18, ~@15 [d5,f#5]@16 ~@15 f#5@24 ~@10]/5", // C#m D
  B: "[[a4,d5,f#5,a5]@7 [a4,c#5,e5]@9]/2", C: "[g#4,b4,e5]/4", D: "[a4,c#5,e5]", E: "[b4,e5,g#5]",
  F: "[a4,d5,f#5]@3 [a4,c#5,f#5]@5", G: "[a4,d5,f#5]", H: "[g#4,b4,e5]",
  I: "[~@5 e4 f#4 a4@14 e4 f#4 a4@30 ~@11, ~@7 [c#5,e5]@57]/8", // C#m
})).s("gm_rock_organ").gain(0.35)

// chords · rock organ · "hmd organ" · soft notes
const rock_organ_soft = note("<~@106 A@2 B@5>".pickRestart({
  A: "[~@5 e4 f#4 a4@9]/2", B: "[a4@5 e4 f#4 a4@14 ~@19, [c#5,e5]]/5",
})).s("gm_rock_organ").gain(0.05)

// chords · acoustic guitar steel · "st guitar 1"
const acoustic_guitar_steel = note("<~@77 A@4 B ~@31>".pickRestart({
  A: "[~@10 [b3,e4] ~ [e3,g#3,b3,e4] ~ [b2,e3]@27 ~@3 [e3,g#3] ~ [e3,g#3]@16 [e3,g#3,b3]@2]/4", // E5 E E5 E
  B: "~@2 [e3,g#3,b3] ~ [e3,g#3,b3] ~@11", // E
})).s("gm_acoustic_guitar_steel").gain(0.54).pan(0.3)

// chords · acoustic guitar steel · "st guitar 2"
const acoustic_guitar_steel_2 = note(`<
  ~ A@2 B@2 C D E F G F G F G ~@23 D G F G ~@23 H G ~@23 I ~@7 H G F G F G F G ~@8
>`.pickRestart({
  A: "[~@12 [a3,c#4,e4,a4]@2 [a3,c#4,e4,a4]@13 ~ [e3,g#3,b3,e4]@2 [e3,g#3,b3,e4]@2]/2", // A E
  B: "[~@6 [a3,c#4,e4,a4] [a3,c#4,e4,a4]@7 ~ [d3,f#3,a3,d4]]/2", // A D
  C: "[e3,g#3,b3,e4]!3 ~ [e3,g#3,b3,e4]@2 ~@2 [e2,b2] ~ [e3,g#3,b3,e4]@6", // E E5 E
  D: "a3@2 [a3,d4]!3 [a3,c#4] ~@2, [a2,e3]@3 ~@5", E: "[f#3,a3]@6 [e3,a3]@9 ~", F: "~@2 [a3,d4]!3 [a3,c#4] ~@2",
  G: "[f#3,a3]@3 [e3,a3]@5", H: "a3@2 [a3,d4]!3 [a3,c#4] ~@2, [a2,e3] ~",
  I: "a3@2 [a3,d4]!3 [a3,c#4] f#3 e3, [a2,e3]@3 ~@5", // D5 A A5
})).s("gm_acoustic_guitar_steel").gain(0.4).pan(0.7)

// chords · acoustic guitar steel · "st guitar 2" · soft notes · D5 A F#m A5 D5 A F#m A5
const acoustic_guitar_steel_3 = note(`<
  ~@105
  [~@2 [a3,d4]!3 [a3,c#4] ~@2]
  [[f#3,a3]@3 [e3,a3]@5]
  [~@2 [a3,d4]!3 [a3,c#4] ~@2]
  [[f#3,a3]@3 [e3,a3]@5]
  ~@4
>`).s("gm_acoustic_guitar_steel").gain(0.2).pan(0.7)

// drums · kick
const kick = s("bd").struct(`<
  A@2 B A@2 B A B A B A@3 B A@9 C A@4 D E B A@2 B E A B A@3 F A@9 C A@4 D E B A@2 B E A B A G B A@2 D A B@2 A B F B A B
  A B H B A@2 B E A B A B A@2 B E A B A@3 F A@3 F A B A@2 ~@4
>`.pickRestart({
  A: "x ~@3 x ~@2 x", B: "x!2", C: "x ~@3 x!2 ~ x", D: "x ~@2 x!2 ~@2 x", E: "x!2 ~ x!2 ~@3", F: "x ~ x!2",
  G: "x ~@2 x!2 ~@3", H: "x ~@2 x!2 ~ x ~",
})).gain(0.4)

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

// drums · clap
const clap = s("cp").struct(`<
  ~@30 A@7 B C B C ~@16 A@7 B C ~@10 B@5 ~ A@7 C A@7 B C B C B C B D B C B C ~@4
>`.pickRestart({
  A: "~@2 x!2 ~@2 x ~", B: "~ x ~ x", C: "~@2 x ~@3 x!2", D: "~@2 x ~@2 x ~ x",
})).gain(0.4)

// drums · low tom
const low_tom = s("lt").struct("<~@5 A ~@3 A ~@3 A ~@15 B ~@26 B ~@8 C ~@13 A ~ A ~@7 D ~@18 D ~@4>".pickRestart({
  A: "~@7 x", B: "~ x!7", C: "~@4 x!4", D: "~@3 x ~@4",
})).gain(0.36)

// drums · hihat
const hihat = s("hh").struct("<A@4 B A ~@8 C A@14 D ~@11 C A@14 D ~@56>".pickRestart({
  A: "x!8", B: "x!7 ~", C: "~ x!7", D: "x!2 ~ x ~ x!3",
})).gain(0.32)

// drums · mid tom
const mid_tom = s("mt").struct("<~@5 A ~@3 A ~@3 A ~@65 A ~ A ~@7 B ~@18 B ~@4>".pickRestart({
  A: "~@3 x", B: "~ x ~@2",
})).gain(0.36)

// drums · open hat
const open_hat = s("oh").struct("<~@4 A ~@6 A ~@63 B ~@28 B ~@8>".pickRestart({
  A: "~@7 x", B: "~@5 x ~ x",
})).gain(0.32)

// drums · high tom
const high_tom = s("ht").struct("<~@5 A ~@3 A ~@3 A ~@65 A ~ B ~@31>".pickRestart({
  A: "~@5 x ~@2", B: "~@4 x!2 ~@2",
})).gain(0.36)

// drums · crash
const crash = s("cr").struct(`<
  ~@6 A ~@3 A ~@12 B ~@6 A ~@3 C ~@2 A ~@12 B ~@6 A ~@3 C ~@2 A ~ A ~ B C ~@10 A ~ A ~@3 C ~@3 A ~@3 C ~@2 A ~@3 A ~@3 A
  ~@7
>`.pickRestart({
  A: "x", B: "~@7 x", C: "~@3 x ~@4",
})).gain(0.36)

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

// drums · rim
const rim = s("rim").struct("<~@76 [~ x ~ x]!5 ~@32>").gain(0.32)

stack(
  bass, electric_guitar_clean, electric_guitar_clean_2, overdriven_guitar, rock_organ, rock_organ_soft,
  acoustic_guitar_steel, acoustic_guitar_steel_2, acoustic_guitar_steel_3, kick, snare, clap, low_tom, hihat, mid_tom,
  open_hat, high_tom, crash, ride, rim
)

More by John Mellencamp