Strudelify

Puppy Love

Donny Osmond

KeyF majorTempo72 bpm
0:00/0:00
// Puppy Love — Donny Osmond
// 72 bpm, 4/4, key F major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: ch 3 "Bell" named as a mallet, played on tubular bells (its pad new age patch is not one)
// note: Full arrangement: all 45 bars on a 24-step grid, each part at one level. Source detail keeps the original performance.
setcpm(72/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 · electric bass finger · "Bass"
const bass = note(`<
  ~ A B C D E F C G H I J D K F C G H L M N O P N Q R S T C D U V C W X Y Z AA AB AC AD AE ~ AF AG
>`.pickRestart({
  A: "f1@5 ~ f1@2 a1@2 c2@2 gb1@5 ~ gb1@2 a1@2 c2@2", B: "f1@5 ~@19", C: "g1@5 bb1 d2@3 bb1@2 g1",
  D: "c1@5 e1 g1@3 e1@2 c1", E: "f1@10 a1@2 c2@5 ~ a1@4 f1@2", F: "d1@9 ~ f1@2 a1@6 f1@4 d1@2",
  G: "c1@9 ~ e1@2 g1@6 e1@4 c1@2", H: "f1@4 a1 c2 gb1@4 a1 c2", I: "f1 ~@7", J: "g1@4 ~ bb1 d2@3 bb1@2 g1",
  K: "f1@5 a1 c2@3 a1@2 f1", L: "f1@5 ~ f1@2 a1@2 c2@2 c1@2 e1@2 g1@2 f1@2 g1@2 a1@2",
  M: "bb1 ~ bb1 ~ bb1 ~ bb1 ~@3 bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~@5",
  N: "bb1 ~ bb1 ~ bb1 ~ bb1 ~@3 bb1 ~ bb1 ~ bb1 ~ bb1 ~ bb1 ~@3 bb1 ~",
  O: "f1 ~ f1 ~ f1 ~ f1 ~@3 f1 ~ f1 ~ f1 ~ f1 ~ f1 ~@3 f1 ~",
  P: "f1 ~ f1 ~ f1 ~ f1@2 a1@2 c2@2 c1@2 e1@2 g1@2 f1@2 g1@2 a1@2",
  Q: "a1 ~ a1 ~ a1 ~ a1 ~@3 a1 ~ a1 ~ a1 ~ a1 ~ a1@2 c2@2 d2@2",
  R: "g1 ~ g1 ~ g1 ~ g1 ~@3 g1 ~ g1 ~ g1 ~ g1 ~ b1@2 d2@2 g1@2",
  S: "c2 ~ c2 ~ c2 ~ c2 ~ bb1 ~ a1 ~ bb1 ~ a1 ~ g1 ~ f1 ~ e1 ~ d1 ~", T: "c1@11 ~@13", U: "f1@5 a1 c2@3 a1 g1 f1",
  V: "d1@5 f1 a1@3 f1@2 d1", W: "c1@5 g1 c2@3 bb1 a1 g1", X: "~@8 a1@2 c2@2 f1@5 ~ f1@2 a1@2 c2@2, f1@5 ~@7",
  Y: "db1@17 ~@7", Z: "ab1@9 ~ b1@2 eb2@6 b1@4 ab1@2", AA: "db1@9 ~ f1@2 ab1@6 f1@4 db1@2",
  AB: "gb1@5 bb1 db2@3 bb1@2 gb1", AC: "eb1@9 ~ gb1@2 bb1@6 gb1@4 eb1@2", AD: "ab1@9 ~ b1@2 eb2@6 b1@2 ab1@2 f1@2",
  AE: "db1@7 ~@5", AF: "gb1@5 ~ gb1@2 bb1@2 db2@2 g1@5 ~ g1@2 bb1@2 db2@2", AG: "gb1 ~@11",
})).s("gm_electric_bass_finger").gain(0.27)

// other · string ensemble 2 · "String"
const string_ensemble_2 = note(`<
  A@3 ~@6 B C D E F G H I J K@5 L M N@2 O P Q R S T@2 U V W X Y Z AA@2 ~ AB@2
>`.pickRestart({
  A: "[~@13 [bb3,c4] ~@10 c6@7 ~@2 f6@2 c6@8 e6@2 f6@2 c6@2 ~@23, ~@6 a3 d4 [f4,g4] bb4 e5 [g5,a5] ~@24, ~@15 e4@2 a4@2 [c5,d5]@2 f5@2 bb5@2 ~@7 e6@2 ~@38]/3", // Bbsus2 Fsus2 Gsus2 Csus2
  B: "c6@8 e6@2 f6@2 c6@8 ~ f6@2 ~, ~@10 e6 ~", C: "c6 ~@23", D: "~@17 bb5@4 d6@2 ~, ~@8 a5 ~@3", E: "c6@11 ~@13",
  F: "~@6 a5@3 bb5@2 c6@6 ~ e6@6", G: "d6 ~", H: "~@16 a5@2 bb5@2 ~ d6@2 ~", I: "c6@7 ~",
  J: "~@6 c6@2 ~ f6@3 c6@8 ~ f6@2 ~, ~@4 e6 ~@5 e6 ~",
  K: "[c6@7 ~ a5@2 f5@2 eb5@2 ~@2 eb5 ~@4 c6 ~@2 f6@82 f4 g4 a4 bb4 c5 d5 e5 f5 g5 a5 bb5 c6 d6 e6, ~@7 c5 ~ g5 bb5 d6 ~@48, ~@15 d5@2 f5@2 a5@2 ~@2 e6@2 ~@95]/5",
  L: "f6", M: "e6", N: "[~@23 c6@16 ~ bb5@2 a5@2 g5@2 f5@2, d6@25 ~@23]/2", O: "c5 ~@11",
  P: "~@14 bb5@2 c6@2 d6@2 [bb5,c6] a5 g5 [e5,f5]", Q: "c5 ~, d5 ~@23",
  R: "~@5 f5@4 a5@2 ~ c6@8 ~ c6@2 ~, ~@2 e5 ~@7 a5 ~", S: "f5@7 ~@5",
  T: "[~@8 bb5@2 c6@2 d6@2 ~ bb5@2 a5@2 g5 f5 e5 d5 c5@9 ~@16, ~@7 c6 ~@16]/2",
  U: "~@12 [db4,d4] [eb4,e4] [f4,gb4] [g4,ab4] [a4,bb4] [b4,c5] [db5,d5] [eb5,e5] [f5,gb5] [g5,ab5] [a5,bb5] [b5,c6]", // Dmaj7 Emaj7 Gbmaj7 Abmaj7 Bbmaj7 Cmaj7 Dmaj7 Emaj7 …
  V: "db6", W: "~@14 ab5@2 bb5@2 b5@2 ~ gb6@3, ~@10 eb6 ~", X: "f6@3 ~@5",
  Y: "~@2 f4@2 gb4@2 bb4@2 ~ f5@2 db5@2 f5@2 gb5@3 bb5@2 db6@2 f6@2, ~@4 db5 ~@7", Z: "eb6@17 ~@7",
  AA: "[~@18 [e6,gb6] [db6,d6] b5 [ab5,a5] [e5,gb5] db5@18 ~@7, ~@23 d5 ~@24]/2", // Esus2 Dmaj7 Amaj7 Esus2
  AB: "[db6@8 ~ gb6@2 db6@8 f6@2 gb6@2 db6@5 ~@20, ~@4 f6 ~@19]/2",
})).s("gm_string_ensemble_2").gain(0.3)

// other · tubular bells · "Bell"
const tubular_bells = note("<~ A B C D E F C G H I C J E F C D K L ~@9 C M E F C N O P Q R S T U V ~@3>".pickRestart({
  A: "c5@4 e5 f5 c5@4 e5 f5", B: "c5 ~@2", C: "~@2 g4 ~ bb4 ~ d5 ~@7 bb4 ~ d5 ~ f5 ~@5",
  D: "~@2 e4 ~ g4 ~ c5 ~@7 g4 ~ c5 ~ e5 ~@5", E: "~@2 f4 ~ a4 ~ c5 ~@7 a4 ~ c5 ~ d5 ~@5",
  F: "~@2 d4 ~ f4 ~ a4 ~@7 f4 ~ a4 ~ c5 ~@5", G: "~@2 e4 ~ g4 ~ c5 ~@7 e4 ~ g4 ~ bb4 ~@5",
  H: "~@2 f4 ~ a4 ~ c5 ~ bb4 ~ a4 ~ bb4 ~ a4 ~ g4 ~ f4 ~ e4 ~ d4 ~", I: "c4 ~@23",
  J: "~@2 e4 ~ g4 ~ c5 ~@7 c5 ~ e5 ~ g5 ~@5", K: "~@2 f4 ~ a4 ~ c5 ~@7 bb4 ~ c5 ~ bb4 ~ a4 ~ g4 ~", L: "f4 ~@23",
  M: "~@2 c4 ~ e4 ~ g4 ~@7 e4 ~ g4 ~ bb4 ~@5", N: "~@2 c4 ~ e4 ~ g4 ~@7 g4 ~ a4 ~ bb4 ~@5",
  O: "~@6 f4 ~ g4 ~ a4 ~ bb4 ~@7 g4 ~ f4 ~", P: "db4 ~@23", Q: "~@2 ab4 ~ b4 ~ eb5 ~@7 b4 ~ eb5 ~ gb5 ~@5",
  R: "~@2 db4 ~ f4 ~ ab4 ~@7 f4 ~ ab4 ~ b4 ~@5", S: "~@2 gb4 ~ bb4 ~ db5 ~@7 bb4 ~ db5 ~ eb5 ~@5",
  T: "~@2 eb4 ~ gb4 ~ bb4 ~@7 gb4 ~ bb4 ~ eb5 ~@5", U: "~@2 ab4 ~ b4 ~ eb5 ~@7 b4 ~ eb5 ~ gb5 ~@3 eb5 ~", V: "db5 ~@3",
})).s("gm_tubular_bells").gain(0.45)

// other · acoustic guitar nylon · "Guitar"
const acoustic_guitar_nylon = note("<~@3 A B C D E F ~@2 G B C H A I ~@11 A B J K A I L M N O P Q R ~@4>".pickRestart({
  A: "~@12 d5@6 f5@5 ~", B: "~@2 c5 e5", C: "~@12 a4@6 c5@5 ~", D: "~@12 a4@5 ~ d5@6", E: "~@12 d5@5 f5@5 ~@2",
  F: "~@6 c5@3 e5@2 ~", G: "~@2 d5 f5", H: "~@2 a4 d5", I: "~@12 c5@6 e5@5 ~", J: "~@2 a4 c5", K: "~@12 a4@6 d5@5 ~",
  L: "~@2 f5 eb5", M: "db5@11 ~@13", N: "~@2 eb5 gb5", O: "~@6 db5@3 f5@2 ~", P: "~@2 bb4 db5", Q: "~@2 bb4 eb5",
  R: "~@12 eb5@6 gb5@5 ~",
})).s("gm_acoustic_guitar_nylon").gain(0.45)

// drums · kick
const kick = s("bd").struct("<~ A B C@4 D@2 E B C@5 D C F G@3 H I@3 J K C@5 D L I C@5 B ~ C B>".pickRestart({
  A: "x ~@4 x!2 ~ x ~@2 x", B: "x", C: "x ~@4 x!2 ~@4 x", D: "x ~@4 x!2 ~@5", E: "x!4", F: "x ~@3 x!2 ~ x!2 ~ x!2",
  G: "x!2 ~ x!2 ~", H: "x ~ x ~ x!2 ~ x!2 ~ x!2", I: "x ~ x ~@2 x!2 ~ x ~@2 x", J: "x!3 ~ x!2 ~ x!2 ~ x!2",
  K: "~@7 x!2 ~ x!2", L: "x!3 ~@2 x!2 ~ x ~@2 x",
})).gain(0.45)

// drums · rim
const rim = s("rim").struct("<~@3 [~ x ~ x]!6 ~@2 [~ x ~ x]!6 ~@11 [~ x ~ x]!6 ~@11>").gain(0.45)

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

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

// drums · low tom
const low_tom = s("lt").struct("<~@2 A ~@6 B C ~@6 D@2 ~@8 E ~@17>".pickRestart({
  A: "~@9 x!3", B: "~ x ~ x!2 ~ x!2 ~ x!2 ~", C: "x ~@10 x", D: "~ x!2 ~ x!2 ~ x!2 ~ x!2", E: "~@2 x!2",
})).gain(0.4)

// drums · open hat
const open_hat = s("oh").struct("<~@18 [~@6 x!6] ~@8 x ~@17>").gain(0.45)

// drums · mid tom
const mid_tom = s("mt").struct("<~@10 [~@5 x] ~@34>").gain(0.45)

// drums · crash
const crash = s("cr").struct("<~ A ~ A ~@7 A ~@7 A ~@3 A ~@4 A ~@6 A@2 ~@4 A ~ A@2>".pickRestart({
  A: "x",
})).gain(0.35)

// drums · high tom
const high_tom = s("ht").struct("<~@10 [~@3 x] ~@34>").gain(0.45)

// drums · ride
const ride = s("rd").struct("<~ A ~@17 A B@3 C B@2 D ~@16 A ~>".pickRestart({
  A: "~ x!11", B: "x!12", C: "~@2 x!10", D: "x!3 ~@9",
})).gain(0.45)

// drums · cabasa
const cabasa = s("cabasa:4").struct("<~@3 A B@6 ~ A B@6 C ~@7 D ~ E B@5 F ~ G B@3 H ~@4>".pickRestart({
  A: "~ x!11", B: "x!12", C: "x", D: "~@4 x!2 ~ x!2 ~ x!2", E: "~@3 x!9", F: "x!6 ~@6", G: "~@2 x!10", H: "x!9 ~@3",
})).gain(0.5)

stack(
  bass, string_ensemble_2, tubular_bells, acoustic_guitar_nylon, kick, rim, snare, hihat, low_tom, open_hat, mid_tom,
  crash, high_tom, ride, cabasa
)