Strudelify

Love Grows (Where My Rosemary Goes)

Edison Lighthouse

KeyB♭ majorTempo109 bpm
0:00/0:00
// Love Grows (Where My Rosemary Goes) — Edison Lighthouse
// 109 bpm, 4/4, key Bb major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: pitch bends are ignored
// note: Full arrangement: all 78 bars on a 16-step grid, each part at one level; ghost notes are separate "_soft" parts. Source detail keeps the original performance.
setcpm(109/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 pick
const bass = note(`<
  A@4 B@3 C D@2 E F D G B C D@2 E F H G B I J K L I M N G B C D@2 E F O G P F Q B@2 I J K L I M R G S T U V@2 W X Y S Z
  X AA T Z X AA T Z X AA T Z X AA T ~
>`.pickRestart({
  A: "a1@2 a1!2 b1@2 e2@4 e2@2 e2@2 a2@2", B: "a1!8", C: "a1!6 gb2 e2", D: "d2!8", E: "a1!4 db2!4", F: "gb1!4 a1!4",
  G: "e2!8", H: "d2!3 db2 b1!4", I: "d2!4 e2!3 ab1", J: "a1@2 a1@2 a1@2 e2@2 gb2@2 gb2@2 gb2 e2 db2 a1",
  K: "b1@2 b1@2 b1@2 b1 gb2 e2@2 e2@2 e2 db2 b1@2", L: "a1@2 a1@2 a1@2 a1@2 a1@2 a1@2 a1@2 a1 db2",
  M: "a1@2 a1@2 a1@2 a1@2 gb2@2 gb2@2 gb2 e2 db2 a1", N: "b1!8", O: "d2!2 db2!2 b1!4", P: "a1!4 ab1!4", Q: "d2!4 e2!4",
  R: "b1@2 b1@2 eb2@2 eb2 e2 gb2@2 gb2@2 ab2@2 gb2@2", S: "f2!8", T: "bb1!8", U: "bb1!6 g2 f2", V: "eb2!8",
  W: "bb1!4 d2!4", X: "g1!4 bb1!4", Y: "eb2!3 d2 c2!4", Z: "bb1!4 a1!4", AA: "eb2!4 f2!4",
})).s("gm_electric_bass_pick").gain(0.7)

// other · overdriven guitar
const overdriven_guitar = note("<A@6 ~@36 A@2 ~@20 B ~@3 B ~@3 B ~@5>".pickRestart({
  A: "a2@2 a2!2 b2@2 e3@4 e3@2 e3@2 a3@2", B: "bb2@2 bb2!2 c3@2 f3@4 f3@2 f3@2 bb3@2",
})).s("gm_overdriven_guitar").gain(0.48).pan(0)

// other · overdriven guitar · soft notes
const overdriven_guitar_soft = note("<~@76 [bb2@2 bb2!2 c3@2 f3@4 f3@2 f3@2 bb3@2] ~>")
  .s("gm_overdriven_guitar").gain(0.06).pan(0)

// other · piano · A B E A
const piano = note("<~@2 [[a1,a2]@2 [a1,a2]!2 [b1,b2]@2 [e2,e3]@4 [e2,e3]@2 [e2,e3]@2 [a2,a3]@2]!4 ~@72>")
  .s("gm_piano").gain(0.4).pan(1)

// other · string ensemble 1
const string_ensemble_1 = note(`<
  ~@4 A B ~@3 C D E F G ~@3 C D E H@2 I J K J L J K M N ~@3 C D E H@2 D E F O@2 J K J P J K M Q R ~@3 S T U V@2 T U W X
  T U W X T U W X Y ~@4
>`.pickRestart({
  A: "a3!2 db4 e4@2 e4 gb4 a4", B: "a4!2 db5 e5@2 e5 gb5 a5", C: "~@8 db5@3 ~ d5@3 ~", D: "e5@5 ~ gb5@4 ~@2 db5@2 b4@2",
  E: "a4 gb4 a4 db5@2 ~ b4@2", F: "a4 gb4 a4 d5@2 ~ db5@2", G: "b4@3 ~", H: "[a4 gb4 a4 d5@8 ~ db5@4]/2",
  I: "[a3,a4]@8 ~ b3 db4 d4 e4 gb4 ab4 a4, ~@2 a3 ~", J: "d5 b4", K: "e5 db5", L: "db5@3 ~", M: "b4 eb5", N: "e5@3 ~",
  O: "[~@24 a3 b3 db4 d4 e4 gb4 ab4 a4, a4@7 ~]/2", P: "db5@7 ~", Q: "e5", R: "f5",
  S: "~@8 eb4 f4 g4 ab4 bb4 c5 d5 eb5", T: "f5@5 ~ g5@4 ~@2 d5@2 c5@2", U: "bb4 g4 bb4 d5@2 ~ c5@2",
  V: "[bb4 g4 bb4 eb5@8 ~ d5@4]/2", W: "bb4 g4 bb4 eb5@2 ~ d5@2", X: "bb4", Y: "f5@5 ~ g5@4 ~@6",
})).s("gm_string_ensemble_1").gain(0.4).pan(0)

// other · string ensemble 1 · soft notes
const string_ensemble_1_soft = note("<~@73 [~@6 d5 c5] [bb4 g4 bb4 d5@2 ~ c5@2] [bb4 g4 bb4 eb5@2 ~ d5@2] bb4 ~>")
  .s("gm_string_ensemble_1").gain(0.2).pan(0)

// other · string ensemble 1
const string_ensemble_1_2 = note(`<
  ~@9 A B C D E ~@3 A B C F@2 G H I H J H I K L ~@3 A B C F@2 B C D M@2 H I H N H I K O P@3 Q@2 R S T@2 R S U V R S U V
  R S U V W ~@4
>`.pickRestart({
  A: "~@8 db6@3 ~ d6@3 ~", B: "e6@5 ~ gb6@4 ~@2 db6@2 b5@2", C: "a5 gb5 a5 db6@2 ~ b5@2", D: "a5 gb5 a5 d6@2 ~ db6@2",
  E: "b5@3 ~", F: "[a5 gb5 a5 d6@8 ~ db6@4]/2", G: "a5@8 a4 b4 db5 d5 e5 gb5 ab5 a5", H: "d6 b5", I: "e6 db6",
  J: "db6@3 ~", K: "b5 eb6", L: "e6@3 ~", M: "[~@24 a4 b4 db5 d5 e5 gb5 ab5 a5, a5@7 ~]/2", N: "db6@7 ~", O: "e6",
  P: "[f6@5 f5 a5 f6@17]/3", Q: "[d7@24 eb5 f5 g5 ab5 bb5 c6 d6 eb6]/2", R: "f6@5 ~ g6@4 ~@2 d6@2 c6@2",
  S: "bb5 g5 bb5 d6@2 ~ c6@2", T: "[bb5 g5 bb5 eb6@8 ~ d6@4]/2", U: "bb5 g5 bb5 eb6@2 ~ d6@2", V: "bb5",
  W: "f6@5 ~ g6@4 ~@6",
})).s("gm_string_ensemble_1").gain(0.4).pan(1)

// other · string ensemble 1 · soft notes
const string_ensemble_1_soft_2 = note("<~@73 [~@6 d6 c6] [bb5 g5 bb5 d6@2 ~ c6@2] [bb5 g5 bb5 eb6@2 ~ d6@2] bb5 ~>")
  .s("gm_string_ensemble_1").gain(0.2).pan(1)

// chords · electric guitar muted
const electric_guitar_muted = note(`<
  ~@6 A B C@2 D E F G A B C@2 D E H I A J K L A J K M G A B C@2 D E N I D E O A@2 J K L A J K P G Q R S T@2 U V W X Y V
  Z R Y V Z R Y V Z R Y V Z R ~
>`.pickRestart({
  A: "[a2,e3]!2 [a2,gb3]!2 [a2,e3]!2 [a2,gb3]!2", B: "[a2,e3]!2 [a2,gb3]!2 [a2,e3]!2 [a2,gb3] [a2,e3]",
  C: "[d3,a3]!2 [d3,b3]!2 [d3,a3]!2 [d3,b3]!2", // D5 G D5 G
  D: "[a2,e3]@2 [a2,e3]@2 e3@3 ~ [db3,ab3]@2 [db3,ab3]@2 [db3,ab3]@2 [db3,ab3]@2, ~@4 a2 ~@2 [a2,e3]@2 ~@7", // A5 Db5 A5
  E: "[gb2,db3]@2 [gb2,db3]@2 [gb2,db3]@3 [gb2,db3] [a2,e3]@2 [a2,e3]@2 [a2,e3]@2 [a2,e3]@2", F: "[d3,a3]!8",
  G: "[e3,b3]!2 [e3,db4]!2 [e3,b3]!2 [e3,db4]!2", H: "[d3,a3]!4 [gb3,b3]!4", I: "[e3,b3]!8",
  J: "[d3,a3]@2 [d3,a3]@2 [d3,a3]@3 [d3,a3] [e3,b3]@2 [e3,b3]@2 [e3,b3]@2 [e3,b3]@2", // D5 E5
  K: "[a2,e3]@2 [a2,e3]@2 [a2,e3]@3 [a2,e3] [a2,e3]@2 [a2,e3]@2 [a2,e3]@2 [a2,e3]@2", // A5
  L: "[b2,gb3]@2 [b2,gb3]@2 [b2,gb3]@3 [b2,gb3] [e3,b3]@2 [e3,b3]@2 [e3,b3]@2 [e3,b3]@2", // B5 E5
  M: "[b2,gb3]!2 [b2,ab3]!2 [b2,a3]!2 [b2,ab3] [b2,gb3]", N: "[d3,a3]!2 [db3,a3]!2 [gb3,b3]!4",
  O: "[d3,a3]!4 [e3,b3]!4", P: "[b2,gb3]!2 [b2,ab3]!2 [b2,gb3]!2 [b2,ab3]!2",
  Q: "[f3,c4]!2 [f3,d4]!2 [f3,c4]!2 [f3,d4]!2", R: "[bb2,f3]!2 [bb2,g3]!2 [bb2,f3]!2 [bb2,g3]!2",
  S: "[bb2,f3]!2 [bb2,g3]!2 [bb2,f3]!2 [bb2,g3] [bb2,f3]", T: "[eb3,bb3]!2 [eb3,c4]!2 [eb3,bb3]!2 [eb3,c4]!2",
  U: "[bb2,f3]@2 [bb2,f3]@2 f3@3 ~ [d3,a3]@2 [d3,a3]@2 [d3,a3]@2 [d3,a3]@2, ~@4 bb2 ~@2 [bb2,f3]@2 ~@7", // Bb5 D5 Bb5
  V: "[g2,d3]@2 [g2,d3]@2 [g2,d3]@3 [g2,d3] [bb2,f3]@2 [bb2,f3]@2 [bb2,f3]@2 [bb2,f3]@2", W: "[eb3,bb3]!4 [g3,c4]!4",
  X: "[f3,c4]!8", Y: "[bb2,f3]!4 [a2,d3]!4", Z: "[eb3,bb3]!4 [f3,c4]!4",
})).s("gm_electric_guitar_muted").gain(0.57).pan(0)

// chords · electric guitar clean
const electric_guitar_clean = note(`<
  ~@6 A@2 B C D E F G A@2 B C D E C G H I H I H I H J G A@2 B C D E F G D E K H@2 I H I H I H J G L M@2 N O P Q O L P Q
  R S P Q R S P Q R S P Q R S ~
>`.pickRestart({
  A: "[[a3,e4] ~ [a3,e4]@2 [a3,gb4]@2 [a3,gb4]@2 [a3,e4]@2 [a3,e4]@2 [a3,gb4]@2 [a3,e4]@4 [a3,e4]@2 [a3,gb4]@2 [a3,gb4]@2 [a3,e4]@2 [a3,e4]@2 [a3,gb4]@2 [a3,e4]@2]/2", // A5 D A5 D A5 D A5 D …
  B: "[a3,d4,gb4]!2 [a3,d4,gb4,db5]!2 [a3,d4,gb4]!4", C: "[a3,d4,gb4]!8",
  D: "[a3,db4,e4]@4 [e4,a4,db5] ~@3 [ab3,db4,e4]@4 [e4,ab4,db5] ~@3", // A Dbm
  E: "[a3,db4,gb4]@4 [a4,db5] ~@3 [a3,db4,e4]@2 ~@2 [e4,a4,db5]@2 ~@2, ~ gb4 ~@2", // Gbm A
  F: "[a3,d4,gb4]@2 [a3,d4,gb4]@2 [a3,d4,gb4]@2 [a3,d4,gb4] [d4,gb4] [a3,d4,gb4]@2 [a3,d4,gb4]@2 [a3,d4,gb4]@2 [a3,d4,gb4]@2", // D
  G: "[b3,e4,ab4]!8", H: "~ [a3,e4] [a3,gb4]!2 [a3,e4]!2 [a3,gb4] [a3,e4]", I: "[a3,d4,gb4]!4 [b3,e4,ab4]!4",
  J: "~ [b3,gb4] [b3,ab4]!2 [b3,gb4]!2 [b3,ab4] [b3,gb4]", // B5 E B5 E B5
  K: "[a3,d4,gb4]@2 [a3,d4,gb4]@2 [a3,d4,gb4]@2 [a3,d4,gb4] [d4,gb4] [b3,e4,ab4]@2 [b3,e4,ab4]@2 [b3,e4,ab4]@2 [b3,e4,ab4]@2", // D E
  L: "[c4,f4,a4]!8", // F
  M: "[[bb3,f4] ~ [bb3,f4]@2 [bb3,g4]@2 [bb3,g4]@2 [bb3,f4]@2 [bb3,f4]@2 [bb3,g4]@2 [bb3,f4]@4 [bb3,f4]@2 [bb3,g4]@2 [bb3,g4]@2 [bb3,f4]@2 [bb3,f4]@2 [bb3,g4]@2 [bb3,f4]@2]/2", // Bb5 Eb Bb5 Eb Bb5 Eb Bb5 Eb …
  N: "[bb3,eb4,g4]!2 [bb3,eb4,g4,d5]!2 [bb3,eb4,g4]!4", O: "[bb3,eb4,g4]!8",
  P: "[bb3,d4,f4]@4 [f4,bb4,d5] ~@3 [a3,d4,f4]@4 [f4,a4,d5] ~@3", // Bb Dm
  Q: "[bb3,d4,g4]@4 [bb4,d5] ~@3 [bb3,d4,f4]@2 ~@2 [f4,bb4,d5]@2 ~@2, ~ g4 ~@2", // Gm Bb
  R: "[bb3,eb4,g4]@2 [bb3,eb4,g4]@2 [bb3,eb4,g4]@2 [bb3,eb4,g4] [eb4,g4] [c4,f4,a4]@2 [c4,f4,a4]@2 [c4,f4,a4]@2 [c4,f4,a4]@2", // Eb F
  S: "~ [bb3,f4] [bb3,g4]!2 [bb3,f4]!2 [bb3,g4] [bb3,f4]", // Bb5 Eb Bb5 Eb Bb5
})).s("gm_electric_guitar_clean").gain(0.22).pan(1)

// other · trombone
const trombone = note(`<
  ~@10 A B C D ~@4 A B E D@2 ~@2 F G H I J K ~@4 A B E D L M N O ~@3 F G H I J P Q ~@4 R S T U R V W X R V W X R V W X R
  ~@4
>`.pickRestart({
  A: "e4@3 ~@3 ab4@8 ~@2", B: "gb4@3 ~@3 a4@8 ~@2", C: "gb4@3 ~", D: "e4@3 ~", E: "gb4", F: "~ ab4", G: "a4 ~",
  H: "a4 ab4", I: "e4 a4", J: "gb4 a4", K: "ab4 ~", L: "a4@3 ~@3 ab4@8 ~@2", M: "a4@3 ~@3 a4@8 ~@2", N: "gb4 e4",
  O: "e4", P: "[ab4,b4]", Q: "[a4,c5]", R: "[bb3,f4]@3 ~@3 [a3,a4]@8 ~@2", S: "[g3,g4]@3 ~@3 [bb3,bb4]@8 ~@2", T: "g4",
  U: "f4@3 ~", V: "[g3,g4]@3 ~@3 bb4@8 ~@2", W: "g4 f4", X: "f4",
})).s("gm_trombone").gain(0.32).pan(1)

// other · trombone · soft notes
const trombone_soft = note("<~@74 [g4@3 ~@3 bb4@8 ~@2] [g4 f4] f4 ~>").s("gm_trombone").gain(0.12).pan(1)

// other · trumpet
const trumpet = note(`<
  ~@10 A@2 B C ~@4 A@2 D C E ~@2 F G H I J K ~@4 A@2 D C L M N O ~@3 F G H I J P Q ~@4 R@2 S E R@2 T U R@2 T U R@2 T U R
  ~@4
>`.pickRestart({
  A: "a4@3 ~@3 e4@8 ~@2", B: "d4@3 ~", C: "ab4@3 ~", D: "d4", E: "a4@3 ~", F: "~ e4", G: "db4 ~", H: "gb4 e4",
  I: "db4!2", J: "b3", K: "e4 ~", L: "e4@3 ~@3 e4@8 ~@2", M: "gb4@3 ~@3 e4@8 ~@2", N: "d4 e4", O: "a4", P: "e4",
  Q: "f4", R: "bb4@3 ~@3 f4@8 ~@2", S: "eb4", T: "eb4@8 bb4@3 ~ a4@3 ~", U: "bb4",
})).s("gm_trumpet").gain(0.32).pan(0)

// other · trumpet · soft notes
const trumpet_soft = note("<~@74 [bb4@3 ~@3 f4@8 ~@2] [eb4@8 bb4@3 ~ a4@3 ~] bb4 ~>").s("gm_trumpet").gain(0.12).pan(0)

// other · electric guitar clean
const electric_guitar_clean_2 = note("<~@13 [~@4 bb3!4] ~@33 [~@8 eb4@2 e4@2 e4 d4 db4@2] ~@30>")
  .s("gm_electric_guitar_clean").gain(0.4).pan(1)

// drums · kick
const kick = s("bd").struct(`<
  ~@2 A@2 B C D@3 E D@3 F D@3 E D@3 E G D@3 G D@3 G D@3 G D@3 E D@12 G@2 D@3 E D@3 G D@16 ~
>`.pickRestart({
  A: "x ~@2 x ~@2 x ~@3 x ~@3 x ~", B: "x!2 ~ x!3 ~ x", C: "x!2 ~ x ~ x ~@2", D: "x!2", E: "x ~@4 x ~ x", F: "x ~@6 x",
  G: "x",
})).gain(0.78)

// drums · snare
const snare = s("sd").struct(`<
  ~@2 A@3 B C D@2 E D@3 F C D@2 E D@3 E G D@3 G D@3 G C D@2 H D@3 E D@12 I@2 C D@2 E D J D K D@16 ~
>`.pickRestart({
  A: "~ x ~ x", B: "~@4 x ~@3 x ~@2 x!2 ~ x ~", C: "~@4 x ~@2 x ~@4 x ~@2 x", D: "~@4 x ~@2 x ~@4 x ~@3", E: "~ x!3",
  F: "~@4 x ~@2 x!4 ~ x ~@3", G: "~@4 x ~ x!5 ~ x ~ x ~", H: "~@4 x ~@3 x!2 ~@2 x!2 ~@2", I: "~@4 x ~@2 x!4 ~ x ~ x ~",
  J: "~@4 x ~@2 x ~@4 x!3 ~", K: "~@4 x ~@3 x!8",
})).gain(0.78)

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

// drums · crash
const crash = s("cr").struct("<~@10 A ~@6 B A ~@4 A ~@10 C ~@4 A ~@4 A ~@11 B A ~@3 A ~@3 A ~@3 A ~@8>".pickRestart({
  A: "x", B: "~@2 x!2", C: "~@5 x ~ x",
})).gain(0.78)

// drums · tambourine
const tambourine = s("tb").struct("<~@4 [~ x ~ x]!22 [x!4] [~ x ~ x]!7 [~ x ~@2] [~ x ~ x]!42 ~>").gain(0.78)

stack(
  bass, overdriven_guitar, overdriven_guitar_soft, piano, string_ensemble_1, string_ensemble_1_soft,
  string_ensemble_1_2, string_ensemble_1_soft_2, electric_guitar_muted, electric_guitar_clean, trombone, trombone_soft,
  trumpet, trumpet_soft, electric_guitar_clean_2, kick, snare, hihat, crash, tambourine
)