Strudelify

Can't Let Go

Originally

KeyG majorTempo170 bpm
0:00/0:00
// Can't Let Go — Originally
// 170 bpm, 4/4, key G major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: duplicate parts dropped: ch 4 "Poly Synthesizer" pad poly (copy of ch 2 "Electric Piano" epiano1)
// note: Transcription provider: pdmx. https://musescore.com/score/781156; license: https://creativecommons.org/publicdomain/zero/1.0/
// note: Full arrangement: all 50 bars on a 16-step grid, each part at one level. Source detail keeps the original performance.
setcpm(170/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 · piano
const piano = note(`<
  A B C@2 D B E@2 F B C@2 D B G@2 ~ H I J K H I J K H I J K H I J L F B C@2 M B N O F B C@2 M B N O P
>`.pickRestart({
  A: "e4!2 g4!2, [e2,e3]@15 ~", B: "g4 d4@2 d4@2 c4 ~ c4, [d2,d3]@3 [d2,d3]@3 [a2,a3]@2",
  C: "[c4@2 c4@2 e4@2 e4 ~@2 d4@2 d4@2 d4 g4 f#4, [c2,c3]@7 e4@2 ~@7, ~@8 [d2,d3]@3 [d2,d3]@3 [g2,g3]@2]/2", // C D G
  D: "e4@2 e4@2 g4@2 g4!2, [e2,e3]@11 ~ [g2,g3]@4", // E G
  E: "[c4@2 c4@2 e4@2 e4 ~@2 d4@2 d4@2 a4 g4 f#4, [c2,c3]@7 e4@2 ~@7, ~@8 [d2,d3]@3 [d2,d3]@3 [g2,g3]@2]/2", // C D G
  F: "e4!2 g4 [g2,g3,g4], [e2,e3]@11 ~@5", // G E
  G: "[c4@4 c4@4 e4@4 e4@2 ~@4 d4@4 d4@4 a4@2 [g2,g3,g4]@2 f#4 ~, [c2,c3]@7 e4@2 ~@7, ~@8 [d2,d3]@3 [d2,d3]@3 ~@2]/2", // G C D
  H: "e3!3 g3", I: "d3@3 d3@3 a3@2", J: "c3!4", K: "d3@3 d3@3 g3@2", L: "d3@3 d4@3 g3@2",
  M: "e4@2 e4 f#4 g4@2 g4!2, [e2,e3]@11 ~ [g2,g3]@4", N: "c4!2 e4!2, [c2,c3]@15 ~",
  O: "e4 d4@2 d4@2 a4 [g2,g3,g4] f#4, [d2,d3]@3 [d2,d3]@3 ~@2", P: "[e2,e3,e4]@15 ~",
})).s("gm_piano").gain(0.4)

// other · epiano1 · "Electric Piano"
const epiano1 = note("<~@33 A B C@2 D B E F A B C@2 D B E F G>".pickRestart({
  A: "e4!2 g4!2", B: "g4 d4@2 d4@2 c4 a3 c4", C: "[c4@2 c4@2 e4@2 e4 e4@2 d4@2 d4@2 d4 g4 f#4]/2",
  D: "e4@2 e4 f#4 g4@2 g4!2", E: "c4!2 e4!2", F: "e4 d4@2 d4@2 a4 g4 f#4", G: "e4",
})).s("gm_epiano1").gain(0.45)

// other · pad sweep · "Sweep Synthesizer"
const pad_sweep = note("<A B C B A B C B A B C B A B C D ~@17 E F G F E F G F E F G F E F G F A>".pickRestart({
  A: "[e2,e3]", B: "[d2,d3]", C: "[c2,c3]", D: "[d2,d3]@7 ~", E: "[e2,e3,e4]", F: "[d2,d3,d4]", G: "[c2,c3,c4]",
})).s("gm_pad_sweep").gain(0.25)

// other · pad halo · "Halo Synthesizer"
const pad_halo = note("<~@33 A B C B A B C B A B C B A B C B A>".pickRestart({
  A: "[e2,e3]", B: "[d2,d3]", C: "[c2,c3]",
})).s("gm_pad_halo").gain(0.25)

// drums · kick
const kick = s("bd").struct("<~@8 [x!4]!8 [x ~@2 x ~@2 x ~] [x!4]!14 ~@2 [x!4]!16 ~>").gain(0.5)

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

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

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

stack(piano, epiano1, pad_sweep, pad_halo, kick, snare, hihat, crash)