Strudelify

Theme From the Saint

Orbital

KeyA♭ majorTempo150 bpm
0:00/0:00
// Theme From the Saint — Orbital
// 150 bpm, 4/4, key G# major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: Tempo changes preserved in elapsed time; displayed bars use the dominant tempo.
// note: sustain pedal (CC 64) lengthens the held notes
// note: Full arrangement: all 170 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(150/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 1 · "Bass"
const bass = note("<~@4 A B ~@2 C D ~@3 E@9 F G@10 E@36 H@7 ~ H@48 ~@4 H@39 I ~>".pickRestart({
  A: "~@4 ab2@2 ab2 gb2", B: "~ gb2 eb2!2 eb2@4", C: "~@5 ab2 ~ ab2", D: "gb2 ~@2 gb2 eb2!2 ~ eb2@7 ~@2",
  E: "ab1@3 gb1@2 eb1!3", F: "ab1@3 gb1@3 eb1@2", G: "eb1@3 gb1@3 ab1@2", H: "ab1 ~ ab1 gb1@2 eb1!3",
  I: "ab1 ~ ab1 gb1@2 eb1 gb2 ab2",
})).s("gm_synth_bass_1").gain(0.42)

// other · vibraphone · "Vibraphon"
const vibraphone = note(`<
  ~ A@4 B@5 ~@6 C D@3 E ~ F G H@2 I J K G L ~@21 M N@3 M N@3 M N@3 M N@3 ~@17 O@40 ~ C P Q@2 ~@6 M R S ~ C T@3 M R U ~ C
  V@4 ~@17
>`.pickRestart({
  A: "[~ ab4, ~@6 ab4@3 ab4@3 b4@16 ~@4, ~@7 d5@16 ~@9, ~ eb5@2 ~, ~@5 db5@8 ~@3]/4",
  B: "[~@17 ab4@16 ~@7, ~@7 ab4@3 ab4@3 b4@16 ~@11, ~ d5@2 ~@2, ~@9 eb5@16 ~@15, ~@11 db5@16 ~@13]/5", C: "~@7 ab4",
  D: "[d5 eb5 ab4 db5@2 ~@2 db5 g5 ab5 db5 gb5@2 ~@2 ab4 d5 eb5 ab4 db5@2 b4@3, ~@5 b4@9 ~@10, ~@13 f5@5 ~@6]/3",
  E: "ab4", F: "~@7 eb5", G: "a5 bb5 eb5 ab5@2 gb5@3",
  H: "[~@2 bb4!2 gb5 f5 db5 ~ a5 bb5 eb5 ab5@2 gb5@3, eb5@6 ~ eb5@2 ~@7]/2", I: "~@2 gb5 f5 gb5 f5 db5 eb5, eb5@3 ~",
  J: "a5 bb5 eb5 ab5@2 gb5 ~ ab4", K: "d5 eb5 ab4 db5@2 b4@2 eb5", L: "eb5", M: "~@13 ab4@3",
  N: "[d5@3 eb5@2 ab4@3 db5@4 b4@12 ab4@19 ~@5]/3", O: "~ gb5@3 e5@2 eb4 db4", P: "d5@3 eb5@3 ab4@2 db5@4 b4@4",
  Q: "[ab4@21 ~@11]/2", R: "d5@3 eb5@2 ab4@3 db5@4 b4@4", S: "ab4@5 b4@7 db5@4",
  T: "[d5@3 eb5@2 ab4@3 db5@4 b4@9 ab4@21 ~@6]/3", U: "ab4@5 ~@2 b4@5 db5@4",
  V: "[d5@3 eb5@3 ab4@2 db5@4 b4@10 ab4@33 ~@9]/4",
})).s("gm_vibraphone").gain(0.16).pan(0.6)

// chords · string ensemble 2 · "Strings"
const string_ensemble_2 = note(`<
  ~@37 A@3 B@4 C@4 D@4 E@4 F@4 G@8 ~@17 H@3 I@8 ~ J@4 K L@8 M N@8 O@5 P@5 Q@7 R@8 S@8 T@8 ~@10
>`.pickRestart({
  A: "eb5/3", B: "[~@15 [eb5,ab5]@49]/4", C: "[~@15 [eb5,ab5,c6]@49]/4", D: "[~@15 [eb5,ab5,c6,eb6]@49]/4",
  E: "[~@15 eb5@49]/4", F: "[~@15 ab5@49]/4", G: "[~@39 eb6@25, ~@15 c6@113]/8", H: "ab5/3",
  I: "[~@79 ab6@49, ~@15 eb6@113]/8", J: "[~ ab6, ab5@63 ~, ~ eb6@3]/4", K: "ab5",
  L: "[~@15 eb6, eb6@63 ~ eb6@55 ~@9, ~@16 ab6@63 ~ ab6@48, ~@47 ab5@64 ab5@17]/8", M: "ab6",
  N: "[~@7 ab6, ab5@32 ab5@31 ~ ab5@31 ~ ab5@31 ~, ~@8 ab6@39 ~ ab6@31 ~ ab6@31 ~@17, ~@16 eb6@23 ~ eb6@31 ~ eb6@31 ~ eb6@24]/8",
  O: "[~@72 eb6@7 ~, ab5@31 ~ ab5@31 ~ ab5@16, ~@8 eb6@31 ~ eb6@31 ~@9, ~@16 ab6@31 ~ ab6@31 ~]/5", P: "ab6/5",
  Q: "[~@79 ab6@33, ~@15 eb6@96 ~]/7", R: "[~@3 ab6, eb6@63 ~ eb6@63 ~, ~@31 ab6@63 ~@34]/8",
  S: "[~@47 eb5@16 ab5@48 ab6@17, eb6, ~ ab6@5 ~@2]/8", T: "[~@3 ab6@29]/8",
})).s("gm_string_ensemble_2").gain(0.26)

// other · pad poly · "Polysynth"
const pad_poly = note("<A ~@3 B@2 ~@2 C D@5 E@2 F E@3 F E G H@10 ~@36 I@7 ~ I@48 ~@4 I@40 ~>".pickRestart({
  A: "eb1 ~@15", B: "[~@4 ab1@3 gb1@3 eb1@6]/2", C: "~@5 ab1@3", D: "[gb1 eb1@15 ~ gb1@2 eb1, ~@8 ab1 ~]/5",
  E: "~ gb1@2 eb1, ab1 ~", F: "ab1 ~ gb1 eb1", G: "ab1@3 gb1@3 eb1 ~", H: "eb1@3 gb1@3 ab1@2", I: "ab1@3 gb1@3 eb1@2",
})).s("gm_pad_poly").gain(0.34)

// other · brass section · "Brass"
const brass_section = note("<~@33 A@36 ~@24 A@15 B A@7 B A@7 B ~@4 A@7 B A@7 B A@7 B ~@15 C ~>".pickRestart({
  A: "ab2@3 a2@3 eb2@2", B: "ab2@3 a2@3 eb2 ~", C: "~@6 [gb3,gb4] [ab3,ab4]",
})).s("gm_brass_section").gain(0.63)

// chords · trumpet
const trumpet = note(`<
  ~@32 A ~@3 A B@3 C D E D F G@3 H I@3 J@2 K L M L K N O L K L P L K L P ~@7 A ~@7 A ~@25 A ~ A ~ A ~ A Q A Q A Q A Q A
  ~@3 A Q A Q A Q A Q A Q A Q A Q A Q A Q A Q A Q A Q A ~@15 R ~
>`.pickRestart({
  A: "~@6 ab4 a4", B: "~ ab3 ~@2 a3 ~ eb3 ~", C: "~ ab3 ~@2 a3 ~ [eb3,ab4] a4", D: "~ [ab3,c4] ~@2 [a3,db4] ~ eb3 ~",
  E: "~ c4@2 ~ [a3,db4] ~ eb3 ~, ~ ab3 ~@6", F: "~ [ab3,c4] ~@2 [a3,db4] ~ [eb3,ab4] a4",
  G: "~ [ab3,c4,eb4] ~@2 [a3,db4,e4] ~ eb3 ~", H: "~ [ab3,c4,eb4] ~@2 [a3,db4,e4] ~ [eb3,ab4] a4",
  I: "~ [ab3,c4,eb4,ab4] ~@2 [a3,db4,e4,a4] ~ eb3 ~", J: "~ [ab3,c4,eb4,ab4] ~@2 [a3,db4,e4,a4] ~ [eb3,ab4] a4",
  K: "ab2@3 gb2@3 eb2@2", L: "~ [ab3,c4,eb4] ~@2 [a3,db4,e4] ~ eb2@2, ab2@3 gb2@3 ~@2",
  M: "ab2@3 gb2@3 d4 eb4, ~@3 eb2", N: "~ [ab3,c4,eb4] ~@2 [a3,db4,e4] ~ eb2@2, ab2@2 gb2 ~",
  O: "ab2@3 ~ d4@2 eb4 ab3, ~@3 gb2@3 eb2@2", P: "ab2@3 [gb2,d4]@3 eb4 ab3, ~@3 eb2",
  Q: "~ [ab3,c4,eb4] ~@2 [a3,db4,e4] ~@3", R: "~@6 [gb4,gb5] [ab4,ab5]",
})).s("gm_trumpet").gain(0.4).pan(0.4)

// chords · trumpet · soft notes
const trumpet_soft = note("<~@33 [ab2@3 a2@3 eb2@2]!21 ~@116>").s("gm_trumpet").gain(0.15).pan(0.4)

// other · timpani
const timpani = note("<~@4 A B@3 C D@2 ~ E F G H I J G H I J K L@4 M L M L M@2 K@36 N@56 ~@3 O N@40 ~>".pickRestart({
  A: "~@4 ab2 ~ ab2 gb2", B: "[~ gb2 eb2!2 eb2@13 ~@7]/3", C: "~@5 ab2 ~ ab2", D: "[gb2 ~@2 gb2 eb2!2 ~ eb2@13 ~@12]/2",
  E: "eb2!16", F: "ab2@5 ~ gb2@3 ~ eb2 ~ eb2 ~ eb2@2, eb2 ~@15", G: "ab2@5 ~ gb2@4 eb2 ~ eb2 ~ eb2@2",
  H: "ab2@6 gb2@3 ~ eb2 ~ eb2 ~ eb2@2", I: "ab2@5 ~ gb2@3 ~ eb2 ~ eb2 ~ eb2 ~", J: "ab2@5 ~ gb2@3 ~ eb2 ~ eb2 ~ eb2@2",
  K: "ab2@3 gb2@2 eb2!3", L: "eb2@3 gb2@3 ab2 eb2", M: "eb2@3 gb2@3 ab2@2", N: "ab2@2 ab2 gb2@2 eb2!3",
  O: "ab2@2 ~ gb2@2 eb2!3",
})).s("gm_timpani").gain(0.6).pan(0.4)

// other · taiko drum · "Taiko"
const taiko_drum = note("<~@4 A B@3 C D@2 ~@58 E@7 ~ E@48 ~@4 E@40 ~>".pickRestart({
  A: "~@4 ab2 ~ ab2 gb2", B: "[~ gb2 eb2!2 eb2@13 ~@7]/3", C: "~@5 ab2 ~ ab2", D: "[gb2 ~@2 gb2 eb2!2 ~ eb2@13 ~@12]/2",
  E: "ab2@2 ab2 gb2@2 eb2!3",
})).s("gm_taiko_drum").gain(0.25).pan(0.7)

// other · orchestra hit · "Orch Hit"
const orchestra_hit = note("<~@168 A@2>".pickRestart({
  A: "[~@6 gb4 ab4@5 ~@4]/2",
})).s("gm_orchestra_hit").gain(0.33)

// drums · kick
const kick = s("bd").struct("<~@13 A@19 ~ A@36 ~@8 A@48 ~@4 A@32 ~@9>".pickRestart({
  A: "x ~@2 x ~ x ~ x",
})).gain(0.33)

// drums · snare
const snare = s("sd").struct("<~@13 A@19 ~ A@36 ~@7 B A@48 ~@4 A@32 ~@9>".pickRestart({
  A: "~@4 x ~@4 x ~@2 x ~ x ~", B: "~@6 x!2",
})).gain(0.47)

// drums · pedal hat
const pedal_hat = s("hh").struct("<~@13 A@19 ~ A@36 ~@8 A@48 ~@4 A@32 ~@9>".pickRestart({
  A: "x!7 ~",
})).gain(0.23)

// drums · open hat
const open_hat = s("oh").struct("<~@13 A@19 ~ A@36 ~@8 A@48 ~@4 A@32 ~@9>".pickRestart({
  A: "~@7 x",
})).gain(0.23)

// drums · ride
const ride = s("rd").struct("<~@13 A@19 B A@36 ~@8 A@48 ~@4 A@32 ~@9>".pickRestart({
  A: "x ~ x ~ x ~ x!5 ~ x ~ x ~", B: "x ~@3 x ~ x ~ x!2 ~@2 x ~ x ~",
})).gain(0.23)

// drums · tambourine
const tambourine = s("tb").struct("<~@13 A@19 ~ A@36 ~@8 A@48 ~@4 A@32 ~@9>".pickRestart({
  A: "x!16",
})).gain(0.23)

// drums · bongos
const bongos = s("bongo:4").struct("<~@13 [~@7 x]!56 ~@8 [~@7 x]!48 ~@4 [~@7 x]!32 ~@9>").gain(0.86)

// drums · congas
const congas = s("conga:13").struct(`<
  ~@13
  [~@4 x ~@4 x ~@2 x ~@3]!56
  ~@8
  [~@4 x ~@4 x ~@2 x ~@3]!48
  ~@4
  [~@4 x ~@4 x ~@2 x ~@3]!32
  ~@9
>`).gain(1.05)

// drums · congas
const congas_2 = s("conga:18").struct("<~@13 [~@5 x ~@2]!56 ~@8 [~@5 x ~@2]!48 ~@4 [~@5 x ~@2]!32 ~@9>").gain(1.05)

// drums · congas
const congas_3 = s("conga:33").struct("<~@13 A@19 B A@36 ~@8 A@48 ~@4 A@32 ~@9>".pickRestart({
  A: "x ~ x!3 ~@3", B: "x!2 ~ x!2 ~@3",
})).gain(1.05)

stack(
  bass, vibraphone, string_ensemble_2, pad_poly, brass_section, trumpet, trumpet_soft, timpani, taiko_drum,
  orchestra_hit, kick, snare, pedal_hat, open_hat, ride, tambourine, bongos, congas, congas_2, congas_3
)