Strudelify

Satin Doll

Ellington

KeyE minorTempo140 bpm
0:00/0:00
// Satin Doll — Ellington
// 140 bpm, 4/4, key E minor. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: duplicate parts dropped: ch 13 "bass2" acoustic bass (copy of ch 2 "bass" acoustic bass); ch 14 "keyboard2" epiano1 (copy of ch 3 "keyboard" epiano1); ch 15 "melody-vi" vibraphone (copy of ch 4 "melody-vi" vibraphone)
// note: Full arrangement: all 70 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(140/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 · acoustic bass · "bass"
const bass = note(`<
  A B C D E F G H I J C K L M N O P Q R S T U V W J X Y C Z AA AB AC AD AE D AF AG AH AI H AJ AK AL AM E AN AO AP AQ AR
  AS AT T AU AV AW J AX AY AF AZ AN BA BB L AA BC AI BD BE
>`.pickRestart({
  A: "d2@7 g#2 g2@6 ~ g2", B: "d2@6 ~ d2 g2@8", C: "e2 a1", D: "e2@6 ~ e2 a1@8", E: "d2@4 e2@4 f2@4 f#2@3 d2",
  F: "f#2@4 g#2@3 ~ a2@4 a#2@3 c#2", G: "c2@2 ~ c1 c2@3 ~ a1@4 g1@3 c2", H: "e2@4 a#1@4 a1@3 a0 a1@4",
  I: "d2@5 ~@2 f#2 g2@6 ~ g2", J: "d2 g2", K: "e2@2 a1 d#2", L: "d2@4 c2@4 b1@4 a1@3 d2",
  M: "f#2@2 ~ f#1 e2@3 ~ d#2@4 c#2@3 f#2", N: "e3@3 g1 d#3@4 d3@3 ~ c#3@3 ~", O: "c3 g2 ~ e2 d2@3 ~ c2@4 ~@3 f#2",
  P: "g3 d3 ~ g2 c#2@3 b1 c2@3 ~ c2@3 g#2", Q: "g2@3 g1 c#2@4 c3 g2 ~ c2 f#2@3 e2", R: "f2@3 ~ f2@4 c2@3 ~ c2@3 f#2",
  S: "f2@4 e2@4 d2@4 c2@3 f2", T: "a1@4 c2@3 a1 d2@4 f#2@3 d2", U: "a1@3 a0 a1@4 d2@3 ~ d2@4",
  V: "d2@4 e2@3 ~ f2@4 a2@3 d2", W: "g2@4 d3@4 g3@4 d3@3 d#2", X: "d2@7 ~ g2@6 ~ g2", Y: "e2@7 a#1 a1@7 ~",
  Z: "d2@4 a2@4 d3@4 a2@3 g2", AA: "f#2@4 g#2@4 a2@4 a#2@3 f#2", AB: "c2@3 c1 c2@4 a1@4 g1@3 f2",
  AC: "e2@3 e1 e2@4 a1@4 c#2@3 a1", AD: "d2@7 ~ g2@8", AE: "d2@8 g2@6 ~ g2", AF: "e2@8 a1@6 ~ a1",
  AG: "d2@3 d1 c2@4 b1@4 a1@3 g2", AH: "f#2@4 c#3@4 f#3@4 c#3@3 c#2", AI: "c2@4 c2@4 a1@4 g1@3 c2",
  AJ: "d2@7 g#2 g2@7 ~", AK: "d2@8 g2@7 f2", AL: "e2@7 a#1 a1@8", AM: "e2@7 ~ a1@7 ~", AN: "f#2@4 e2@4 d#2@4 c#2@3 f#2",
  AO: "c2@2 ~ [c1,g1] c2@4 a1@4 g1@2 ~ g1", AP: "c2@3 ~ d2@3 ~ d#2@4 e2@4", AQ: "g2@3 g1 g2@4 c3 g2 ~ c2 g#2@3 f#2",
  AR: "g2@4 c#2@4 c2@3 c1 f#2@4", AS: "f2@3 f1 c#2@4 c2@4 e2@3 c2", AT: "f2@4 g2@4 g#2@4 a2@3 f2",
  AU: "a2 e2 ~ a1 d#2@3 c#2 d2@4 f#2@3 d2", AV: "d2@4 e2@4 f2@4 a2@2 ~ g#2", AW: "g2@4 f2@4 e2@4 d2@3 g2",
  AX: "d2@7 g#2 g2@8", AY: "e2@8 a1@7 f2", AZ: "d2@4 e2@3 ~ f2@4 f#2@3 g2", BA: "c2@4 g2@4 c3@4 g2@3 f2",
  BB: "e2@4 g2@3 e2 d#2@3 ~ d#2@3 d#2", BC: "c2@4 d2@3 ~ d#2@4 e2@3 c#2", BD: "c2 e2 f2 f#2",
  BE: "~ g2@3 ~ c3 ~ c3@5 c2@2 ~@2",
})).s("gm_acoustic_bass").gain(0.36)

// bass · acoustic bass · "bass" · soft notes
const bass_soft = note("<A B ~ C ~@4 D ~@6 E ~@9 F G ~@5 H A C I ~@4 J ~@2 K ~@3 L ~@11 I ~@10>".pickRestart({
  A: "~@13 g1 ~@2", B: "~@5 d1 ~@10", C: "~@5 e1 ~@10", D: "~@5 g#2 ~@7 g1 ~@2", E: "~@12 g#2@3 ~",
  F: "~@7 d1 ~@5 g1 ~@2", G: "~@15 a0", H: "~@7 d1 ~@8", I: "~@13 a0 ~@2", J: "~@15 g1", K: "~@7 e1 ~@7 a0",
  L: "~@3 g1 ~@3 g1 ~@3 g1 ~@4",
})).s("gm_acoustic_bass").gain(0.2)

// chords · epiano1 · "keyboard"
const epiano1 = note(`<
  A B C D E F G H I J K L M N O@2 P Q R S T U V W X Y Z AA AB AC AD H AE AF AG AH AI AJ AK AL AM AN AO AP AQ AR O@2 AS
  AT AU AV AW AX AY AZ BA BB BC BD BE F BF BG BH AR BF BI ~ BJ
>`.pickRestart({
  A: "[f3,c4,e4,a4]@7 ~ [f3,b3,d4,g4]@2 ~ [f3,b3,d4,g4]@4 ~", // Fmaj7 G7
  B: "[f3,c4,e4,a4]@7 ~ [f3,a3,b3,e4]@2 ~@2 [f3,a3,b3,e4]@4", // Fmaj7
  C: "[g3,d4,e4,b4]@2 ~@2 [g3,d4,e4,b4]@4 [g3,c#4,e4,a4]@2 ~ [g3,c#4,e4,a4]@4 ~", // Em7 A7
  D: "[g3,b3,d4,e4] ~ [g3,b3,d4,e4]@2 [g3,c#4,f4,a#4] ~ [g3,c#4,f4,a#4]@2", E: "[f#3,g#3,c4,e4,b4]@13 ~@3",
  F: "[e3,a#3,c#4,g#4]@13 ~@3", G: "[e3,g3,c4]@6 ~ [e3,g3,c4] ~@8",
  H: "~@3 [g3,d4,e4,b4]@4 ~ [g3,a#3,c#4,f4]@4 c#4 g4 ~ a4", I: "[f3,c4,e4,a4]@3 ~ [f3,b3,e4,a4]@3 ~",
  J: "[f3,a3,c4,d4]@7 ~ [f3,a3,b3,e4]@2 ~ [f3,a3,b3,e4]@4 ~", K: "~@3 [g3,b3,d4,e4]@4 ~ [g3,c#4,f#4,b4]@6 ~@2",
  L: "[g3,b3,d4,e4]@2 ~@2 [g3,b3,d4,e4]@4 [g3,c#4,f4,a#4]@3 a2 [g3,c#4,f4,a#4]@2 ~@2", // Em7 Gm7b5
  M: "~@7 d3 [f#3,c4,e4,a4]@2 ~ d3 [f#3,c4,e4,a4]@2 ~@2", N: "[e3,a#3,d#4,g#4]@11 ~@5",
  O: "[~@8 [e3,c4,g4]@2 ~ [e3,c4,g4]@2 ~@2 [e3,c4,g4]@13 ~@4]/2", P: "[f3,a3,a#3,d4]@2 ~@6 [e3,a#3,d4,a4]@7 ~",
  Q: "[f3,a#3,d4,a4]@4 a#3 f4 ~ g4 [e3,a#3,c#4,g#4]@4 a#3 e4 ~ g4", // A#maj7 A#m7b5
  R: "[d3,a3,c4,f4]@2 ~@6 [e3,a#3,c#4,g#4]@4 a#3 e4 ~ g4", S: "~@7 f3 [d3,a3,c4,f4]@2 ~ f3 [d3,a3,c4,f4]@2 ~@2",
  T: "[g3,b3,c4,e4]@4 c4 g4 ~ a4 [f#3,c4,e4,b4]@7 ~", U: "[g3,a3,c4,e4]@4 c4 g4 ~ a4 [f#3,c4,d4,a4]@2 ~@6",
  V: "[f3,c4,d4,a4]@11 ~@5", W: "~@7 g2 [f3,b3,d4,g4]@2 ~ g2 [f3,b3,d4,g4]@2 ~@2",
  X: "[f3,c4,e4,a4]@7 ~ [f3,b3,e4,a4]@6 ~@2", Y: "[f3,c4,d4,a4]@3 d3 [f3,c4,d4,a4]@2 ~@2 [f3,b3,e4,a4]@6 ~@2",
  Z: "~@3 [g3,d4,e4,b4]@4 ~ [g3,c#4,e4,b4]@7 ~", AA: "[g3,d4,e4,b4]@6 ~@2 [g3,a#3,c#4,f4]@7 ~",
  AB: "[f#3,c4,e4,b4]@6 ~ [f#3,c4,e4,b4] ~@8", AC: "[e3,a#3,c#4,g#4]@11 ~@5",
  AD: "[e3,g3,c4]@7 ~ [e3,g3,c4]@2 ~ c3 [e3,g3,c4] ~@3", // C
  AE: "~@3 [f3,c4,e4,a4]@4 ~ [f3,b3,d4,a4]@2 ~ [f3,b3,d4,a4]@4 ~", AF: "[f3,c4,e4,a4]@7 ~ [f3,a3,b3,e4]@6 ~@2",
  AG: "[g3,d4,e4,b4]@2 ~ [g3,d4,e4,b4]@4 ~ [g3,a3,c#4,e4]@3 a2 [g3,a3,c#4,e4]@2 ~@2", // Em7 A7
  AH: "[g3,b3,d4,e4]@6 ~@2 [g3,c#4,f4,a#4]@7 ~", AI: "[f#3,g#3,c4,e4,b4]@11 ~@5",
  AJ: "[e3,g#3,a#3,d#4]@7 ~ [e3,g#3,a#3,d#4]@2 ~ f#2 [e3,g#3,a#3,d#4] ~@3", AK: "[e3,g3,c4]@13 ~@3",
  AL: "[g3,b3,d4,e4]@7 ~ [g3,c#4,f4,a#4]@2 ~@6", // Em7 Gm7b5
  AM: "[f3,c4,d4,a4]@2 ~ [f3,c4,d4,a4]@4 ~ [f3,b3,d4,g4]@2 ~@2 [f3,b3,d4,g4]@4", // Dm7 G7
  AN: "[f3,c4,e4,a4]@2 ~ [f3,c4,e4,a4]@4 ~ [f3,b3,e4,a4]@6 ~@2", // Fmaj7
  AO: "[g3,d4,e4,b4]@3 e3 [g3,d4,e4,b4]@2 ~@2 [g3,b3,c#4,f#4]@2 ~@2 [g3,b3,c#4,f#4]@4", // Em7 Gmaj7
  AP: "[g3,d4,e4,b4]@2 ~ [g3,d4,e4,b4]@4 ~ [g3,c#4,f4,a#4]@2 ~@2 [g3,c#4,f4,a#4]@4", // Em7 Gm7b5
  AQ: "[f#3,c4,e4,b4]@7 ~ [f#3,c4,e4,b4]@2 ~ d3 [f#3,c4,e4,b4] ~@3", AR: "[e3,a#3,d#4,g#4]@6 ~ [e3,a#3,d#4,g#4] ~@8",
  AS: "[f3,a#3,d4,g4]@4 a#3 f4 ~ g4 [e3,a#3,d4,a4]@2 ~@6", AT: "~@3 [f3,a#3,d4,a4]@4 ~ [e3,g#3,a#3,c#4]@4 a#3 e4 ~ g4",
  AU: "[d3,f3,a3,c4] ~@3 [e3,g3,a#3,d#4] ~@3", AV: "[d3,f3,a3,c4]@6 ~ [d3,f3,a3,c4] ~@8",
  AW: "[g3,a3,c4,e4]@7 ~ [f#3,g#3,b3,c4,e4]@2 ~@6", AX: "[g3,c4,e4,b4]@7 ~ [f#3,g#3,c4,e4,b4]@2 ~@6",
  AY: "[f3,a3,c4,d4]@11 ~@5", AZ: "~@7 g2 [f3,g3,b3,d4]@2 ~ g2 [f3,g3,b3,d4]@2 ~@2",
  BA: "[f3,c4,e4,a4]@7 ~ [f3,b3,e4,a4]@2 ~ [f3,b3,e4,a4]@4 ~", // Fmaj7
  BB: "[f3,c4,d4,a4]@2 ~@2 [f3,c4,d4,a4]@4 [f3,b3,d4,g4]@3 g2 [f3,b3,d4,g4]@2 ~@2", // Dm7 G7
  BC: "~@3 [g3,d4,e4,b4]@4 ~ [g3,b3,c#4,f#4]@2 ~ [g3,b3,c#4,f#4]@4 ~", BD: "~@3 [g3,d4,e4,b4]@4 ~ [g3,a#3,c#4,f4]@7 ~",
  BE: "[f#3,c4,e4,b4]@13 ~@3", BF: "[e3,c4,g4]@13 ~@3", BG: "[g3,d4,e4,b4]@7 ~ [f#3,c#4,f4,a#4]@2 ~@6",
  BH: "[f#3,c4,e4,a4]@11 ~@5", BI: "[e3,c4,g4]@11 ~@5", BJ: "[e3,c4,g4]@2 ~@2 [f3,c#4,g#4]@2 ~ [e3,c4,g4]@7 ~@2",
})).s("gm_epiano1").gain(0.26)

// chords · string ensemble 1 · "strings"
const string_ensemble_1 = note(`<
  ~@4 A B C D ~@4 E F G@2 H I J K L@2 M N ~@4 O P C Q ~@4 O F R D ~@4 A S T@2 U V J K W X Y Z ~@4 A B R AA A P AB C ~@2
>`.pickRestart({
  A: "f#6@8 a6@4 f#6@3 ~, c6@15 ~", B: "e6@8 g#6@4 e6@3 ~, a#5@15 ~", C: "~ g6, [g5,e6]", D: "[g5,e6]!2",
  E: "c6 e6, f#6", F: "~ g#6, [a#5,e6]", G: "[~@7 g5, [e6,g6]]/2", H: "~ f6 ~ e6, a#5!2", I: "[a#5,g6]@2 ~ e6, ~ a#5",
  J: "[a5,f6]@2 ~ e6, ~ a#5", K: "[a5,d6]", L: "[g5,c6] [c6,a6]", M: "[c6,f6]", N: "[b5,f6]", O: "~ a6, [c6,f#6]",
  P: "[a#5,e6]", Q: "[g5,d6] [g5,e6]", R: "e6@8 g6@4 e6@3 ~, g5@15 ~", S: "a#5 c#6, e6", T: "[~ c6@2 g5, [e6,g6]]/2",
  U: "[a#5,f6] [a#5,g6]", V: "~ f6 [a#5,e6]@2, a#5 ~", W: "[g5,c6] [c6,f#6]", X: "[g5,e6]@2 ~ f#6, ~ c6",
  Y: "c6 d6, f6", Z: "~ g6, [b5,f6]", AA: "[g5,d6] [f#5,c#6]", AB: "[g5,e6]",
})).s("gm_string_ensemble_1").gain(0.15)

// drums · kick
const kick = s("bd").struct(`<
  A ~@2 B ~ A ~ C A ~ D B A E F B ~ A@2 G ~@3 H A@3 G ~ A ~ G A ~ A H A@3 ~ A ~ A I A ~ A C ~ A F G A@7 H ~ G ~@2 A G A
  ~ A J
>`.pickRestart({
  A: "x", B: "~@15 x", C: "x!2", D: "~@3 x", E: "x ~@14 x", F: "x ~ x!2", G: "x ~@10 x ~@4", H: "~@3 x ~@7 x ~@4",
  I: "~@3 x ~@12", J: "~@7 x ~@4 x ~@3",
})).gain(0.31)

// drums · kick · soft notes
const kick_soft = s("bd").struct("<~@7 A ~@16 B ~@9 B ~@12 A ~@9 B ~@12>".pickRestart({
  A: "~@7 x ~@8", B: "~@15 x",
})).gain(0.2)

// drums · rim
const rim = s("rim").struct(`<
  A@3 ~ A B A ~ A@2 B ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A@3 ~ A ~ A@3 ~ A ~@3
>`.pickRestart({
  A: "~ x ~ x", B: "~ x ~@2",
})).gain(0.31)

// drums · snare
const snare = s("sd").struct(`<
  ~@3 A ~ A B C ~@2 D A ~@2 E A ~@3 F B ~@2 G ~@3 H B ~@2 H ~@3 G B I ~ J ~@3 K ~@2 I C ~@2 E H B ~ I B ~@3 G ~ L B ~ I
  H ~ J M N
>`.pickRestart({
  A: "~@7 x ~@8", B: "~@3 x ~@12", C: "~@3 x ~@7 x ~@4", D: "~@11 x ~@4", E: "~@11 x ~@3 x", F: "~@11 x!2 ~@3",
  G: "x ~@7 x ~@6 x", H: "~@3 x ~@3 x!2 ~@7", I: "~@15 x", J: "x ~@6 x!2 ~@7", K: "x ~@6 x ~@7 x", L: "~@3 x",
  M: "~@3 x ~@3 x ~@3 x ~ x ~ x", N: "x ~@2 x!2 ~@11",
})).gain(0.31)

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

// drums · low tom
const low_tom = s("lt").struct("<~@3 A ~@7 A ~@3 A ~@23 B ~@15 C ~@11 B ~@2>".pickRestart({
  A: "~@8 x ~@2 x!2 ~@3", B: "~@3 x ~@7 x ~@3 x", C: "~@13 x ~ x",
})).gain(0.41)

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

// drums · hihat · soft notes
const hihat_soft = s("hh").struct("<A B@2 ~@5 A@2 B ~@13 A B@2 ~@5 A B@2 ~@5 B A B ~@13 B@2 A ~@2 C ~@8>".pickRestart({
  A: "~@7 x ~@7 x", B: "~@7 x ~@8", C: "~@11 x ~@4",
})).gain(0.26)

// drums · mid tom
const mid_tom = s("mt").struct("<~@5 A ~@21 A ~@3 A ~@19 A ~@3 B ~@9 A ~@4>".pickRestart({
  A: "~@12 x ~@2 x", B: "~@11 x ~@4",
})).gain(0.31)

// drums · open hat
const open_hat = s("oh").struct(`<
  ~@5 A B C ~@2 D ~@3 E ~@4 F ~@2 B ~@17 F B ~@4 B C ~@2 E ~@3 B C F ~ B ~@5 B ~@3 G ~
>`.pickRestart({
  A: "~@7 x ~@8", B: "~@11 x ~@4", C: "~ x ~ x", D: "~@2 x!2", E: "~@3 x ~@12", F: "~@15 x", G: "~@3 x",
})).gain(0.31)

// drums · high tom
const high_tom = s("ht").struct("<~@3 A ~@7 A ~@3 A ~@27 B ~@11 C ~@14>".pickRestart({
  A: "x", B: "~@8 x ~@2 x!2 ~@3", C: "~ x",
})).gain(0.36)

// drums · high tom · soft notes
const high_tom_soft = s("ht").struct("<~@3 A ~@7 A ~@3 A ~@39 B ~@14>".pickRestart({
  A: "~@3 x ~@12", B: "~@7 x ~@8",
})).gain(0.2)

// drums · crash
const crash = s("cr").struct(`<
  A ~@3 A ~@3 A ~@3 A ~ B ~ A ~@3 A ~@3 A ~@2 A@2 ~@2 A@2 ~@3 A ~@3 A ~@3 A ~@3 A ~ B A@2 ~@2 A@2 ~@3 A ~ A ~@2 A@2 ~ A
  C
>`.pickRestart({
  A: "x", B: "~@3 x", C: "~@7 x ~@8",
})).gain(0.36)

// drums · ride
const ride = s("rd").struct(`<
  ~@3 A B C@2 D ~@3 A B C E A B C F G H F C I ~@3 J B F C J ~@3 I B I F ~@5 B K C D H F E J H F C ~@4 I B G B K C J B ~
  L ~
>`.pickRestart({
  A: "~@4 x ~@10 x", B: "x!4", C: "x ~@3 x ~@3 x ~@3 x ~@2 x", D: "x ~@2 x ~@3 x!2 ~@6 x", E: "x ~@3 x ~@3 x ~@6 x",
  F: "x ~@2 x!2 ~@3 x ~@3 x ~@3", G: "x!2 ~@2", H: "x ~@3 x ~@3 x ~@2 x!2 ~@3", I: "x ~@3 x ~@2 x!2 ~@3 x ~@3",
  J: "x!3 ~", K: "x ~@3 x ~@2 x!2 ~@2 x!2 ~@3", L: "~ x",
})).gain(0.36)

// drums · ride · soft notes
const ride_soft = s("rd").struct(`<
  ~@4 A B@2 ~@5 A B@2 ~ A B C ~ A C B ~@4 B A C B@2 ~@4 A C@2 ~@5 A C B ~ A C B@2 A C B ~@5 A ~ A C B@2 A ~@3
>`.pickRestart({
  A: "~@7 x ~@7 x", B: "~@7 x ~@8", C: "~@15 x",
})).gain(0.2)
// … 5 more lines

More by Ellington