Strudelify

That's the Way Love Goes

Janet Jackson

KeyG minorTempo147 bpm
0:00/0:00
// That's the Way Love Goes — Janet Jackson
// 147 bpm, 4/4, key G minor. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: pitch bends are ignored
// note: duplicate parts dropped: ch 13 "Funk Gtr." electric guitar muted (copy of ch 1 "Acco. Bass" acoustic bass)
// note: Full arrangement: all 162 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(147/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 · acoustic bass · "Acco. Bass"
const bass = note(`<
  ~@8 A@2 B ~@4 C B ~@4 D E@3 F@2 D E@3 F@2 D E@3 F@2 D E@3 F@2 D E@3 F@2 G@3 H I J@2 K@2 L M@3 E@3 F@2 D E@3 F@2 D E@3
  F@2 D E@3 F@2 D E@3 F@2 G@3 H I N@2 K@2 L M@3 E@3 O@2 D E@3 P@2 D E@3 P@2 D E@3 P@2 D E@3 P@2 Q@4 R@3 S@3 T ~ D E@3
  P@2 ~@9
>`.pickRestart({
  A: "[~@6 eb2@6 d2@6 bb1@3 g1@2 ~ bb1@3 g1@2 gb1 g1@2]/2", B: "bb1 g1@2 ~@13",
  C: "~@2 bb1@3 g1@2 ~ bb1@3 g1@2 gb1 g1@2", D: "~@2 eb1@9 eb1@2 eb1 bb1 ~",
  E: "[~ bb1 ~@2 eb1@3 bb1 ~@2 f1@9 f1@2 f1 c2 ~@2 c2 ~@2 c2 ~@2 f1@3 g1@9 g1@2 g1 d2 ~]/3",
  F: "[~ d2 ~@2 d2 ~@2 d2 ~@2 g1@9 g1@2 g1 d2 ~@2 d2 ~@2 g1@3 d2]/2",
  G: "[~@2 eb1@8 ~ eb1@2 ~ bb0@6 eb1@5 ~ f1@9 f1@3 c1@6 f1@4]/3", H: "~@2 g1@9 g1@2 g1 d1@2",
  I: "~ d1@3 ~@3 g1@2 ~ d2@6", J: "[~@3 g1@2 g1 g1@2 ~ g1@2 ~ d2 ~@2 g1@3 bb1@7 ~@2 bb1 ~ bb1 f1@2]/2",
  K: "[~ f1@2 ~ bb1 ~@2 f1@3 a1@9 f1@2 a1 f1@2 ~ g1@2 ~ a1@3 bb1]/2", L: "~@2 ab1@9 ab1@2 ab1 ab1@2",
  M: "[~ ab1@2 ~ ab1@3 ab1@2 ~ g1@9 g1@2 g1 g1@2 ~ g1@2 ~ f1@3 f1@3 eb1@9 eb1@2 eb1 bb1 ~]/3",
  N: "[~@3 g1@2 g1 g1@2 ~ g1@2 ~ d2 ~@2 g1@3 bb1@8 ~ bb1 ~ bb1 f1@2]/2",
  O: "[~ d2 ~@2 g1@3 d2 ~@2 f1@9 f1@2 f1 c2 ~@2 c2 ~@2 f1@3 c2]/2",
  P: "[~ d2 ~@2 g1@2 ~ d2 ~@2 f1@9 f1@2 f1 c2 ~@2 c2 ~@2 f1@3 c2]/2",
  Q: "[~@2 eb1@8 ~ eb1@3 bb1@6 eb1@3 bb1@3 f1@8 ~ f1@3 c2@5 ~ f1@2 ~ gb1@3 g1@11 ~ d1@2]/4",
  R: "[~ d1@5 ~ g1@3 f1@8 ~ f1@3 c2@3 f1@3 c2@3 f1@3 eb1@2 ~ eb1@6 eb1@3 bb1@2]/3",
  S: "[~ bb1@3 eb1@3 bb1@3 f1@8 ~ f1@3 c2@2 ~ c2@3 f1@3 c2@3 g1@8 ~ g1@3 d2@2]/3", T: "~ d2@3 g1@3 d2@3 ~@6",
})).s("gm_acoustic_bass").gain(0.63)

// other · piano · "Piano 3"
const piano = note(`<
  ~@3
  [~@7 g6]
  [~@3 d6@2 ~@2 c6@2 ~@3 bb5@2 ~@2]
  [a5@2 ~@3 f5@2 ~@2 c5@2 ~@3 bb4@2]
  [~@2 a4@2 ~@3 f4@2 ~@2 c4@2 ~@3]
  ~@155
>`).s("gm_piano").gain(0.24).pan(1)

// other · piano · "Piano 3" · soft notes
const piano_soft = note("<~@7 [bb3@2 ~@2 a3@2 ~@3 f3@2 ~@2 c3@2 ~] [~ bb2 ~@6] ~@153>").s("gm_piano").gain(0.12).pan(1)

// other · celesta · "Piano 3"
const celesta = note(`<
  ~@25 A B@3 C ~@7 A B@3 C ~@14 D@6 E@2 ~@22 F@2 G@4 ~@6 D@6 E@2 ~@10 H@4 ~@28 I@2 ~@12
>`.pickRestart({
  A: "~@5 c6@3", B: "[~@6 d6@6 f6@6 ~@12 d6@7 ~@11]/3", C: "c6@7 ~@9",
  D: "[~ [f3,f4,f5] [g3,g4,g5] [bb3,bb4,bb5]@4 [c4,c5,c6]@4 [d4,d5,d6]@4 [g4,g5]]/6", // F G Bb C D G
  E: "[[f4,f5]@3 [eb4,eb5]@3 [d4,d5]@3 ~@7]/2", F: "[~@8 g4 ~@2 [g3,g4] bb4@2 ~ c5@2 ~ db5 d5@6 ~@7]/2",
  G: "[~@2 g5@3 c5@8 ~ f5@3 bb4@8 ~@7]/4", H: "[~@3 [d5,d6]@3 [f5,f6]@3 [g5,g6]@17 ~@6]/4",
  I: "[~@3 d6 g6@6 c6@19 ~@3]/2",
})).s("gm_celesta").gain(0.15).pan(0.7)

// other · celesta · "Piano 3" · soft notes
const celesta_soft = note("<~@26 A ~@11 A ~@47 B@2 C@4 ~@43 D@8 ~@5 E@2 ~@2 F@2 G ~@7>".pickRestart({
  A: "bb5@3 ~@5", B: "[~@8 g3 ~@3 bb3@2 ~ c4@2 ~ db4 d4@6 ~@7]/2", C: "[~@2 g4@3 c4@8 ~ f4@3 bb3@8 ~@7]/4",
  D: "[~ bb5@63]/8", E: "[~@3 d5 g5@6 c5@19 ~@3]/2", F: "[~@3 bb6@3 [a5,a6]@3 [f5,f6]@3 [c6,c7]@3 [g5,g6]@3 ~@14]/2",
  G: "~@5 [d5,d6]@2 ~", // D
})).s("gm_celesta").gain(0.07).pan(0.7)

// other · epiano1 · "Piano 3"
const epiano1 = note("<~@135 A B@2 C@3 D@6 ~@15>".pickRestart({
  A: "~@2 bb6@5 [a5,a6]@4 [f5,f6]@5", // A F
  B: "[~@10 [d6,d7]@5 [bb5,bb6]@4 [a5,a6]@5 ~@4 [c5,c6]@4, [c5,c6]@6 ~@6 [f5,f6]@3 ~]/2", // D Bb A C F
  C: "[~@2 [f6,f7]@24 [g6,g7]@9 ~@9 [c6,c7]@3 [g5,g6], ~@35 [bb5,bb6]@6 [f5,f6]@6 ~, ~@19 [a5,a6]@3 ~@2]/3", // F G C G Bb F A
  D: "[~ [b5,c6]@47]/6", // Cmaj7
})).s("gm_epiano1").gain(0.1).pan(0.7)

// chords · pad warm · "Warm Pad"
const pad_warm = note("<~@3 A@6 B@12 C@36 D@6 C@36 D@6 E@30 F@7 ~@5 G@6 H@5 ~@4>".pickRestart({
  A: "[~@14 [g4,bb4,d5,f5]@77 ~@5]/6", B: "[~ [g4,bb4,d5]@12 [a4,c5,d5]@12 [g4,bb4,d5]@23]/6",
  C: "[~ [g4,bb4,d5]@12 [a4,c5,d5]@12 [f4,g4,bb4,d5]@23, ~ f4@24 ~@23]/6", // Gm D7 Gm7
  D: "[~ bb4@12 a4@12 bb4@12 b4@11, ~ [f4,d5]@24 [f4,d5]@23]/6", // Dm
  E: "[~ [g4,bb4,d5]@12 [a4,c5,d5]@12 [g4,bb4,d5]@12 [a4,c5,d5]@11, ~ f4@24 f4@23]/6", // Gm D7 Gm D7
  F: "[~ [bb4,d5]@12 [a4,d5]@12 [g4,d5]@12 [a4,d5]@12 ~@7]/7", // Bb D5 G5 D5
  G: "[~@13 [a4,c5,d5]@12 [g4,bb4,d5]@12 [a4,c5,d5]@11, ~ [g4,bb4,d5]@25 ~@70, ~ f4@24 f4@23]/6", // D7 Gm D7 Gm
  H: "[~@2 [g4,bb4,d5]@24 a4@43 ~@11, ~ f3@39, ~ f4@24 ~@15, ~@26 c5@33 ~@21, ~@13 d5@12 ~@15]/5", // Gm
})).s("gm_pad_warm").gain(0.04)

// other · string ensemble 2 · "String"
const string_ensemble_2 = note(`<
  A@8 B@7 C@12 D@6 C@6 E@7 ~@10 F@6 G@7 D@6 C@6 H@6 I@7 ~@4 F@6 G@7 D@18 C@6 J@6 K@6 L@7 ~@8
>`.pickRestart({
  A: "[~@52 g6@37 ~@2 g6@37, ~@7 d3@2 d2@2 g1@33 ~@84, ~@8 g1@2 g2@5 ~@27 g5@12 ~@74]/8",
  B: "[~@3 [f5,f6]@12 [f5,f6]@13]/7", C: "[~ [g5,g6]@21 [f5,f6]@26]/6",
  D: "[~@8 c7@3 [f6,bb6]@13, ~ [g5,g6]@21 ~@26]/6", E: "[~@32 c7@12 [f6,bb6]@53 ~@15, ~ [g5,g6]@21 ~@34]/7",
  F: "[~ [f4,f5] [g4,g5] [bb4,bb5]@4 [c5,c6]@4 [d5,d6]@4 [g5,g6]]/6", // F G Bb C D G
  G: "[[f5,f6]@3 [eb5,eb6]@3 [d5,d6]@3 [g5,g6]@21 [f5,f6]@26]/7", H: "[~ [g5,g6]@21 f6@26]/6",
  I: "[~@2 [g5,g6]@42 [f5,f6]@53 ~@15]/7", // G F
  J: "[~@2 [a5,bb5]@26 ~@3 [a5,bb5]@6 ~@48 f6@11, ~@13 [a5,bb5]@19, ~@53 g5@43, ~@23 c6@9]/6", K: "[~ [b5,c6]@47]/6",
  L: "[~ [g5,g6]@21 [f5,f6]@28 ~@6]/7", // G F
})).s("gm_string_ensemble_2").gain(0.06)

// other · string ensemble 2 · "String" · soft notes
const string_ensemble_2_soft = note(`<
  ~ A@3 ~@25 B@5 ~@7 B@5 ~@25 B@5 ~@7 B@5 ~@25 B@5 ~ B@5 ~ B@5 ~@23 C@8 ~
>`.pickRestart({
  A: "[e4@11 ~@7 g4@12 ~@18, [g2,b3]@11 ~@5]/3", B: "[~@12 f5@53 ~@15]/5", C: "[~@5 [g5,g6]@123]/8",
})).s("gm_string_ensemble_2").gain(0.03)

// chords · electric guitar muted · "Muted Gtr."
const electric_guitar_muted = note(`<
  ~@21 A B C A D C A D C E D C A D C A B C A D C E D C A D C E D C A B C A D C ~@6 A D C E B C A D C A D C E D C E D C A
  B C E D C E D C A D C A D C E B C ~@6 E D C A D C A B C E D C E D C A D C A D C E B C E D C A D C ~@4 F G ~@6 H B C I
  ~@11
>`.pickRestart({
  A: "~ [a4,d5] [f4,a4,d5]@2 ~@3 [a4,d5] ~@8", B: "~@10 d5@3 ~@3, ~@9 d4@5 ~@2", C: "[d4,d5] ~@7",
  D: "~@10 d5@3 ~@3, ~@9 d4@4 ~@3", E: "~ d5 [f4,a4,d5]@2 ~@3 [a4,d5] ~@8", F: "~@9 d4 f4@2 g4 a4 ~ f4",
  G: "g4@2 a4 bb4 ~@12", H: "~@2 [f4,a4,d5]@2 ~@3 [a4,d5] ~@8", I: "~ d5 [f4,a4]@2 ~@12",
})).s("gm_electric_guitar_muted").gain(0.3)

// chords · electric guitar muted · "Muted Gtr." · soft notes
const electric_guitar_muted_2 = note(`<
  ~@21 A ~@2 A ~@2 A ~@2 B ~@2 A ~@2 A ~@2 A ~@2 B ~@2 A ~@2 B ~@2 A ~@2 A ~@8 A ~@2 B ~@2 A ~@2 A ~@2 B ~@2 B ~@2 A ~@2
  B ~@2 B ~@2 A ~@2 A ~@2 B ~@8 B ~@2 A ~@2 A ~@2 B ~@2 B ~@2 A ~@2 A ~@2 B ~@2 B ~@2 A ~@14 C ~@2 D ~@4 E ~@6
>`.pickRestart({
  A: "~ f4 ~@5 f4 ~@8", B: "~ [f4,a4] ~@5 f4 ~@8", C: "~@7 f4 ~@8", D: "~ [f4,a4] ~@14",
  E: "~@2 f4@2 ~@4 f4@2 ~ f4@2 ~ f4@2",
})).s("gm_electric_guitar_muted").gain(0.15)

// chords · electric guitar jazz · "Jazz Gtr."
const electric_guitar_jazz = note(`<
  ~@21 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A B ~ A C ~ A ~@2 A ~@2 A ~@2 A ~@2 A ~@2
  A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A B ~ A C ~ A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@2 A ~@14 A
  ~@2 A ~@11
>`.pickRestart({
  A: "~ [f4,bb4,d5] ~@6", B: "~@5 [f4,bb4,d5] ~@2", C: "~@5 [f4,b4,d5] ~@2",
})).s("gm_electric_guitar_jazz").gain(0.4).pan(0.3)

// bass · acoustic guitar steel · "Bass Drum 2"
const bass_2 = note(`<
  ~@9 A B C A B C A B C A D ~ A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C
  A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B
  C A B C A B C A B C ~@12 A B C A B C A D ~@7
>`.pickRestart({
  A: "~@2 c2 ~@10 c2!2 ~", B: "~ c2 ~@5 c2 ~@2 c2 ~@5", C: "~@5 c2!2 ~@2 c2 ~@5 c2", D: "~ c2 ~@5 c2 ~@8",
})).s("gm_acoustic_guitar_steel").gain(0.8)

// other · distortion guitar · "Distortion Gtr."
const distortion_guitar = note("<~@75 A@6 B@6 C@6 D@7 ~@29 E@7 ~@26>".pickRestart({
  A: "[~ [d4,d5]@9 [g4,g5]@3 [c5,c6]@9 [f4,f5]@21 [d4,d5]@3 [g4,g5]@2]/6", // D G C F D G
  B: "[~@2 [d4,d5]@18 [g4,g5]@6 [c5,c6]@18 [f4,f5]@6 [bb4,bb5]@18 [a4,a5]@6 [g4,g5]@11 ~ [d4,d5]@6 [g4,g5]@4]/6", // D G C F Bb A G D …
  C: "[~ [d4,d5]@9 [g4,g5]@3 [c5,c6]@9 [f4,f5]@3 [bb4,bb5]@6 [a4,a5]@6 [g4,g5]@11]/6", // D G C F Bb A G
  D: "[~ [g4,g5]@12 [f4,f5]@12 [bb4,bb5]@6 [a4,a5]@6 [g4,g5]@12 ~@7]/7", // G F Bb A G
  E: "[~ [g4,g5]@12 [a4,a5]@12 [bb4,bb5]@12 [c5,c6]@12 ~@7]/7", // G A Bb C
})).s("gm_distortion_guitar").gain(0.18)

// other · taiko drum · "Taiko"
const taiko_drum = note("<~@9 A@6 B@7 ~@119 C ~@20>".pickRestart({
  A: "[~ c0@44 ~@3]/6", B: "[~@2 c0@95 ~@15]/7", C: "~ c0@6 ~",
})).s("gm_taiko_drum").gain(0.64)

// drums · rim
const rim = s("rim").struct("<~@20 A ~@41 A ~@72 B C D B C D B C D B C A ~@15>".pickRestart({
  A: "~@3 x", B: "~ x", C: "~ x ~@2", D: "x ~@2 x",
})).gain(0.64)

// drums · clap
const clap = s("cp").struct(`<
  ~@9 A B C A B C A B C A B D A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B E A B C
  A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B
  C A B C A B C A B C ~@12 A B C A B C A B ~@7
>`.pickRestart({
  A: "~ x", B: "~ x ~@2", C: "x ~@2 x", D: "~@3 x", E: "x",
})).gain(0.56)

// drums · snare
const snare = s("sd").struct(`<
  ~@9 A B C A B C A B C A B D A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C
  A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B
  C A B C A B C A B C ~@11 D A B C A B C A B ~@7
>`.pickRestart({
  A: "~ x", B: "~ x ~@2", C: "x ~@2 x", D: "~@3 x",
})).gain(0.64)

// drums · low tom
const low_tom = s("lt").struct("<~@74 [~@9 x ~@2 x ~@3] ~@87>").gain(0.56)

// drums · hihat
const hihat = s("hh").struct(`<
  ~@9 A B C A B C A B C A D E F B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C
  A B C A B C A B C A B C A B C A B C A B C F B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B
  C A B C A B C A B C ~@12 A B C A B C A D ~@7
>`.pickRestart({
  A: "~@2 x ~@2 x ~@2 x ~@2 x ~ x!2 ~", B: "~@4 x ~@2 x ~@2 x ~@2 x ~@2", C: "x ~@2 x ~ x!2 ~@5 x ~@2 x",
  D: "~@4 x ~@2 x ~@8", E: "~@3 x", F: "~@5 x ~@2 x ~@2 x ~ x!2 ~",
})).gain(0.64)

// drums · mid tom
const mid_tom = s("mt").struct("<~@74 [~@5 x ~@2 x ~@7] ~@87>").gain(0.4)

// drums · crash
const crash = s("cr").struct("<~@21 A ~@41 A ~@23 A ~@17 A ~@5 A ~@5 A ~@5 A ~@5 A ~@17 A ~@5 A ~@8>".pickRestart({
  A: "~ x ~@6",
})).gain(0.64)

// … 36 more lines

More by Janet Jackson