Strudelify

thunderstruck

ACDC

KeyB majorTempo512 bpm
0:00/0:00
// thunderstruck — ACDC
// 512 bpm, 4/4, key B major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: Tempo changes preserved in elapsed time; displayed bars use the dominant tempo.
// note: metre changes (1/4 at bar 1, 4/4 at bar 1, 6/4 at bar 626) are rendered on a constant 4/4 grid of one bar per cycle
// note: ch 4 "Violin Solo" named as a string part, played on violin (its overdriven guitar patch is not one)
// note: Transcription provider: pdmx. https://musescore.com/score/5927237; license: https://creativecommons.org/publicdomain/zero/1.0/
// note: Full arrangement: all 628 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(512/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.

// other · flute
const flute = note(`<
  ~@35 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D F@2 A B C D E D F@2 A
  B C D E D F@2 A B C D E D F@2 A B C D E D F@2 A B C D E D F@2 A B C D E D F@2 ~@6 F@2 ~@6 F@2 ~@6 F@2 ~@4 A G@2 ~ A H
  I H J@4 ~@2 F@2 ~@14 F@2 ~@14 F@2 K L@2 ~ K M@2 ~ N@2 O ~@3 F@2 P@2 Q ~@5 R@2 S ~@13 T@2 S ~@9 U@2 ~@2 V@2 S ~@13 W@2
  X@2 Y@2 Z@2 W@2 AA@3 E ~@18 W@2 E ~@2 A AB@2 AC@2 AD@4 ~@2 W@2 E ~@5 AE@2 S ~ S ~@7 A I AF@2 E ~@4 I AG@4 ~@2 A I AH
  AI E ~@4 AJ@2 ~@3 AK@2 ~@4 AL@2 G@2 ~@2 AM@2 AN@2 S ~@11 AO@2 P@2 AP ~@17 A I AF@2 AQ@2 ~@3 AR AS@4 ~@34 A B C D E D
  ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D AT S ~@4 AU@2 AV@2 ~@4 AL@2 G@2 ~@2 C@2 AN@2 AV@2 ~@4 AL@2 G@2 ~@2 C@4
  Q ~ AW AX@2 ~@3 Q ~ AW AX@2 ~@3 Q ~ AW AX@2 ~@3 Q ~ AW AY@5 AV@2 ~@4 AL@2 G@2 ~@2 E@2 AZ@2 AV@2 ~@4 AL@2 G@2 ~@2 C@4
  BA@3 BB BC@3 ~@11 BD
>`.pickRestart({
  A: "~ b4", B: "d5 b4", C: "d5@15 ~", D: "e5 d5", E: "f#5@15 ~", F: "b5 ~", G: "[b4@8 d#5@23 ~]/2", H: "b4 d#5",
  I: "b4!2", J: "[b4@8 b4@15 ~ a4@15 ~ b4@15 ~@9]/4", K: "~ b5", L: "[b5@8 d#6@23 ~]/2", M: "[b5@8 d#6@11 ~ b5@11 ~]/2",
  N: "[d#6@11 ~ b5@11 ~ b5@8]/2", O: "b5@15 ~", P: "[b4@11 ~ b4@11 ~ b4@8]/2", Q: "d#5@15 ~",
  R: "[d#5@8 b4@4 d#5@11 ~ d#5@8]/2", S: "b4@15 ~", T: "[d#5@11 ~ b4@11 ~ b4@8]/2", U: "[~@8 b5@11 ~ b4@11 ~]/2",
  V: "[~@12 d#5@11 ~ b4@8]/2", W: "[d#5@11 ~ e5@11 ~ d#5@8]/2", X: "[f#5@11 ~ f#5@11 ~@9]/2",
  Y: "[~@8 b4@11 ~ b4@11 ~]/2", Z: "[d#5@11 ~ e5@11 ~@9]/2", AA: "f#5", AB: "[d#5@11 ~ e5@11 ~ e5@8]/2",
  AC: "[e5@11 ~ e5@11 ~ d#5@8]/2", AD: "[f#5@61 ~@3]/4", AE: "f#4@11 ~@5", AF: "[d#5@8 d#5@4 e5@11 ~ d#5@8]/2",
  AG: "[d#5@4 b4@4 b4@15 ~ a4@15 ~ b4@15 ~@9]/4", AH: "d#5!2", AI: "e5 d#5", AJ: "[b5@11 ~ b4@11 ~@9]/2",
  AK: "[f#4@23 ~@9]/2", AL: "[~@8 d5@11 ~ b4@11 ~]/2", AM: "e5@15 ~", AN: "[d5@11 ~ d5@11 ~ b4@8]/2", AO: "a4@15 ~",
  AP: "f#4@15 ~", AQ: "[f#5@15 ~]/2", AR: "f#4!2", AS: "[b4@4 f#4@4 f#4@15 ~ f#4@15 ~ f#4@15 ~@9]/4", AT: "b4",
  AU: "[~@12 d5@11 ~ b4@8]/2", AV: "[b4@23 ~@9]/2", AW: "~ d#5", AX: "[d#5@8 b4@23 ~]/2",
  AY: "[d#5@8 d5@15 ~ d5@15 ~ d5@15 ~ d5@11 ~ b4@11 ~]/5", AZ: "[e5@11 ~ d5@11 ~ b4@8]/2", BA: "[d5@23 ~]/3",
  BB: "d5 c#5 c5@2", BC: "[b4@23 ~]/3", BD: "~@2 b5@13 ~",
})).s("gm_flute").gain(0.4)

// other · flute · soft notes
const flute_soft = note("<~@11 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@595>".pickRestart({
  A: "~ b4", B: "d5 b4", C: "d5@15 ~", D: "e5 d5", E: "f#5@15 ~",
})).s("gm_flute").gain(0.15)

// other · flute
const flute_2 = note(`<
  ~@27 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D F@2 A
  B C D E D F@2 A B C D E D F@2 A B C D E D F@2 A B C D E D F@2 A B C D E D F@2 A B C D E D F@2 ~@6 F@2 ~@6 F@2 ~@6 F@2
  ~@18 F@2 A G@2 ~ A H I@2 J@2 K ~@3 F@2 J@2 L ~ A M@2 N@2 O@3 ~@2 F@2 A G@2 ~ A P@2 ~ Q@2 K ~@3 F@2 ~@8 R@2 S ~@4 T U@2
  L ~@17 V@2 ~@2 W@2 S ~@25 X K ~@2 Y@2 Z@2 ~ E AA@2 AB@2 AC@2 ~@16 X K ~@6 Y@2 E ~ AD@2 E ~ E ~ AE@2 AF@2 ~@11 I AG@4
  ~@2 AH AI@2 I K ~@4 AJ@2 ~ T AK X F ~@10 AL@2 AM@2 S ~@5 AN@2 G@2 ~@2 AO@2 AP@2 K ~@17 AQ AR R@2 AC@2 ~@3 I AG@4 ~@34
  A B C D E D ~@2 A B C D E D ~@2 A B C D E D ~@2 A B C D E D X K ~@6 AS AT ~@10 K@2 AM@2 AS AT ~@10 K@5 ~ A AU@2 ~@3 K
  ~ A AU@2 ~@3 K ~ A AU@2 ~@3 K ~ A ~@5 AS AT ~@4 AV@2 AW@2 ~@2 AL@2 AX@2 AS AT ~@4 AV@2 AW@2 ~@2 K@4 AY@4 AZ@3 ~@11 BA
>`.pickRestart({
  A: "~ b4", B: "d5 b4", C: "d5@15 ~", D: "e5 d5", E: "f#5@15 ~", F: "b4 ~", G: "[b4@8 d#5@23 ~]/2", H: "b4 d#5",
  I: "b4!2", J: "[~@8 b4@11 ~ b4@11 ~]/2", K: "b4@15 ~", L: "d#5@15 ~", M: "[b4@8 d5@23 ~]/2",
  N: "[~@8 d#5@15 ~ b4@8]/2", O: "[b4@8 a4@15 ~ b4@15 ~@9]/3", P: "[b4@8 d#5@11 ~ b4@11 ~]/2",
  Q: "[d#5@11 ~ b4@11 ~ b4@8]/2", R: "[b4@8 b4@4 b4@11 ~ b4@8]/2", S: "f#4@15 ~", T: "~ d#5",
  U: "[d#5@11 ~ d#5@11 ~ b4@8]/2", V: "[~@8 b4@11 ~ b3@11 ~]/2", W: "[~@12 b4@11 ~ f#4@8]/2", X: "b4",
  Y: "[d#5@11 ~ e5@11 ~ d#5@8]/2", Z: "[f#5@11 ~ f#5@11 ~@9]/2", AA: "[f#5@11 ~ f#5@11 ~ f#5@8]/2",
  AB: "[f#5@11 ~ f#5@11 ~ d#5@8]/2", AC: "[b4@15 ~]/2", AD: "d#5@11 ~@5", AE: "[f#5@11 ~ f#5@11 ~ e5@8]/2",
  AF: "[d5@11 ~ b4@19 ~]/2", AG: "[d#5@4 b4@4 b4@15 ~ a4@15 ~ b4@15 ~@9]/4", AH: "~ f#4", AI: "f#4!2",
  AJ: "[b4@11 ~ b4@11 ~@9]/2", AK: "d#5 b4 b4@2", AL: "a4@15 ~", AM: "[b4@11 ~ b4@11 ~ f#4@8]/2",
  AN: "[~@8 d5@11 ~ b4@11 ~]/2", AO: "e5@15 ~", AP: "[d5@11 ~ d5@11 ~ b4@8]/2", AQ: "~ e4", AR: "e4!2", AS: "f#4",
  AT: "f#4 ~", AU: "[b4@8 f#4@23 ~]/2", AV: "[~@8 b4@11 ~ f#4@11 ~]/2", AW: "[f#4@8 f#4@23 ~]/2",
  AX: "[b4@11 ~ f#4@11 ~ f#4@8]/2", AY: "[b4@61 ~@3]/4", AZ: "[b4@23 ~]/3", BA: "~@2 b4@13 ~",
})).s("gm_flute").gain(0.4)

// chords · piano
const piano = note(`<
  ~@43 A B C D E D ~@2 F G H I J I ~@2 F G H I J I ~@2 F G H I J I ~@2 F G H I J I K@2 F G H I J I K@2 F G H I J I L@2 M
  N O P Q P L@2 M N O P Q P L@2 M N O P Q P L@2 M N O P Q P R S T U R S T U R S T U R S T U R S T U R S T U R S T U R S
  T U R S T U R S T U R S T U V W T U R S T U R S T U R S T U R S T U R S T U R S T U R S T U R S T U R S T U R S T U R
  S T U R S T U X@2 Y Z AA@2 AB@2 X@2 Y Z AA@2 AB@2 X@2 Y Z AA@2 AB@2 X@2 Y Z AA@2 AB@2 Z@8 AC AD AE AF AC AD AE AF AC
  AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF
  AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AC AD AE AF AG AH AI ~@4 AH AG AH
  AI ~@4 AH AG AH AI ~@4 AH AG AH AI ~@5 AJ@3 AK AL@4 AJ@3 AK AL@4 AJ@3 AK AM@4 AJ@3 AK AM@4 AN@8 AO@8 AP@6 AO@2 AP@6 AO
  AQ AR@3 AS AT@4 AR@3 AS AT@4 AR@3 AS AT@4 AR@3 AS AT@4 AU@2 AV AW AX AY AZ AY AU@2 AV AW AX AY AZ AY AU@2 AV AW AX AY
  AZ AY AU@2 AV AW AX AY AZ AY BA BB BA BB BA BB BA BB AR@3 AS AT@4 AR@3 AS AT@4 AR@3 AS AT@4 AR@3 AS BC@2 BD@2 BE@3
  BF@4 ~ BE@3 BF@4 ~ BE@3 BF@4 ~ BE@3 BF@4 ~ AR@3 AS AT@4 AR@3 AS AT@4 AR@3 AS AT@4 AR@3 AS AT@4 BG@4 BA@5 BH@6 BI@4
>`.pickRestart({
  A: "~ b3", B: "d4 b3", C: "d4@15 ~", D: "e4 d4", E: "f#4@15 ~", F: "~ [b2,b3]", G: "[d3,d4] [b2,b3]",
  H: "[d3,d4]@15 ~", I: "[e3,e4] [d3,d4]", J: "[f#3,f#4]@15 ~", K: "[b2,b3] ~", L: "[b2,b3] b2", M: "b2 [b2,b3]",
  N: "[b2,d4] [b2,b3]", O: "b2!2, d4@15 ~", P: "[b2,e4] [b2,d4]", Q: "b2!2, f#4@15 ~", R: "b3!2 b2@2, b2@2 b3 ~",
  S: "b2!2, b3 ~@3", T: "b3@3 ~@2 b3@3 b2@8, b2@2 b3 ~", U: "b3 ~@2 b3, b2!2, ~@3 b3@2 ~@3",
  V: "b3!2 b2@2, [b1,b2]@2 b3 ~", W: "[b1,b2] b2, b3 ~@3", X: "[b2!2 b2!2, b3@15 ~, f#3@15 ~ f#3@15 ~]/2",
  Y: "b2!2, e3@15 ~", Z: "b2!2", AA: "[b2@2 [b2,f#3]@2 f#3 ~ b2@2, ~@8 b3@11 ~ [e3,a3]@11 ~, ~@2 b2 ~]/2",
  AB: "[b2!2 b2!2, e3@15 ~]/2", AC: "[f#3,b3]!3 ~, b2!2", AD: "[f#3,b3] ~ b2@2, b2 ~",
  AE: "[f#3,b3]@3 ~@2 [f#3,b3]@3 [f#3,b3]@4 ~@4, b2!2", AF: "[f#3,b3] ~@2 [f#3,b3], b2!2, ~@3 [f#3,b3]@2 ~@3",
  AG: "[b2,f#3,b3]@15 ~", AH: "[a2,e3,a3]@15 ~", AI: "[e2,b2,e3]@15 ~",
  AJ: "[b1!2 [b1,f#3] [e2,e3] e2!2, b3@23 ~ a3@23 ~, f#3@15 ~@17 e3@15 ~]/3", AK: "[b1,e3,b3] [a1,f#3,c#4]",
  AL: "[a1!2 [a1,e3] [b1,b3] b1!2 b1!2, a3@23 ~@9 b3@15 ~ b3@15 ~, e3@15 ~@9 e3@38 ~@2]/4", // A5 B
  AM: "[a1!2 [a1,e3] b1 b1!2 b1!2, a3@23 ~@41, e3@15 ~@9 e3@38 ~@2]/4", // A5
  AN: "[b1!2 b1!2 b1!2 b1!2 b1!2 b1!2 b1!2 b1!2, b3@61 ~@3, f#3@15 ~ f#3@15 ~ f#3@15 ~ f#3@15 ~ f#3@15 ~ f#3@15 ~ f#3@15 ~ f#3@15 ~]/8",
  AO: "b1!2",
  AP: "[[b1,f#3,b3] [b1,e3] [b1,e3] [b1,b3] b1!2 b1!2 b1!2 b1!2, ~@8 a3@15 ~ e3@68 ~@4, ~@32 b3@15 ~ b3@15 ~ b3@15 ~ b3@15 ~]/6", // B5 E5 B
  AQ: "b1!2, e3@15 ~", AR: "[f#3@15 ~ f#3@8 e3@8 e3@15 ~, [b2,b3]@23 ~ [a2,a3]@23 ~]/3", AS: "[e2,b2,e3] [f#2,c#3,f#3]",
  AT: "[e3@15 ~ e3@8 [e2,b2,e3]@38 ~@2, [a2,a3]@23 ~@41]/4", AU: "[f#3@15 ~ f#3@8 [e2,b2,e3]@8, [b2,b3]@23 ~@9]/2",
  AV: "~ [b1,b2]", AW: "[d2,d3] [b1,b2]", AX: "[d2,d3]@15 ~", AY: "[e2,e3] [d2,d3]", AZ: "[f#2,f#3]@15 ~",
  BA: "[b1,b2]", BB: "[b1,b2]@15 ~", BC: "[e3@15 ~ e3@8 [e2,b2,e3]@8, [a2,a3]@23 ~@9]/2", BD: "[[e2,b2,e3]@15 ~]/2",
  BE: "[f#3@15 ~ f#3@15 ~ f#3@8 [e2,e3]@8, [b2,b3]@19 ~@5]/3", // E B
  BF: "[[f#2,f#3]@8 e3@8 e3@15 ~ e3@15 ~ e3@15 ~, ~@8 [a2,a3]@53 ~@3]/4", // F# A
  BG: "[[b1,f#3]@15 ~ [b1,f#3]@15 ~ [b1,f#3]@15 ~ [b1,f#3]@15 ~, [b2,b3]@61 ~@3]/4", // B5 B
  BH: "[~ [b1,b2]@17 [b1,b2]@19 [b1,b2]@18 [b1,b2]@20 ~ [b1,b2]@20]/6", // B
  BI: "[[b1,b2]@23 [b1,b2]@26 ~ [b1,b2,f#3,b3]@13 ~]/4", // B B5
})).s("gm_piano").gain(0.4)

// drums · kick
const kick = s("bd").struct(`<
  ~@81 A@2 ~ A ~ A ~ A@3 ~ A ~ A ~ A@3 ~ A ~ A ~ A@3 ~ A ~ A ~ A@3 ~ A ~ A ~ A@3 ~ A ~ A ~ A@3 ~ A ~ A ~ A@3 ~ A ~ A ~
  A@3 ~ A ~ A ~ A@3 ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A
  ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~@4 B C D B
  A@83 ~@4 A@4 ~@4 A@4 ~@4 A@4 ~@4 B A@96 ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A@2 ~ A ~ A ~ A
  ~ A@97 ~@7 A ~@9 E
>`.pickRestart({
  A: "x", B: "~ x", C: "~ x ~@2", D: "x ~@2 x", E: "~ x ~@6",
})).gain(0.4)

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

// drums · low tom
const low_tom = s("lt").struct("<~@242 A ~ A ~@17 B C ~@81 A@3 ~@4 A@4 ~@4 A@4 ~@4 A@4 ~@4 D ~@251>".pickRestart({
  A: "x", B: "~ x ~@2", C: "~@3 x", D: "~@2 x!2",
})).gain(0.4)

// drums · hihat
const hihat = s("hh").struct("<~ A@243 B A@16 B ~@3 A@80 ~@32 A@134 B A@97 ~@19>".pickRestart({
  A: "x!2", B: "x",
})).gain(0.4)

// drums · mid tom
const mid_tom = s("mt").struct("<~@242 A ~ B ~@16 C D E C ~@363>".pickRestart({
  A: "x", B: "x!2", C: "~ x", D: "~ x ~@2", E: "x ~@2 x",
})).gain(0.4)

// drums · crash
const crash = s("cr").struct("<~@609 x ~@7 x ~@9 [~ x ~@6]>").gain(0.4)

stack(flute, flute_soft, flute_2, piano, kick, snare, low_tom, hihat, mid_tom, crash)