Strudelify

Good Lovin'

Blackstreet

KeyC minorTempo79 bpm
0:00/0:00
// Good Lovin' — Blackstreet
// 79 bpm, 4/4, key C minor. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: pitch bends are ignored
// note: Full arrangement: all 73 bars on a 32-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(79/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 · synth bass 2 · "MLII Productions"
const bass = note(`<
  A B A B A B A C ~@4 A B A C A B A B A B A C A B A B A B A D ~@4 E@2 F@2 E@6 F@2 E@6 G@2 H I H I H I H J H I H I H I H
  J ~
>`.pickRestart({
  A: "f1@3 ~@9 g1@3 ~@13 f1@2 g1@2", B: "ab1@3 ~@9 c2@19 ~", C: "db2@7 ~ db2@7 ~ c2@7 ~ c2@6 ~@2",
  D: "db2@7 ~@2 db2@7 ~ c2@7 ~ c2@6 ~", E: "[~ f1@3 ~@9 g1@3 ~@13 f1@2 g1@2 ab1@3 ~@9 c2@19]/2",
  F: "[~ f1@3 ~@9 g1@3 ~@13 f1@2 g1@2 db2@7 ~ db2@7 ~ c2@7 ~ c2@6 ~]/2",
  G: "[~ f1@3 ~@9 g1@3 ~@13 f1@2 g1@2 db2@7 ~ db2@7 ~ c2@7 ~@2 c2@6]/2", H: "~@2 f1@3 ~@9 g1@3 ~@13 f1@2",
  I: "g1@2 ab1@3 ~@9 c2@18", J: "g1@2 db2@7 ~ db2@7 ~ c2@7 ~ c2@6",
})).s("gm_synth_bass_2").gain(0.45)

// other · piano
const piano = note(`<
  ~@7 A@2 B C D E F@3 G H@2 I@3 J K ~@8 L M N O@2 P Q@3 R@2 S@4 T ~@8 U V W X Y Z@2 AA ~@9
>`.pickRestart({
  A: "[~@24 bb3 ~ c4 ~ eb4 ~ eb4@5 ~ c4@2 ~@18 [ab3,bb3] ~ c4 ~ eb4 ~ c4 ~]/2", // Absus2
  B: "eb4@3 ~ f4@2 ~@2 c4 ~@11 bb3@3 ~ c4 ~ eb4@2 c4 ~ f4 ~", C: "c4 ~ eb4@6 ~@16 bb3 ~ c4 ~ eb4@2 ~@2",
  D: "f4@2 ~@2 g4 ~ f4 ~@3 eb4@5 ~ c4 ~@3 g4 ~@3 g4 ~@3 g4 ~ g4@2", E: "~@2 f4@3 ~ eb4@2 ~@16 bb3 ~ c4 ~ eb4@3 ~",
  F: "[f4@2 ~@2 eb4 ~@3 c4 ~@3 g4@4 f4 ~@7 c4@3 ~ eb4 ~ eb4 f4@4 ~ g4 ~ f4@5 ~ eb4 ~ c4@6 bb3 ~ c4@5 ~ eb4 ~ f4@6 g4 ~ f4@6 eb4@2 c4@4 ~@14, ~@31 e4 ~@64]/3",
  G: "~@18 bb3@2 c4 ~ c4 ~ eb4@2 ~@2 eb4@2 ~@2",
  H: "[f4@2 ~@2 eb4@6 ~@14 c4@3 ~ eb4 ~ f4@6 g4 ~ f4@6 eb4 ~ c4@5 ~ bb3 ~ c4 ~@3 eb4 ~@5]/2",
  I: "[f4@3 ~ g4 ~ f4@5 ~ eb4@10 ~@2 bb3@4 c4 ~ eb4@6 c4 ~ eb4@4 c4 ~ eb4@2 c4 ~ eb4@3 ~ c4@2 ~@2 bb3@4 c4 ~ eb4@5 ~ c4 ~ eb4@4 c4 ~ eb4@2 c4 ~ f4@3 ~ g4@3 ~ f4@3 ~ eb4@4]/3",
  J: "~@20 bb3@4 c4 ~ bb3 ~ eb4@3 ~", K: "f4 ~ c4 ~ eb4@11 ~@17", L: "~ eb4@4 c4@2 ~@18 [ab3,bb3] ~ c4 ~ eb4 ~ c4",
  M: "~ eb4@3 ~ f4@2 ~@2 c4 ~@11 bb3@4 c4 ~ eb4@2 c4 ~ f4", N: "~ c4 ~ eb4@6 ~@16 bb3 ~ c4 ~ eb4@2 ~",
  O: "[~ f4@2 ~@2 g4 ~ f4 ~@3 eb4@5 ~ c4 ~@3 g4 ~@3 g4 ~@3 g4 ~ g4@2 ~@2 f4@3 ~ eb4@2 ~@16 bb3 ~ c4 ~ eb4@3]/2",
  P: "~ f4@2 ~@2 eb4@2 ~@2 c4 ~@3 g4@4 f4 ~@7 c4@4 eb4 ~ eb4",
  Q: "[f4@4 ~ g4 ~ f4@5 ~ eb4 ~ c4@6 bb3 ~ c4@5 ~ eb4 ~ f4@6 g4 ~ f4@6 eb4@2 c4@4 ~@12 g4@5 ~@15 bb3@2 c4 ~ c4 ~ eb4@2 ~@2 eb4@2 ~, e4 ~@95]/3",
  R: "[~ f4@2 ~@2 eb4@6 ~@14 c4@3 ~ eb4 ~ f4@5 ~ g4 ~ f4@6 eb4 ~ c4@5 ~ bb3 ~ c4 ~@3 eb4 ~@4]/2",
  S: "[~ f4@3 ~ g4 ~ f4@5 ~ eb4@10 ~@2 bb3@4 c4 ~ eb4@6 c4 ~ eb4@4 c4 ~ eb4@2 c4 ~ eb4@3 ~ c4@2 ~@2 bb3@4 c4 ~ eb4@5 c4 ~ eb4@4 ~ c4 ~ eb4@2 c4 ~ f4@3 ~ g4@3 ~ f4@3 ~ eb4@6 ~@18 bb3@4 c4 ~ bb3 ~ eb4@3]/4",
  T: "~ f4 ~ c4 ~ eb4@11 ~@16", U: "~@20 bb3@2 c4 ~ c4 ~ eb4@2 ~@2 eb4@2", V: "~@2 f4@2 ~@2 eb4@6 ~@14 c4@4 eb4 ~",
  W: "f4@5 ~ g4 ~ f4@6 eb4 c4@6 ~ bb3 c4 ~@4 eb4 ~@3", X: "~@2 f4@3 ~ g4 ~ f4@6 eb4@10 ~@2 bb3@4 c4 ~",
  Y: "eb4@6 c4 ~ eb4@4 c4 ~ eb4@2 c4 ~ eb4@3 ~ c4@2 ~@2 bb3@3 ~ c4 ~",
  Z: "[eb4@5 c4 ~ eb4@4 ~ c4 ~ eb4@2 c4 ~ f4@3 g4@3 ~@2 f4@3 ~ eb4@6 ~@18 bb3@3 ~ c4 ~ bb3 ~ eb4@2]/2",
  AA: "~@2 f4 ~ c4 ~ eb4@11 ~@15",
})).s("gm_piano").gain(0.45)

// other · acoustic guitar nylon
const acoustic_guitar_nylon = note(`<
  ~@23 A B C D E F G H I ~@15 J K L M N O P Q R ~@7 S T U V W X Y Z AA ~
>`.pickRestart({
  A: "~@20 c4@4 eb4@2 c4 ~ eb4@3 ~", B: "f4@3 ~ g4@3 ~@13 c4@4 eb4@2 c4 ~ eb4@3 ~",
  C: "f4@2 ~@2 eb4@7 ~@9 c4@4 eb4@2 c4 ~ eb4@2 ~@2", D: "f4@4 g4@3 ~@13 c4@4 eb4@2 c4 ~ eb4@2 ~@2",
  E: "f4@2 ~@2 g4 ~ f4 ~@3 eb4@5 ~ c4 ~@3 c4@4 eb4@2 c4 ~ eb4@3 ~", F: "f4@3 ~ g4@3 ~@13 c4@4 eb4@2 c4@2 eb4 ~@3",
  G: "f4@3 ~ g4 ~ eb4@13 ~ c4@4 eb4@2 ~ c4 eb4@3 ~", H: "f4@3 ~ g4@2 ~@15 c4@3 eb4@2 c4@2 eb4@3 ~",
  I: "bb4@6 ab4 g4 ~ ab4@5 ~ g4 f4 g4@6 f4 eb4 f4@6 ~", J: "~@21 c4@4 eb4@2 c4 ~ eb4@3",
  K: "~ f4@3 ~ g4@3 ~@13 c4@4 eb4@2 c4 ~ eb4@3", L: "~ f4@2 ~@2 eb4@7 ~@9 c4@4 eb4@2 c4 ~ eb4@3",
  M: "~ f4@4 g4@3 ~@13 c4@4 eb4@2 c4 ~ eb4@2 ~", N: "~ f4@2 ~@2 g4 ~ f4 ~@3 eb4@5 ~ c4 ~@3 c4@4 eb4@2 c4 ~ eb4@3",
  O: "~ f4@3 ~ g4@3 ~@13 c4@4 eb4@2 c4@2 eb4 ~@2", P: "~ f4@3 ~ g4 ~ eb4@13 ~ c4@3 ~ eb4@2 ~ c4 eb4@3",
  Q: "~ f4@3 ~ g4@2 ~@15 c4@3 eb4@2 c4@2 eb4@3", R: "~ bb4@6 ab4 g4 ab4@5 ~ g4 f4 g4@6 ~ f4 eb4 f4@6",
  S: "~@22 c4@4 eb4@2 c4 ~ eb4@2", T: "~@2 f4@3 ~ g4@3 ~@13 c4@4 eb4@2 c4 ~ eb4@2",
  U: "~@2 f4@2 ~@2 eb4@7 ~@9 c4@4 eb4@2 c4 ~ eb4@2", V: "~@2 f4@4 g4@3 ~@13 c4@4 eb4@2 c4 ~ eb4@2",
  W: "~@2 f4@2 ~@2 g4 ~ f4 ~@3 eb4@5 ~ c4 ~@3 c4@4 eb4@2 c4 ~ eb4@2", X: "~@2 f4@3 ~ g4@3 ~@13 c4@4 eb4@2 c4@2 eb4 ~",
  Y: "~@2 f4@3 ~ g4 ~ eb4@13 ~ c4@4 eb4@2 ~ c4 eb4@2", Z: "~@2 f4@3 ~ g4@2 ~@15 c4@3 eb4@2 c4@2 eb4@2",
  AA: "~@2 bb4@6 ab4 g4 ab4@5 ~ g4 f4 g4@6 f4 eb4 f4@6",
})).s("gm_acoustic_guitar_nylon").gain(0.45)

// chords · acoustic guitar steel
const acoustic_guitar_steel = note(`<
  ~@15 A@2 ~@4 B C D E F G H I J K L ~@7 M@2 ~@4 N O P Q R S T U V W X Y ~@4 Z AA AB@4 AC AD AE@2 AF ~
>`.pickRestart({
  A: "[~@28 [g4,bb4,g5,bb5] ~ [g4,bb4,g5,bb5]@5 ~ [f4,ab4,f5,ab5] ~ [f4,ab4,f5,ab5]@4 ~@2 [eb4,g4,eb5,g5] ~ [eb4,g4,eb5,g5]@3 ~@15]/2", // Gm Fm Eb
  B: "~@24 [g4,bb4] ~ [g4,bb4] ~ [g4,bb4]@3 ~", C: "[ab4,c5]@3 ~ [bb4,eb5]@3 ~ [ab4,c5]@3 ~ [g4,bb4]@3 ~@17, gb4 ~@31",
  D: "~@20 [c4,bb4]@4 [eb4,bb4]@2 c4 ~ [eb4,bb4]@4", // C7 Eb5
  E: "[f4,bb4]@3 ~ [g4,c5]@3 ~@13 [c4,g4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@4", // Bb5 C5 Eb5
  F: "[f4,c5]@3 ~ [g4,c5]@2 [f4,bb4]@5 ~@9 [c4,g4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@4", // F5 C5 Bb5 C5 Eb5
  G: "[f4,bb4]@3 ~ [g4,c5]@2 ~@14 [c4,bb4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@3 ~", // Bb5 C5 C7 Eb5
  H: "~@8 [eb4,bb4]@2 ~@2 [eb4,bb4]@2 ~@6 [c4,d4,bb4]@3 ~ [eb4,bb4]@2 ~@2 [eb4,bb4]@3 ~", // Eb5 Gm Eb5
  I: "[f4,bb4]@4 [g4,c5]@3 ~@13 [c4,bb4]@4 [eb4,bb4]@2 ~@2 [eb4,bb4]@4", // Bb5 C5 C7 Eb5
  J: "[f4,bb4]@4 [g4,c5]@2 [f4,bb4]@5 ~@9 [c4,bb4]@4 [eb4,bb4]@2 ~@2 [eb4,bb4]@4", // Bb5 C5 Bb5 C7 Eb5
  K: "[f4,bb4]@4 [g4,c5]@3 ~@17 [eb4,bb4]@2 c4@2 [eb4,bb4]@3 ~", L: "[f4,bb4]@3 ~@3 f4@8 ~@18",
  M: "[~@29 [g4,bb4,g5,bb5] ~ [bb4,g5,bb5]@5 ~ [f4,ab4,f5,ab5] ~ [f4,ab4,f5,ab5]@4 ~@2 [eb4,g4,eb5,g5] ~ [eb4,g4,eb5,g5]@3 ~@14]/2", // Gm Eb Fm Eb
  N: "~@25 [g4,bb4] ~ [g4,bb4] ~ [g4,bb4]@3", // Gm
  O: "~ [ab4,c5]@3 ~ [bb4,eb5]@3 ~ [ab4,c5]@3 ~ [g4,bb4]@3 ~@16, ~ gb4 ~@30", // Ab Eb5 Ab Gm
  P: "~@21 [c4,bb4]@4 [eb4,bb4]@2 c4 ~ [eb4,bb4]@3", // C7 Eb5
  Q: "~ [f4,bb4]@3 ~ [g4,c5]@3 ~@13 [c4,g4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@3", // Bb5 C5 Eb5
  R: "~ [f4,c5]@3 ~ [g4,c5]@2 [f4,bb4]@5 ~@9 [c4,g4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@3", // F5 C5 Bb5 C5 Eb5
  S: "~ [f4,bb4]@3 ~ [g4,c5]@2 ~@14 [c4,bb4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@3", // Bb5 C5 C7 Eb5
  T: "~@9 [eb4,bb4]@2 ~@2 [eb4,bb4]@2 ~@6 [c4,d4,bb4]@3 ~ [eb4,bb4]@2 ~@2 [eb4,bb4]@3", // Eb5 Gm Eb5
  U: "~ [f4,bb4]@4 [g4,c5]@3 ~@13 [c4,bb4]@4 [eb4,bb4]@2 ~@2 [eb4,bb4]@3", // Bb5 C5 C7 Eb5
  V: "~ [f4,bb4]@4 [g4,c5]@2 [f4,bb4]@5 ~@9 [c4,bb4]@4 [eb4,bb4]@2 ~@2 [eb4,bb4]@3", // Bb5 C5 Bb5 C7 Eb5
  W: "~ [f4,bb4]@4 [g4,c5]@3 ~@17 [eb4,bb4]@2 c4@2 [eb4,bb4]@3", X: "~ [f4,bb4]@3 ~@3 f4@8 ~@15 [g4,bb4,g5,bb5] ~",
  Y: "[bb4,g5,bb5]@5 ~ [f4,ab4,f5,ab5] ~ [f4,ab4,f5,ab5]@4 ~@2 [eb4,g4,eb5,g5] ~ [eb4,g4,eb5,g5]@3 ~@13", // Eb Fm Eb
  Z: "~@26 [g4,bb4] ~ [g4,bb4] ~ [g4,bb4]@2", // Gm
  AA: "~@2 [ab4,c5]@3 ~ [bb4,eb5]@3 ~ [ab4,c5]@3 ~ [g4,bb4]@3 ~@15, ~@2 gb4 ~@29", // Ab Eb5 Ab Gm
  AB: "[~@22 [c4,bb4]@4 [eb4,bb4]@2 c4 ~ [eb4,bb4]@4 [f4,bb4]@3 ~ [g4,c5]@3 ~@13 [c4,g4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@4 [f4,c5]@3 ~ [g4,c5]@2 [f4,bb4]@5 ~@9 [c4,g4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@4 [f4,bb4]@3 ~ [g4,c5]@2 ~@14 [c4,bb4]@3 ~ [eb4,bb4]@2 c4 ~ [eb4,bb4]@2]/4", // C7 Eb5 Bb5 C5 Eb5 F5 C5 Bb5 …
  AC: "~@10 [eb4,bb4]@2 ~@2 [eb4,bb4]@2 ~@6 [c4,d4,bb4]@3 ~ [eb4,bb4]@2 ~@2 [eb4,bb4]@2", // Eb5 Gm Eb5
  AD: "~@2 [f4,bb4]@4 [g4,c5]@3 ~@13 [c4,bb4]@4 [eb4,bb4]@2 ~@2 [eb4,bb4]@2", // Bb5 C5 C7 Eb5
  AE: "[~@2 [f4,bb4]@4 [g4,c5]@2 [f4,bb4]@5 ~@9 [c4,bb4]@4 [eb4,bb4]@2 ~@2 [eb4,bb4]@4 [f4,bb4]@4 [g4,c5]@3 ~@17 [eb4,bb4]@2 c4@2 [eb4,bb4]@2]/2", // Bb5 C5 Bb5 C7 Eb5 Bb5 C5 Eb5
  AF: "~@2 [f4,bb4]@3 ~@3 f4@8 ~@16", // Bb5
})).s("gm_acoustic_guitar_steel").gain(0.45)

// drums · kick
const kick = s("bd").struct(`<
  A B A B A B A C A B A B A B A C A B A B A B A C A B A B A B A D E F E F E F E G E F E F E F E G E F E F E F E H I J I
  J I J I K I J I J I J I K ~
>`.pickRestart({
  A: "x ~@2 x ~@3 x", B: "x ~@2 x ~@4", C: "x ~ x!3 ~ x ~", D: "x ~@8 x ~@3 x ~@3 x ~@7 x ~@6",
  E: "~ x ~@11 x ~@15 x ~@2", F: "~ x ~@11 x ~@18", G: "~ x ~@7 x ~@3 x ~@3 x ~@7 x ~@6",
  H: "~ x ~@7 x ~@3 x ~@3 x ~@8 x ~@5", I: "~ x ~@5 x ~@7 x", J: "~ x ~@5 x ~@8", K: "~ x ~@3 x ~ x ~ x ~@3 x ~@2",
})).gain(0.35)

// drums · rim
const rim = s("rim").struct("<~@7 A ~@7 A ~@7 A ~@7 B ~@7 C ~@7 C ~@7 D E ~@6 F E ~@6 F E>".pickRestart({
  A: "~@3 x ~@3 x ~@3 x ~@3 x", B: "~@6 x ~@8 x ~@7 x ~@7 x", C: "~@7 x ~@7 x ~@7 x ~@7 x", D: "~@7 x ~@7 x ~@8 x ~@7",
  E: "x", F: "~ x!3",
})).gain(0.5)

// drums · clap
const clap = s("cp").struct("<[~ x ~@2]!31 [~@9 x ~@22]!25 [~@5 x ~@10]!16 ~>").gain(0.45)

// drums · snare
const snare = s("sd").struct("<[~ x ~ x]!31 [~@9 x ~@15 x ~@6]!24 [~@9 x ~@16 x ~@5] [~@5 x ~@7 x ~@2]!16 ~>")
  .gain(0.45)

// drums · hihat
const hihat = s("hh").struct(`<
  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 C D C D C D C D C D C D C D C D C D C D C D C D E F G F
  G F G F G F G F G F G F G ~
>`.pickRestart({
  A: "~@3 x!2 ~@3", B: "~@4 x!4", C: "~@17 x ~@3 x ~@3 x ~@3 x ~@2", D: "~@13 x ~@3 x ~@14",
  E: "~@17 x ~@3 x ~@4 x ~@3 x ~", F: "~@7 x ~ x ~@6", G: "~@9 x ~ x ~ x ~ x",
})).gain(0.45)

// drums · hihat · soft notes
const hihat_soft = s("hh").struct("<[~ x ~@6]!32 [~@5 x ~@26]!24 [~@3 x ~@12]!16 ~>").gain(0.3)

// drums · open hat
const open_hat = s("oh").struct("<x!32 [~ x ~@30]!24 [~ x ~@14]!16 ~>").gain(0.5)

// drums · cabasa
const cabasa = s("cabasa:4").struct(`<
  A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ A ~ B ~ B ~ B ~ B ~ B ~ B ~ B ~ B ~ B ~ B ~ B ~ B ~ C ~ C
  ~ C ~ C ~ C ~ C ~ C ~ C ~@2
>`.pickRestart({
  A: "~@8 x!3 ~@5", B: "~@17 x ~ x ~ x ~@10", C: "~@9 x!3 ~@4",
})).gain(1.76)

// drums · shaker
const shaker = s("sh").struct(`<
  [x!8]!31
  [x ~@3 x ~@4 x ~@3 x ~@3 x ~@3 x ~@3 x ~@3 x ~@2]
  [~ x ~@3 x ~@3 x ~@3 x ~@3 x ~@3 x ~@3 x ~@3 x ~@2]!23
  [~ x ~@3 x ~@3 x ~@3 x ~@3 x ~@3 x ~@4 x ~@3 x ~]
  [~ x ~ x ~ x ~ x ~ x ~ x ~ x ~ x]!16
  ~
>`).gain(0.45)

stack(
  bass, piano, acoustic_guitar_nylon, acoustic_guitar_steel, kick, rim, clap, snare, hihat, hihat_soft, open_hat,
  cabasa, shaker
)

More by Blackstreet