Strudelify

Red Light Special

TLC

KeyC minorTempo62 bpm
0:00/0:00
// Red Light Special — TLC
// 62 bpm, 4/4, key C minor. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: pitch bends are ignored
// note: sustain pedal (CC 64) lengthens the held notes
// note: Full arrangement: all 72 bars on a 24-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(62/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 · epiano1 · "Keys"
const epiano1 = note(`<
  A B A C@2 D E F A G A H A I A J K L K M A B A C@2 D E F A G A H A I A J K L K M N B A C@2 D O P Q R S T U V W X A B A
  C@2 D E Y@3 ~@6
>`.pickRestart({
  A: "g3@5 g3 [f3,bb3,d4]@3 [g3,c4,eb4]@3, [c4,eb4] ~", // Bb Cm
  B: "eb3@5 ~@3 eb3 f3@2 f3, [ab3,c4]@2 [ab3,c4] [bb3,d4], ~@5 eb3@3 ~@4", // Ab Bb
  C: "[eb3@5 ~@12 g3 [f3,bb3,d4]@3 [g3,c4,eb4]@3, c4@7 c4@2 eb4@2 g3@6 ~@7, ab3!2 ~@2, ~@5 eb3@7 ~@12, ~@4 d4@2 [c4,eb4]@3 ~@3]/2", // Bb Cm
  D: "eb3@5 eb3 [eb3,ab3,c4]@3 [f3,bb3,d4]@3, [ab3,c4] ~", E: "[bb3,d4,f4] [bb3,db4,eb4,f4]",
  F: "[ab3,c4,eb4] [c4,eb4,g4]", G: "[eb3,ab3,c4]@19 ~@5",
  H: "[eb3,ab3,c4]@5 ~@6 bb3, ~@5 eb3@3 eb3@4, ~@2 ab3!2, ~@7 c4@5, ~@5 d4", // Ab
  I: "eb3@5 ~@6 bb3, ab3@2 ab3, c4!2, ~@5 eb3@7, ~@3 d4",
  J: "eb3@10 ~@8 d4@3 ~@3, ab3@16 ab3@5 ~@3, c4@4 c4@3 ~, ~@5 eb3@6 ~", K: "[eb4,g4,bb4]@2 [d4,f4,bb4] [eb4,g4,bb4]",
  L: "[c4,eb4,g4]@19 ~ [c4,eb4,g4]@4", M: "[c4,eb4,g4]@6 [d4,f4,bb4]@6 [c4,eb4,g4] ~@11",
  N: "g3@5 g3 [f3,bb3,d4]@3 [g3,c4]@3, eb4, c4 ~", O: "[bb3,d4,f4] [bb3,c4,eb4,f4]",
  P: "[ab3,c4,eb4]@6 [c4,eb4,g4] ~@5", // Ab Cm
  Q: "gb3@4 ~ f4 ab3@3 ab3@3, [bb3,db4]@13 ~@11, f4@5 ~ [f3,c4,eb4]@6, ~@8 gb3@5 ~@11", // Bbm F7
  R: "f4@3 ~@7 bb3@2 bb3@6 ~@4 d4@2, [d4,g4]@3 d4@2 g4, bb3@10 ~@2 g4@6 bb3@5 ~, ~ f4@7, ~ bb4@3", // G5
  S: "gb3@4 ~ f4 ab3@3 ~@2 eb4, [bb3,db4]@6 eb4@5 ~, f4@5 ~ f3@6, ~@2 gb3 c4@2 c4, ~@3 ab3", // Bbm
  T: "bb3@2 ~@3 bb3 bb3@4 ~ d4, g4 [f4,g4], d4@6 [d4,bb4]@7 ~@7 bb3@4, ~@2 bb3@3 ~ d4@5 ~", // Fsus2 Gm
  U: "gb3@4 ~ f4 ab3@3 ~@2 eb4, [bb3,db4]@3 c4@2 c4, f4@5 ~ eb4@5 ~, ~@2 gb3 f3@3, ~@3 ab3", // Bbm
  V: "[c4,eb4,g4]@3 [d4,f4,bb4]@3 c4@4 ~ bb4, ~ [e4,g4], ~@6 bb4@5 ~, ~@5 c4", // Cm Bb Em
  W: "[c4,eb4,ab4]@3 [bb3,d4,g4]@3 ab3@3 ~@2 f4, ~ eb4, ~@6 f4@5 ~, ~@3 c4@2 c4, ~@3 ab3", // Ab Gm
  X: "[c4,eb4,g4]@12 [c4,eb4,g4] ~@11", Y: "[[ab3,c4,eb4] [c4,eb4,g4]@4 ~]/3",
})).s("gm_epiano1").gain(0.26)

// bass · fretless bass · "Bass"
const bass = note(`<
  A B A C A D E F G H I J I K I J L M N O A B A C A D E F G H I J I K I K L M N O A B A C A D E P Q R Q R Q S T U A B A
  C A D E F ~@8
>`.pickRestart({
  A: "c2@4 c3 ~@5 bb1@2 c2@5 ~ c2@6", B: "f1@4 f2 ~@5 eb1@2 f1@7 ~ g1@2 bb1@2", C: "f1@4 f2 ~@5 eb1@2 f1@8 g1@2 bb1@2",
  D: "f1@4 f2 ~@5 eb1@2 f1@6 g1@4 ab1@2", E: "g1@3 ~ g1 ~@3 g1@2 eb1@2 gb1@3 ~ gb1 ~@3 gb1@2 eb1@2",
  F: "f1@4 g1@2 ab1@6 bb1@11 ~", G: "c2@4 c3 ~@5 bb1@2 c2@4 c3@2 c2@2 bb1@2 g1@2",
  H: "f1@4 f2 ~@5 eb1@2 f1@4 f2@2 f1@2 g1@2 bb1@2", I: "c2@4 c3 ~@5 bb1@2 c2@5 ~ c2@2 bb1@2 g1@2",
  J: "f1@4 f2 ~@5 eb1@2 f1@5 ~ f1 ~ g1@2 bb1@2", K: "f1@4 f2 ~@5 eb1@2 f1@5 ~ f1@2 g1@2 bb1@2",
  L: "c2@4 ~ c2 g1@3 c2@3", M: "f1@8 ~@2 eb1@2 f1@5 ~ f1 ~ g1@2 bb1@2", N: "c2@2 c3 ~@2 c2 g1@3 c2@3",
  O: "f1@3 g1@3 bb1 ~@5", P: "f1@3 ab1@3 bb1 ~@5", Q: "gb1@4 ab1 a1 bb1@6", R: "eb2@11 ~ eb2@12", S: "c2 d2 c2@2",
  T: "ab1 g1 f1@2", U: "bb1@12 bb1 ~@7 g1@2 bb1@2",
})).s("gm_fretless_bass").gain(0.31)

// other · string ensemble 2 · "Strings"
const string_ensemble_2 = note(`<
  A B C D E B F@2 ~@12 A B C D E B F@2 ~@12 A B C D E B F@2 ~@8 A B C D E B F@2 ~@8
>`.pickRestart({
  A: "~@8 eb4@2 ~@2 c4@7 ~@5", B: "~@3 c4@2 ~", C: "~@6 eb4@3 ~@3 c4@7 ~@5", D: "~@12 c4@7 ~@5",
  E: "~@6 eb4@2 ~@4 c4@7 ~@5", F: "bb4 ~@2 eb4 ~@2",
})).s("gm_string_ensemble_2").gain(0.2)

// other · string ensemble 2 · "Strings" · soft notes
const string_ensemble_2_soft = note("<~@5 A ~@19 A ~@19 A ~@15 A ~@10>".pickRestart({
  A: "~@3 eb4 ~@8",
})).s("gm_string_ensemble_2").gain(0.1)

// other · overdriven guitar · "Elec Guitar"
const overdriven_guitar = note(`<
  A B C D A E F G ~@12 H I J K A E F G ~@12 H I J K A E F G L@2 M N M ~@2 O P Q R S T U V W ~@8
>`.pickRestart({
  A: "g5@17 ~ g5@2 f5@2 eb5@2", B: "c5@10 eb5 c5", C: "f5@18 g5@5 ~", D: "g5@4 f5 eb5 c5@18",
  E: "c5@12 eb5@2 f5 ~@3 eb5@2 f5@2 ~@2", F: "bb5@9 ab5 g5 ab5", G: "bb5 g5 eb5@10", H: "g5@17 ~ g5@4 f5 eb5",
  I: "c5@9 c5 eb5 c5", J: "f5@17 ~ g5@5 ~", K: "g5@4 ~ d5@16 ~@3, ~@2 f5 ~@9",
  L: "[eb4@6 bb4@7 g4 ab4 bb4@4 g4 ab4 bb4@3]/2", M: "eb4@12 bb4@11 ~", N: "g4 eb4 d4 g4 eb4 d4 g4 eb4 d4 g4 eb4 d4",
  O: "~@9 c5 eb5 c5", P: "g5@17 ~ f5@4 eb5@2, ~@18 g5 ~@5", Q: "f5@4 eb5@2 c5@6 ~@8 c5@2 eb5 c5", R: "f5@3 g5",
  S: "~@2 g5 f5 eb5 f5 f5@3 eb5 c5 ~ c5@6 ~@2 c5@2 eb5 c5", T: "g5@10 [f5,g5] eb5",
  U: "f5@4 eb5@2 c5@4 eb5@2 ~@6 bb4!2 c5 bb4 eb5 c5", V: "bb5@7 ab5 g5 ab5 g5 eb5", W: "ab5 g5 eb5 ab5 g5 eb5 c6@6",
})).s("gm_overdriven_guitar").gain(0.36).pan(0)

// other · epiano2 · "Piano"
const epiano2 = note(`<
  A B A C A D ~ E A F A G A C A B H I J K L M L N L O P@2 L Q A C R C A B J S J K L T A U A V ~@10 L M L N L O P W@3 ~@6
>`.pickRestart({
  A: "eb3@2 d3 eb3", B: "c3@3 d3", C: "c3", D: "c3@23 ~", E: "~@4 eb3@3 ~", F: "c3@11 ~", G: "c3@7 ~",
  H: "eb3@11 ~ f3@6 g3@6", I: "eb3@5 ~", J: "g3@2 f3 g3", K: "eb3@3 f3@3 eb3 ~@5", L: "~@2 d3 eb3, eb3@3 ~",
  M: "eb3, c3@11 ~", N: "~ c3@23, eb3", O: "c3@18 d3@5 ~, eb3", P: "eb3", Q: "c3, eb3@7 ~@17", R: "eb3@12 d3@6 ~ eb3@5",
  S: "eb3@7 ~", T: "c3@3 d3, eb3@7 ~", U: "c3@5 ~", V: "c3@11 ~ c3@6 d3@6", W: "[eb3@55 ~@17]/3",
})).s("gm_epiano2").gain(0.26)

// drums · kick
const kick = s("bd").struct("x ~@4 x!2 ~@5").gain(0.4)

// drums · snare
const snare = s("sd").struct(`<
  [~ x ~ x]!19
  [~@6 x ~@11 x ~@2 x!3]
  [~ x ~ x]!19
  [~@6 x ~@11 x ~ x!4]
  [~ x ~ x]!23
  [~@6 x ~@11 x ~@2 x!3]
  [~ x ~ x]!8
>`).gain(0.4)

// drums · hihat
const hihat = s("hh").struct("<A B A@2 C D A@14 C A E A C A@14 D A ~@15 C A E A C A@3 C A E A C A@3>".pickRestart({
  A: "x!12", B: "x!10 ~ x", C: "~ x!11", D: "x!10 ~@2", E: "x!5 ~ x!6",
})).gain(0.3)

// drums · hihat · soft notes
const hihat_soft = s("hh").struct("<A@7 ~ A@19 B A@11 ~@2 A@22 B A@7 B>".pickRestart({
  A: "~ x!2 ~ x!2 ~ x!2 ~ x!2", B: "~ x ~@10",
})).gain(0.2)

// drums · low tom
const low_tom = s("lt").struct("<~@22 [~@5 x ~@6] ~@35 [~@5 x ~@6] ~@7 [~@5 x ~@6] ~@5>").gain(0.25)

// drums · open hat
const open_hat = s("oh").struct("<~ A ~@3 A ~@15 A ~@3 A ~@15 A ~@3 A ~@11 A ~@3 A ~@3 A ~@3 A ~@2>".pickRestart({
  A: "~@5 x",
})).gain(0.4)

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

// drums · tambourine
const tambourine = s("tb").struct(`<
  A@4 B A@3 C A C A C A C A C A C A B A@3 B A@3 C A C A C A C A C A C D B A@3 B A@3 B A@7 B A@3 B A@3 B A@3 B A@3
>`.pickRestart({
  A: "x!12", B: "~ x!11", C: "x ~ x!10", D: "x!10 ~@2",
})).gain(0.2)

// drums · cabasa
const cabasa = s("cabasa:4").struct("<~@34 [~@2 x!4 ~@2 x ~@15]!3 ~@35>").gain(1.01)

// drums · shaker
const shaker = s("sh").struct("~@2 x!5 ~@7 x!5 ~@5").gain(0.2)

stack(
  epiano1, bass, string_ensemble_2, string_ensemble_2_soft, overdriven_guitar, epiano2, kick, snare, hihat, hihat_soft,
  low_tom, open_hat, crash, tambourine, cabasa, shaker
)

More by TLC