Strudelify

Kung Fu Fighting

Carl Douglas

KeyC majorTempo106 bpm
0:00/0:00
// Kung Fu Fighting — Carl Douglas
// 106 bpm, 4/4, key C 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 (2/4 at bar 1, 8/4 at bar 2, 2/4 at bar 11, 4/4 at bar 11) are rendered on a constant 4/4 grid of one bar per cycle
// note: pitch bends are ignored
// note: Full arrangement: all 83 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(106/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.

// chords · piano · "Track-1"
const piano = note("<A@7 B@3 ~@73>".pickRestart({
  A: "[~@2 [g4,c5,e5]@33 ~@4 [a4,d5,f5]@33 ~@5 [c4,g4,c5,e5]@34 ~, ~@2 c4@36 ~ d4@37 ~@36]/7", // C Dm C
  B: "[~ [a4,d5,f5]@16 ~@7, ~@2 d4@39 ~@7]/3", // Dm
})).s("gm_piano").gain(0.48)

// other · sitar · "Track-2"
const sitar = note("<A B@3 C D E@2 F ~@74>".pickRestart({
  A: "~@2 [c5,d5] d#5 f5 g5 [a5,a#5] c6 d6@2 c6 [a5,a#5] [f5,g5] d#5 d5@2", // Csus2 A#maj7 Fsus2
  B: "[~ f5 ~ a5 a#5 c6 a#5@3 [f5,g5] d#5 d5 c5@3 d5@2 f5 ~ a5 ~ d6@2 a#5 a5 [f5,g5] d#5 d5 a#4@2 ~@2 f5 g5 a5 a#5 ~@2 a5 g5 f5 d#5 d5 c5 [a#4,c5]@2 ~ d#5, ~@18 g5@2 ~ c6 ~@6 c5 ~ c5@2 ~@5 a#5@2 ~@9, ~@31 d#5@2 ~@3 c6@2 ~@10]/3", // Fsus2 A#sus2
  C: "[f5,g5] a5 ~@4 g5 f5 d#5 d5 ~ d5@2 d#5 f5 g5, ~@10 c5@3 ~@3", // Fsus2
  D: "a5 a#5@2 ~@2 a5 g5 f5 d#5 d5 c5@2 d5@2 [f5,g5] a5, ~@2 a#5 ~@5", // Fsus2
  E: "[a#5 c6 ~ a5 g5 f5 ~ [c5,d5] ~@3 [d5,d#5] f5 g5 a5 ~ c6 a5 [f5,g5] d#5 d5 ~@2 c5 d#5 f5 ~ a5 a#5 c6 a#5 a5, ~@2 a#5@2 ~@2 d#5@2 ~ a#4@2 ~@10 c5@2 ~@9, ~@10 c5@2 ~@3 a#5@3 ~@4 a#4@2 ~@8]/2", // Csus2 D#maj7 Fsus2
  F: "[f5,g5] ~ d5@4 f5 [g5,a5] a#5@3 a5 g5@2 d#5@2, ~ d#5@2 ~@13", // Fsus2 Gsus2
})).s("gm_sitar").gain(0.1)

// other · sitar · "Track-2" · soft notes
const sitar_soft = note("<~ A B@2 C D ~ E F@2 ~@73>".pickRestart({
  A: "~ d#5 g5 ~@5 a5 ~@7", B: "[d#5@2 ~@2 a#5 ~@2 c6 ~@7 d5@2 ~@13 d5 ~]/2", C: "~@2 a#5@3 a5@2 ~@9",
  D: "~@2 c6@2 ~@9 d#5 ~@2", E: "~@8 d5 ~ g5 ~@5", F: "[~@5 d#5 ~@7 f5@2 ~ c5@3 ~@13, ~@15 d5@2 ~@15]/2",
})).s("gm_sitar").gain(0.05)

// chords · piano · "Track-2           2"
const piano_2 = note("<A@2 ~ B ~ C D E F ~@74>".pickRestart({
  A: "[~@14 c5 f5@2 e5@5 c5@2 ~ g5@7]/2", B: "~@5 f5 ~@4 f5 a5@3 ~@2, ~@2 d5 ~@5",
  C: "~@5 g4 c5 ~ e5@3 ~@2 c5@2 ~, ~@7 f5@3 ~ d5@5", D: "g5@3 ~@5", E: "~@11 a4 f5@2 ~@2, ~@12 d5 ~@3",
  F: "d5 ~ a5@5 d6@4 ~@5, ~ f5@2 ~@13",
})).s("gm_piano").gain(0.32)

// chords · piano · "Track-2           2" · soft notes
const piano_soft = note("<[~@14 g4 ~] [~@4 d5@5 ~@7] ~ [~@4 a4 ~@5 d5 ~@5] ~@79>").s("gm_piano").gain(0.16)

// bass · acoustic bass · "Track-3"
const bass = note(`<
  ~@10 A@2 B@2 A@2 B@2 A B A B A B A C A@2 B@2 A@2 B@2 A B A B A B A C A@2 B@2 A@2 B@2 D E F G H I J K A@2 B@2 A@2 B@2
  A@2 B@2 A@2 B@2 A@2 B@2 A@2 B@2 L
>`.pickRestart({
  A: "c2!2 ~@4 c2!2 ~ c2!2 ~ c2 a#1 g1 ~", B: "d2!2 ~@4 d2!2 ~ d2!2 ~ d2 c2 a1 ~", C: "g1!2 ~@4 g1!2 ~ g1!2 ~ g1!3 ~",
  D: "a1!2 ~@4 a1!2 ~ a1!2 ~ a1 ~ e1 g1", E: "a1 ~@5 a1!2 ~ a1!2 ~ a1 ~ [a1,a#1] c2",
  F: "d2!2 ~@4 d2!2 ~ d2!2 ~ d2!2 a1 c2", G: "d2 ~@5 d2!2 ~ d2!2 ~ d2 ~ e1 g1",
  H: "a1 [a1,a#1] ~@4 a1!2 ~ a1!2 ~ a1!2 e1 g1", I: "a1!2 ~@4 a1!2 ~ a1!2 ~ a1!3 c2",
  J: "d2 [c2,d2] ~@4 d2!2 ~ d2!2 ~ d2 ~ c2 a1", K: "d2 ~@5 g1!2 ~ g1!2 ~ g1 a1 c2 a1", L: "~@4 c2 ~@3",
})).s("gm_acoustic_bass").gain(0.64)

// other · string ensemble 1 · "Track-5"
const string_ensemble_1 = note(`<
  A@7 B@2 ~@9 C D E F G H I@2 ~ J K L ~ M K N O P Q H R S T@2 ~ J K L ~ M K N U@4 V@2 W@2 ~ J K L ~ M K N ~ J K L ~ M K
  N ~ J K L ~ J K L ~
>`.pickRestart({
  A: "[~@2 [c4,e5]@38 [d4,f5]@37 [c4,e5]@35]/7", B: "[~ [d4,f5]@14 ~]/2", C: "[c4,c5], g4@7 ~", D: "[d4,d5]",
  E: "c4@15 ~", F: "d5", G: "[c4,e5], g4@7 ~", H: "[d4,a4,d5]", I: "[[c4,c5]@16 [g3,d5]@15 ~, g4@15 ~]/2",
  J: "[a4,a5]!4 [g4,g5] ~ [g4,g5]!2 [e4,e5] ~ [e4,e5] ~ [g4,g5]@3 ~", K: "~@14 [f4,f5] [e4,e5]",
  L: "[f4,f5] ~ [e4,e5] d5 [e4,e5] ~ [d4,d5] [c4,c5] [d4,d5] ~ [a3,a4] ~ [a3,a4]@2 ~@2", // F E D C D A
  M: "[a4,a5]!4 [g4,g5] ~ [g4,g5]!2 [e4,e5] ~ [e4,e5] ~ [g4,g5]@2 ~@2", // A G E G
  N: "[f4,f5] ~ [e4,e5] [d4,d5] [e4,e5] ~ [d4,d5] [c4,c5] [d4,d5] ~ [a3,a4] ~ [a3,a4]@2 ~@2", O: "[c4,c5]@15 ~",
  P: "[d4,d5,f5]", Q: "[c4,c5,e5], g4@7 ~", R: "[c4,g4,c5]", S: "d4", T: "[[c4,c5] [g3,d5], g4@31 ~]/2",
  U: "[[a3,c5]@16 d5@15 ~, a4@61 ~@3]/4", V: "[c5@15 ~]/2",
  W: "[f5@14 [f4,f5] [e4,e5] [f4,f5] ~ [e4,e5] [d4,d5] [e4,e5] [d4,d5] [c4,c5] [d4,d5] ~@2 g4@2 ~@4, [d4,d5]@19 ~@6 g5@4 ~@3]/2", // F E F E D E D C …
})).s("gm_string_ensemble_1").gain(0.56)

// other · string ensemble 1 · "Track-5" · soft notes
const string_ensemble_1_soft = note(`<
  ~@18 A B C D E F A G ~@3 H ~ I ~@2 J K ~ L A M A N ~@3 H ~ I ~@2 O@2 P@2 Q@4 ~@3 H ~ I ~@5 H ~ I ~@5 H ~@3 H ~
>`.pickRestart({
  A: "e5@15 ~", B: "[a4,f5]@15 ~", C: "[g4,c5,e5]@15 ~", D: "[d4,f5], a4@13 ~@3", E: "c5", F: "f5", G: "b4@7 ~",
  H: "~@3 d4 ~@12", I: "~@4 a4 ~@11", J: "[g4,e5]@15 ~", K: "a4@15 ~", L: "f5@15 ~", M: "[a4,d5,f5]", N: "b4@15 ~",
  O: "[e5@31 ~]/2", P: "[d4, f5@15 ~]/2", Q: "[[a3,e5] ~, a5@53 ~@11]/4",
})).s("gm_string_ensemble_1").gain(0.32)

// drums · kick
const kick = s("bd").struct("<~@10 [x!4]!72 [~@2 x ~@2 x ~@2 x ~@7]>").gain(0.52)

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

// drums · snare · soft notes
const snare_soft = s("sd").struct("<~@41 [x!8 ~@8] ~@31 [x!8 ~@8] ~@9>").gain(0.33)

// drums · clap
const clap = s("cp").struct("<~@82 [~ x ~@2 x ~@3]>").gain(0.66)

// drums · low tom
const low_tom = s("lt").struct("<~@65 [~@14 x!2] ~@17>").gain(0.39)

// drums · hihat
const hihat = s("hh").struct("<~@10 [x!16]!72 [x ~@4 x!4 ~@7]>").gain(0.39)

// drums · mid tom
const mid_tom = s("mt").struct("<~@17 [~@5 x ~@2] ~@47 [~@6 x ~ x ~@2 x ~@4] ~@16 [~@5 x ~@10]>").gain(0.52)

// drums · open hat
const open_hat = s("oh").struct("<~@10 A@7 ~@9 A@8 ~@8 A@23 ~ A@7 ~ A@8 ~>".pickRestart({
  A: "~@4 x ~@2 x ~ x ~@2 x ~@3",
})).gain(0.59)

// drums · high tom
const high_tom = s("ht").struct("<~@17 [~ x] ~@47 [~@2 x ~ x ~@5 x ~@2 x ~@2] ~@17>").gain(0.52)

// drums · crash
const crash = s("cr").struct("<~@26 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A ~@7 A ~@8>".pickRestart({
  A: "x",
})).gain(0.52)

// drums · ride
const ride = s("rd").struct("<[~ x ~@6] ~ [~@7 x ~@8] ~ [~@13 x ~@2] ~@2 [~ x ~@6] ~@75>").gain(0.39)

// drums · bongos
const bongos = s("bongo:18").struct("<~@9 [~@14 x!2] ~@73>").gain(1.55)

stack(
  piano, sitar, sitar_soft, piano_2, piano_soft, bass, string_ensemble_1, string_ensemble_1_soft, kick, snare,
  snare_soft, clap, low_tom, hihat, mid_tom, open_hat, high_tom, crash, ride, bongos
)