Strudelify

Streetbeats

Hans Dulfer

KeyB♭ minorTempo140 bpm
0:00/0:00
// Streetbeats — Hans Dulfer
// 140 bpm, 4/4, key A# minor. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: pitch bends are ignored
// note: Full arrangement: all 144 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
// note: Guitar parts that double another keep only their own notes (fills, solos): DISTORTION.
setcpm(140/4)

// Notation: c3@3 lasts 3 steps · ~ is a rest · [c3,e3] is a chord · "a, b" plays two voices at once.
// A part's distinct bars are riffs (A, B, C...) played in order: edit a riff to change every repeat.

// chords · alto sax
const alto_sax = note(`<
  ~@3 A B@4 C@3 D C@3 D B@7 E ~@8 B@8 C@3 D C@3 D ~@16 B@8 C@3 D C@3 D ~@16 B@8 ~@24 B@8 C@3 D C@3 F
>`.pickRestart({
  A: "~@15 ab4", B: "bb3!2 ~ bb4 ~ bb3 ~ bb3!4 ~ ab3!2 ~ ab4",
  C: "[bb2,f4] bb2 ~ [bb2,f4] ~ [bb2,f4] ~ bb2 [bb2,f4]!2 bb2 ~ [b2,gb4] ~ ab2 [ab2,eb4]", // Bb5 B5 Ab5
  D: "[bb2,f4] bb2 ~ [bb2,f4] ~ [bb2,f4] ab2 [ab2,eb4] [bb2,f4] bb2 ~ [bb2,f4] ~ [bb2,f4] ~@2", // Bb5 Ab5 Bb5
  E: "bb3!2 ~ bb4 ~ bb3 ~ bb3!4 ~@5", F: "[bb2,f4] bb2 ~ [bb2,f4] ~ [bb2,f4] ab2 ~@9",
})).s("gm_alto_sax").gain(0.72).pan(0.4)

// chords · alto sax · soft notes
const alto_sax_soft = note("<~@8 A@3 B A@3 B ~@24 A@3 B A@3 B ~@24 A@3 B A@3 B ~@56 A@3 B A@3 C>".pickRestart({
  A: "~ f4 ~@5 f4 ~@2 f4 ~@3 eb4 ~", B: "~ f4 ~@4 eb4 ~@2 f4 ~@6", C: "~ f4 ~@4 eb4 ~@9",
})).s("gm_alto_sax").gain(0.32).pan(0.4)

// bass · electric bass finger · "FINGERDBAS"
const bass = note(`<
  ~@4
  [ab1 bb1@2 ab1 bb1@2 ab1 bb1@2 db2!3 eb2!2 f2!2]!139
  [ab1 bb1@2 ab1 bb1@2 ab1 bb1@2 db2!3 eb2!2 f2 ~]
>`).s("gm_electric_bass_finger").gain(0.4)

// chords · distortion guitar · "DISTORTION" · Bb5 Emaj7 Bbmaj7 Bb5 Db5 Ebmaj7 Eb5 Bb5 …
const distortion_guitar = note(`<
  [[bb2,f3,bb3]@2 [f3,bb3]!4 [bb2,f3,bb3]@2 bb3 [f3,bb3]!3 [bb2,f3,bb3]@2 [ab2,eb3,e3,ab3,a3]@2]
  [[bb2,f3,a3,bb3]@2 [f3,bb3] ~ [f3,bb3] ~ [db3,ab3] [db3,ab3,db4]@3 [db3,ab3,db4]@2 [eb3,a3,bb3,d4,eb4]@2 [eb3,bb3,eb4]@2]
  [[bb2,f3,bb3]@2 [f3,bb3]!4 [bb2,f3,bb3]@2 bb3 [f3,bb3]!3 [bb2,f3,bb3]@2 [ab2,eb3,e3,ab3,a3]@2]
  [[bb2,f3,a3,bb3]@2 [f3,bb3] ~ [f3,bb3] ~ [db3,ab3] [db3,ab3,db4]@3 [db3,ab3,db4]@2 [eb3,a3,bb3,d4,eb4]@2 [eb3,bb3,eb4]@2]
  ~@140
>`).s("gm_distortion_guitar").gain(0.46)

// chords · distortion guitar · "DISTORTION" · soft notes
const distortion_guitar_soft = note("<[~@8 f3 ~@7] [~@5 f3 ~@5 db4 ~@4] [~@8 f3 ~@7] [~@5 f3 ~@5 db4 ~@4] ~@140>")
  .s("gm_distortion_guitar").gain(0.26)

// chords · overdriven guitar · "OVERDRIVE"
const overdriven_guitar = note(`<
  ~@4 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 B A B A B A B A B A B A B A B A B A B A B C D C E C
  D C E F G H G H G H G H G H G H G H G I B A B A B A B C D C E C D C E A B A B A B A B A B A B A B A B A B A B A B A B
  C D C E C D C E G J G J G J G J G J G J G J G K
>`.pickRestart({
  A: "[bb2,f3,bb3] [f3,bb3] [bb2,f3]@2 [bb2,f3,bb3] [f3,bb3] ~ [f3,bb3] bb2 [f3,bb3]!3 [ab2,eb3,ab3] ~ [ab2,eb3,ab3]@2, ~@3 [bb2,f3] ~@4", // Bb5 Ab5 Bb5
  B: "[bb2,f3,bb3] [f3,bb3] [bb2,f3]@2 [bb2,f3,bb3] [f3,bb3] ~ [f3,bb3] bb2 [f3,bb3]!2 [ab3,db4] [eb3,bb3,eb4]@2 [db3,ab3,db4]@2, ~@3 [bb2,f3] ~@4", // Bb5 Db5 Eb5 Db5 Bb5
  C: "[bb2,f3,bb3]@2 [f3,bb3]!4 [bb2,f3,bb3]@2 [f3,bb3]!4 [bb2,f3,bb3]@2 [ab2,eb3,e3,ab3,a3]@2", // Bb5 Emaj7
  D: "[bb2,f3,a3,bb3]@2 [f3,bb3] ~ [f3,bb3] f3 [db3,ab3] [db3,ab3,db4]@3 ~ db4 [eb3,a3,bb3,d4,eb4]@2 [eb3,bb3,eb4]@2, ~@5 [db3,ab3,db4] ~@2", // Bbmaj7 Bb5 Db5 Ebmaj7 Eb5 Db5
  E: "[bb2,f3,a3,bb3]@2 [f3,bb3] ~ [f3,bb3] f3 [db3,ab3,db4] [db3,ab3,db4]@3 ~ db4 [eb3,a3,bb3,d4,eb4]@2 [eb3,bb3,eb4]@2, ~@5 [db3,ab3,db4] ~@2", // Bbmaj7 Bb5 Db5 Ebmaj7 Eb5 Db5
  F: "[bb2,f3,bb3] [f3,bb3] [bb2,f3]@2 [bb2,f3,bb3] [f3,bb3] [ab2,eb3] [f3,bb3] bb2 [f3,bb3]!3 [b2,gb3,b3]!2 ~@2", // Bb5 Ab5 Bb5 B5
  G: "[bb2,f3,bb3] [f3,bb3] [bb2,f3]@2 [bb2,f3,bb3] [f3,bb3] [ab2,eb3] [f3,bb3] bb2 [f3,bb3]!3 [b2,gb3,b3]@2 [bb2,f3,bb3]@2", // Bb5 Ab5 Bb5 B5 Bb5
  H: "[bb2,f3,bb3] [f3,bb3] [bb2,f3] ~ [bb2,f3,bb3] [f3,bb3] [ab2,eb3] [f3,bb3] bb2 [f3,bb3]!3 [b2,gb3,b3]!2 ~@2", // Bb5 Ab5 Bb5 B5
  I: "[bb2,f3,bb3] [f3,bb3] [bb2,f3] ~ [bb2,f3,bb3] [f3,bb3] ~ [f3,bb3] bb2 [f3,bb3]!3 [ab2,eb3,ab3] ~ [ab2,eb3,ab3]@2, ~@3 [bb2,f3] ~@4", // Bb5 Ab5 Bb5
  J: "[bb2,f3,bb3] [f3,bb3] [bb2,f3] ~ [bb2,f3,bb3] [f3,bb3] [ab2,eb3] [f3,bb3] bb2 [f3,bb3]!2 [bb3,eb4] [eb3,bb3,eb4]@2 [db3,ab3,db4]@2", // Bb5 Ab5 Bb5 Eb5 Db5
  K: "[bb2,f3,bb3] [f3,bb3] [bb2,f3] ~ [bb2,f3,bb3] [f3,bb3] [ab2,eb3] [f3,bb3] bb2 [f3,bb3]!2 [bb3,eb4] [eb3,bb3,eb4]@2 [db3,ab3,db4] ~", // Bb5 Ab5 Bb5 Eb5 Db5
})).s("gm_overdriven_guitar").gain(0.3).pan(0.8)

// chords · overdriven guitar · "OVERDRIVE"
const overdriven_guitar_2 = note("<~@24 A B C D A B C D ~@112>".pickRestart({
  A: "[ab4,db5] [ab4,d5] ~@4 [db4,ab4,db5]@6 bb3 ab3 ~@2", B: "bb3 ab3 [ab3,db4]@2 [db4,f4]@2 [f4,ab4]@2 [f4,ab4]@8",
  C: "~@2 eb3@2 f3@2 db4@6 bb3 ab3 ~@2, ~@3 ab3 ~@4", D: "[db4,f4]!2 ~@2 [ab4,db5] ~@3 [g4,c5] ~@3 [f4,bb4]@2 ~@2",
})).s("gm_overdriven_guitar").gain(0.56)

// drums · kick
const kick = s("bd").struct("<~@4 [x!4]!140>").gain(0.64)

// drums · snare
const snare = s("sd").struct("<~@4 [x!2 ~@2 x ~@2 x ~@2 x!3 ~ x ~]!140>").gain(0.16)

// drums · snare · soft notes
const snare_soft = s("sd").struct("<~@4 [~@15 x]!139 ~>").gain(0.08)

// drums · hihat
const hihat = s("hh").struct("<~@4 [x!5 ~ x!2]!140>").gain(0.48)

// drums · open hat
const open_hat = s("oh").struct("<~@4 [~@5 x ~@2]!140>").gain(0.48)

// drums · open hat · soft notes
const open_hat_soft = s("oh").struct("<~@4 [~@15 x]!139 ~>").gain(0.24)

// drums · tambourine
const tambourine = s("tb").struct("<~@4 [x!8]!140>").gain(0.4)

// drums · tambourine · soft notes
const tambourine_soft = s("tb").struct("<~@4 [~ x ~ x ~ x ~ x ~ x ~ x ~ x ~ x]!139 [~ x ~ x ~ x ~ x ~ x ~ x ~ x ~@2]>")
  .gain(0.16)

stack(
  alto_sax, alto_sax_soft, bass, distortion_guitar, distortion_guitar_soft, overdriven_guitar, overdriven_guitar_2,
  kick, snare, snare_soft, hihat, open_hat, open_hat_soft, tambourine, tambourine_soft
)