Strudelify
Cantaloop cover art

1993 · Hand On The Torch

Cantaloop

Us3

KeyF minorTempo117 bpm
0:00/0:00
// Cantaloop — Us3
// 117 bpm, 4/4, key F minor. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: Full arrangement: all 123 bars on a 16-step grid, each part at one level. Source detail keeps the original performance.
setcpm(117/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, A@4 for four bars: edit a riff to change every repeat.

// chords · piano · "Right Hand"
const piano = note(`<
  A@7 ~ A@4 B@4 ~@5 A ~@3 A ~ A ~@2 A@4 B@4 A@7 ~@9 A@4 B@4 A@4 B@4 ~@3 A ~@3 A ~ A ~@2 A@4 B@4 A@4 B@4 A@4 B@4 A@4 B@4
  A@4 B@4 ~
>`.pickRestart({
  A: "~@2 [ab3,c4]@2 [bb3,d4] ~@3 [c4,eb4]@4 [bb3,d4]@2 [ab3,c4] ~", // Ab Bb Cm Bb Ab
  B: "~@2 [ab3,b3]@2 [bb3,db4] ~@3 [b3,eb4]@4 [bb3,db4]@2 [ab3,b3] ~", // Abm Bbm B Bbm Abm
})).s("gm_piano").gain(0.3)

// bass · fretless bass · "Bass"
const bass = note(`<
  A@2 B@5 ~ A B@3 C@4 ~@2 A B@3 A B@3 A B@2 ~ A B@3 C@4 A B@3 A B@2 ~ A B A B A B A ~ A B@3 C@4 A B@3 C@4 A B@3 A B@3 A
  B@2 ~ A B@3 C@4 A B@3 C@4 A B@3 C@4 A B@3 C@4 A B@3 C@4 ~
>`.pickRestart({
  A: "f1@4 ~@2 c1@5 ~ eb1@2 f1 ~", B: "f1@5 ~ c1@5 ~ eb1@2 f1 ~", C: "db1@5 ~ ab1@5 ~ b1@2 db2 ~",
})).s("gm_fretless_bass").gain(0.57)

// chords · trumpet
const trumpet = note(`<
  ~@7 A B@2 C D E@2 F@2 G ~@8 A ~@4 H ~ H ~ I@3 ~@10 J ~ K ~ J ~ L H ~ H ~ I@3 ~ H ~ H ~ I@3 ~@12 A B@2 C D E@2 M@2 ~@8
  H ~ H ~ I@3 ~@18
>`.pickRestart({
  A: "~@6 f4!2", B: "[~@6 f4 ~ ab4@2 bb4 ~ bb4@10 ab4 ~ bb4@2 ~ c5@2 ~ eb4@2]/2", C: "f4@5 ~ f4@9 ~", D: "~@6 f4 f5",
  E: "[~@6 f4 ~ ab4@2 bb4@2 ~ bb4@9 ab4 ~ bb4@3 b4@3 eb4@2]/2", F: "[f4@5 ~ f4@17 ~ c5@2 eb5 ~ c5@2 eb5 ~]/2",
  G: "f4 ~@7", H: "~@2 [f4,c5] ~@2 [f4,c5] ~@2 [f4,c5]@2 [ab4,eb5]@2 ~@4", I: "~@6 [db5,f5,ab5,f6]@3 ~@7",
  J: "~@4 [c3,c4]@3 [eb3,eb4] [f3,f4]@2 ~ [eb3,eb4] [c3,c4]@2 ~@2", // C Eb F Eb C
  K: "~@4 [f3,f4]@3 [ab3,ab4] [bb3,bb4]@2 ~ [ab3,ab4] [f3,f4]@2 ~@2", // F Ab Bb Ab F
  L: "~@4 [c4,c5,c6]@3 [eb4,eb5,eb6] [f4,f5,f6]@2 ~ [eb4,eb5,eb6] [c4,c5,c6]@2 ~@2", // C Eb F Eb C
  M: "[f4@5 ~@11 f4@7 ~@9, ~@6 f4@17 ~@9]/2",
})).s("gm_trumpet").gain(0.4)

// chords · tenor sax · "Saxes"
const tenor_sax = note("<~@31 A ~ A B@3 ~@10 C ~ D ~ C ~ E ~ A ~ A B@3 ~@2 A ~ A B@3 ~@30 A ~ A B@3 ~@18>".pickRestart({
  A: "~@2 [f3,c4] ~@2 [f3,c4] ~@2 [f3,c4]@2 [ab3,eb4]@2 ~@4", B: "~@6 [f3,db4,ab4]@3 ~@7",
  C: "~@4 [c3,c4]@3 [eb3,eb4] [f3,f4]@3 [eb3,eb4] [c3,c4]@2 ~@2", // C Eb F Eb C
  D: "~@4 [f3,f4]@3 [ab3,ab4] [bb3,bb4]@3 [ab3,ab4] [f3,f4]@2 ~@2", // F Ab Bb Ab F
  E: "~@4 [c4,c5]@2 ~ eb5 [f4,f5]@2 ~ [eb4,eb5] [c4,c5]@2 ~@2, ~@7 eb4@2 ~@7", // C F Eb C
})).s("gm_tenor_sax").gain(0.4)

// chords · electric guitar jazz · "Jazz Guitar"
const electric_guitar_jazz = note("<~@12 A@3 ~@19 A@3 ~@21 A@2 B@6 C D@2 ~@54>".pickRestart({
  A: "[db4,f4] ~ [bb4,db5,eb5] ~@5", B: "[~@2 [bb4,db5,eb5] ~@45, [db4,f4]]/6", C: "~@2 [bb4,db5,eb5] ~@5, [db4,f4]",
  D: "[~@2 [bb4,db5,eb5] ~@7 [bb4,db5,eb5] ~@5, [db4,f4]@9 ~@7]/2", // Eb7 Db
})).s("gm_electric_guitar_jazz").gain(0.25)

// drums · kick
const kick = s("bd").struct("<A@7 B A@21 C A@23 ~ A@27 C A@40 ~>".pickRestart({
  A: "x ~@2 x ~ x ~ x", B: "x", C: "x ~@6 x ~@2 x ~@3 x ~",
})).gain(0.45)

// drums · snare
const snare = s("sd").struct("<[~ x ~ x]!7 ~ [~ x ~ x]!45 ~ [~ x ~ x]!68 ~>").gain(0.4)

// drums · open hat
const open_hat = s("oh").struct("<~@29 [x!8] ~@51 [x!8] ~@41>").gain(0.4)

// drums · ride
const ride = s("rd").struct("<A@7 ~ A@8 ~@2 A@11 ~ A@16 ~@8 A@27 ~ A@40 ~>".pickRestart({
  A: "x!8",
})).gain(0.35)

// drums · bongos
const bongos = s("bongo:18").struct("<~@29 A ~@16 B C B C B C B ~@28 A ~@41>".pickRestart({
  A: "~@4 x ~@4 x ~ x ~ x ~ x", B: "~ x!2 ~@5", C: "~@2 x ~ x!2 ~ x ~@8",
})).gain(1.04)

// drums · congas
const congas = s("conga:18").struct("<~@29 A ~@16 B C@2 D B C@2 ~@28 A ~@41>".pickRestart({
  A: "~@2 x ~@4 x ~@8", B: "~@7 x ~ x!2 ~@5", C: "~@6 x!2", D: "~@11 x!2 ~ x ~",
})).gain(1.27)

// drums · cabasa
const cabasa = s("cabasa:4").struct("<A@16 ~@2 A@11 ~ A@16 ~@4 A@3 ~ A@27 ~ A@40 ~>".pickRestart({
  A: "x!16",
})).gain(2.01)

stack(piano, bass, trumpet, tenor_sax, electric_guitar_jazz, kick, snare, open_hat, ride, bongos, congas, cabasa)