Strudelify
Menuet cover art
KeyG majorTempo108 bpm
0:00/0:00
// Menuet — Ludwig van Beethoven
// 108 bpm, 4/4, key G major. Source: midi.
// Generated by strudelify. One cycle = one bar.
// note: duplicate parts dropped: ch 2 pad new age (copy of ch 1 piano)
// note: Full arrangement: all 74 bars on a 32-step grid, each part at one level. Source detail keeps the original performance.
setcpm(108/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, A@4 for four bars: edit a riff to change every repeat.

// other · string ensemble 1
const string_ensemble_1 = note(`<
  ~ A B C@5 D E F@2 G@2 H ~ I@2 J K B L ~ M N@2 O P Q R@3 S P T ~ U@2 V W X@2 Y Z ~ AA AB@2 AC@2 AD AE AF AG AH AI AJ O
  AK AL AM@2 B AN@2 AO AP AQ AR AS AT@2 AU AV
>`.pickRestart({
  A: "b3@2 ~@6 b3@2 ~@6 g2@3 ~@13", B: "~@15 d4@2 ~@15",
  C: "[~@8 g3@2 ~@21 [f#3,c4]@2 ~@6 c4@2 ~@14 [g3,b3]@2 ~@6 g3@2 ~@6 g2@3 ~@13 [g3,b3]@2 ~@6 e2@2 ~@22 d2@3 ~@5 d4@2 ~@6 [a2,a3]@2 ~@23, ~@127 a3 ~@32]/5", // F#dim G A
  D: "~@7 g2@2 ~@7 g3 ~@15", E: "~@4 g3 ~@11",
  F: "[~@15 g2@3 ~@5 [g3,b3,d4] ~@7 g3@2 ~@6 g2@3 ~@13 g3@2 ~@7, ~@31 b3 ~@32]/2", // G
  G: "[~@7 g3@2 ~@6 g3@2 ~@14 d4@2 ~@6 [a2,g3,c#4]@2 ~@23]/2", H: "~@8 g2@3 ~@4 b3 ~@16",
  I: "[~@8 c3@2 ~@6 d3@2 ~@5 d4@2 ~@6 [a3,d4]@2 ~@14 g3@2 ~@15, ~@47 b3 ~@16]/2", J: "~@15 [e3,d4,e4]@2 ~@15",
  K: "~@7 c4 ~@15 [b3,d4]@2 ~@7", L: "~@31 d4", M: "~@15 [g3,b3]@2 ~@6 [g3,b3] ~@8",
  N: "[~@15 [e3,g#3,d4]@2 ~@14 a3@2 ~@6 [c4,d4]@2 ~@7 d4@2 ~@14, ~@47 g2@4 ~@13]/2", O: "~@8 g3 ~@7",
  P: "~@23 g2@3 ~@6", Q: "~@15 d3@3 ~@6 f#3 ~@7", R: "[~@16 g3@2 ~@6 g3 ~@6 a2@2 ~@30 c#4@2 ~@6 c#4@2 ~@23]/3",
  S: "~@15 b3 ~@7 d4@2 ~@7", T: "~@7 g3@2 ~@15 f#3 ~@7, ~@23 [c4,d4]@2 ~@7",
  U: "[~@16 d4@2 ~@6 a2@3 ~@4 g3@2 ~@14 d4@2 ~@15, ~@31 c#4 ~@32]/2", V: "~@12 [c4,d4] ~@3", W: "~@15 f#3@2 ~@15",
  X: "[~@7 f#3@2 ~@22 d4@2 ~@7 g2@3 ~@4 b3 ~@16]/2", Y: "c3@2 ~@5 g3 ~@15 d2@2 ~@7", Z: "~@3 c4 ~@12",
  AA: "~@7 d4@2 ~@23", AB: "[~@31 c4@2 ~@22 b3 ~@8]/2", AC: "[~@7 c4@2 ~@6 g3@2 ~@14 d4@2 ~@31, ~@15 e4 ~@48]/2",
  AD: "~@15 b3 ~@7 b3@2 ~@7", AE: "~@7 g3@2 ~@7 d4@2 ~@14", AF: "d4@2 ~@5 c4@2 ~@14 [g3,b3]@2 ~@7, f#3 ~@31",
  AG: "~@23 g3@2 ~@7", AH: "~@7 e4@2 ~@23", AI: "~@15 f#3@10 ~@7", AJ: "~@8 g2@3 ~@21", AK: "d4 ~@31",
  AL: "g3@2 ~@5 g2@3 ~@5 b3@2 ~@15, b3 ~@31",
  AM: "[~@7 b3 ~@7 e3@2 ~@6 d3@2 ~@6 [a3,d4]@2 ~@7 g3@2 ~@13 d3@3 ~@6, ~@39 a2@3 ~@22]/2", // D5
  AN: "[d3@3 ~@4 a3@2 ~@14 g2@3 ~@5 g3@2 ~@30 a3, ~@31 d4 ~@32]/2", AO: "~@8 g2@2 ~@6 d4 ~@15", AP: "~@15 e4@2 ~@15",
  AQ: "~@7 f#3@2 ~@6 b3@4 ~@13", AR: "~@15 [b3,d4]@2 ~@6 [b3,d4]@2 ~@7, ~@15 g3 ~@16",
  AS: "~@8 [f#3,c4,d4]@2 ~@21 [g3,b3]", AT: "[~@15 d3@2 ~@14 f#3@2 ~@22 b3 ~@8]/2",
  AU: "~@8 g3@2 ~@5 e4@3 ~@6 a3@3 ~@5, ~@7 f4@2 ~@23", AV: "c4 ~@22 b3@2 ~@7",
})).s("gm_string_ensemble_1").gain(0.2).pan(1)

// other · string ensemble 1
const string_ensemble_1_2 = note(`<
  ~ A B C D E F G H I@2 J K L M N O P Q R S T U@3 ~ V@2 ~ W X@2 Y Z AA@2 ~ AB T AC@2 AD AE@2 AF AG AH AI AJ@2 AK AL AM
  AN AO@2 AP@2 AQ AR ~ AS AT AU AV@3 AW AX@3 AY AZ BA
>`.pickRestart({
  A: "g3 ~@3 d4 ~@7 g3 ~@3", B: "~@8 g2@3 ~@5 g3@2 ~@5 b3@2 ~@7", C: "~@8 b3@2 ~@6 d4 ~@15", D: "~@7 d4@2 ~@23",
  E: "d4 ~@14 g3@2 ~@15", F: "~@7 e4@2 ~@6 e4@2 ~@15, ~@15 b3 ~@16", G: "~@23 d3@3 ~@6", H: "~@16 d4@2 ~@5 b3@2 ~@7",
  I: "[g2@2 ~@6 d4 ~@14 d3@3 ~@5 [c4,d4]@2 ~@6 [f#3,c4]@2 ~@23]/2", J: "~@15 [g3,d4]@2 ~@6 b3 ~@8",
  K: "~@7 [b3,e4]@2 ~@6 b3 ~@16", L: "~@7 a3 ~@7 d3@2 ~@6 d4@2 ~@7", M: "~@15 g3@2 ~@15", N: "~@8 [a3,c4,d4] ~@7",
  O: "~@23 c4@2 ~@6 f#3", P: "~@7 g2@2 ~@23", Q: "~@7 g3 ~@24", R: "~@7 d3@2 ~@23", S: "~@15 b3@2 ~@6 b3 ~@8",
  T: "~@16 f#3 ~@15", U: "[~@7 c3@2 ~@6 d3@3 ~@5 [f#3,d4]@2 ~@6 d4@2 ~@6 g2@3 ~@21 g2@2 ~@15 e4@2 ~@14]/3",
  V: "[~@8 g2@3 ~@13 b3 ~@6 d3@3 ~@5 [f#3,d4]@2 ~@6 f#3 ~@15 d4]/2", W: "[c4,d4]@2 ~@22 b3 ~@7",
  X: "[~@7 a3 ~@7 [d3,a3]@2 ~@14 g3@2 ~@6 g3@2 ~@6 d4@3 ~@14]/2", Y: "~@8 g2@3 ~@4 [g3,d4]@2 ~@6 g3@2 ~@7",
  Z: "~@7 f#3@2 ~@6 f#3@2 ~@14 b3", AA: "[~@31 [c4,d4]@2 ~@14 g3@2 ~@6 g3@2 ~@7, ~@47 b3 ~@16]/2", AB: "~@7 c#4@2 ~@23",
  AC: "[d3@2 ~@29 d4@2 ~@22 d4@2 ~@6 c4, ~@55 f#3 ~@8]/2", AD: "~@15 g3 ~@7 g3@2 ~@7",
  AE: "[~@7 e4@2 ~@22 c4@2 ~@6 d4@2 ~@6 g2@3 ~@5 [g3,b3]@2 ~@7]/2", AF: "~@7 d3@3 ~@13 c4@2 ~@7", AG: "~@15 c4@2 ~@15",
  AH: "~@7 f#3@2 ~@14 d4@2 ~@7", AI: "~@7 g2@3 ~@5 g3 ~@16",
  AJ: "[~@7 [g3,e4]@2 ~@6 c4@2 ~@6 d2@2 ~@6 c4@2 ~@6 c4@2 ~@6 d2@4 ~@13]/2", AK: "~@7 g2@3 ~@5 d4@2 ~@15",
  AL: "~@15 b3@2 ~@6 d3@3 ~@6", AM: "c4 ~@15", AN: "[g3,d4]@2 ~@5 g2@3 ~@5 g3@2 ~@6 b3@2 ~@7",
  AO: "[~@15 e4@2 ~@15 d4@2 ~@5 g3@2 ~@6 [d3,d4]@10 ~@7, ~@15 b3 ~@15 a3@2 ~@31]/2", // D
  AP: "[~@16 d4 ~@6 [g3,b3] ~@7 g2@2 ~@14 b3@2 ~@6 d3@3 ~@5 f#3, ~@15 g3@2 ~@47]/2", AQ: "~@7 [c4,d4]@2 ~@23",
  AR: "d4@2 ~@13 [g3,d4]@2 ~@6 g3@2 ~@7", AS: "~@7 a3@2 ~@7 d4@10 ~@6, ~@16 d3@3 ~@13",
  AT: "~@8 g2@4 ~@3 b3@2 ~@6 b3@2 ~@7", AU: "~@7 d4@2 ~@7 d4@2 ~@14, ~@16 f#3 ~@15",
  AV: "[~@7 [c3,c4]@3 ~@5 d3@3 ~@5 d4 ~@8 f#3 ~@23 g3@2 ~@5 g2@3 ~@13 d4@2 ~@7 [c4,e4]@5 ~@3, ~@31 d4@2 ~@23 b3 ~@39]/3", // C
  AW: "~@15 [g2,g3,d4]@5 ~@12", AX: "[~@31 d3@3 ~@13 [f#3,c4,d4]@2 ~@6 g2@2 ~@6 d4@2 ~@31]/3",
  AY: "d4 ~@14 g3@2 ~@15, ~@15 d4 ~@16", AZ: "~@15 e3@2 ~@15", BA: "~@23 d4@2 ~@7",
})).s("gm_string_ensemble_1").gain(0.25).pan(0.6)

// other · string ensemble 1
const string_ensemble_1_3 = note(`<
  ~ A B@2 C D E F G H@4 I J K L@2 M@2 N O P@2 Q R S T@2 U V@2 W@2 X Y@2 Z AA AB AC AD AE@3 AF AG AH AI AJ AK AL AM AN AO
  AP C AQ AR ~ AS@2 AT AU AV AL AW ~@3 AX AY@2 AZ
>`.pickRestart({
  A: "d4 ~@3 g3 ~@7 [b3,d4] ~@3", B: "[~@23 d4@2 ~@6 g2@2 ~@15 [g3,b3]@2 ~@14]/2", C: "~@23 d4@2 ~@7",
  D: "~@15 d4@2 ~@15", E: "~@7 b3@2 ~@7 g3@2 ~@14", F: "f#3 ~@6 g3@2 ~@7 d3@2 ~@5 [f#3,a3]@2 ~@7",
  G: "~@23 [g3,d4]@2 ~@7", H: "[~@16 g3@2 ~@13 f#3@2 ~@6 d4@2 ~@22 d4@2 ~@30 e2@3 ~@13 e4 ~@16]/4", I: "~@23 a3@2 ~@7",
  J: "~@23 b3 ~@8", K: "d3@2 ~@6 [f#3,c4] ~@15 g2@2 ~@6", L: "[b3 ~@7 [g3,c4]@2 ~@13 f#3@2 ~@6 c4@2 ~@31]/2",
  M: "[~@7 [b3,f4]@2 ~@6 g#3@2 ~@6 a2@3 ~@5 [a3,c4]@2 ~@6 [f#3,d4]@2 ~@6 g2@2 ~@6 g3@2 ~@7, ~@31 e4 ~@32]/2", // Bdim Am D
  N: "~@7 g2@3 ~@13 g3@2 ~@7", O: "~@8 c4@2 ~@13 g2@2 ~@6 g3",
  P: "[~@7 [g3,c4,e4]@2 ~@14 c4@2 ~@6 [f#3,c4]@2 ~@14 d4@2 ~@6 d4 ~@8]/2", Q: "~@8 g3@2 ~@21 [c4,e4], ~@8 b3 ~@23",
  R: "~@7 [d3,f#3]@2 ~@7 g3@2 ~@14", S: "~@8 [b3,d4] ~@7",
  T: "[~@15 d4@2 ~@14 b3@2 ~@6 [g3,d4]@2 ~@15 [c4,d4]@2 ~@6]/2", U: "f#3 ~@7 g2@3 ~@5 d4 ~@15",
  V: "[~@7 [g3,c#4]@2 ~@6 f#3@2 ~@6 a2@2 ~@6 a3@2 ~@31]/2", W: "[~@31 d3@3 ~@5 d4@2 ~@6 d4@2 ~@14 d4]/2",
  X: "g3 ~@30 f#3", Y: "[~@7 g2@3 ~@5 d4@2 ~@6 b3 ~@7 a2@3 ~@5 g3@2 ~@6 a3@2 ~@15]/2", Z: "~@7 g3@2 ~@6 a3@2 ~@15",
  AA: "~@8 [c4,d4] ~@7", AB: "~@8 [f#3,c4,d4]@2 ~@13 d3@3 ~@6", AC: "~@15 d3@2 ~@6 c4@2 ~@6 f#3",
  AD: "~@15 d4 ~@7 b3@2 ~@7",
  AE: "[~@15 e4@2 ~@14 d4@2 ~@30 b3@2 ~@14 [f#3,c4,d4]@2 ~@6 d4@2 ~@7, ~@15 c4 ~@71 f#3 ~@8]/3", // D7
  AF: "~@15 f#3@2 ~@13 f#3@2", AG: "~@7 [c4,d4]@2 ~@6 d3@2 ~@6 c4@2 ~@7", AH: "f#3 ~@14 b3 ~@16",
  AI: "c3@2 ~@21 d3@2 ~@7", AJ: "~@7 f#3 ~@24", AK: "~@23 g3@2 ~@7", AL: "~@8 g3 ~@7",
  AM: "~@7 d4@2 ~@23, ~@7 f#3 ~@24", AN: "~@15 b3 ~@7 d4@2 ~@7", AO: "~@7 b3@2 ~@14 d2@2 ~@7",
  AP: "~@7 [a2,c#4]@2 ~@23, ~@7 a3 ~@24", AQ: "~@8 d4@2 ~@21 c4", AR: "~@8 g2 ~@3 [g3,d4] ~@3",
  AS: "[~@16 g3@2 ~@13 f#3@2 ~@15 f#3@10 ~@6]/2", AT: "~@15 g3@2 ~@7 g3@2 ~@6", AU: "~@16 a3 ~@14 b3",
  AV: "~@7 e4@3 ~@13 [f#3,a3] ~@8", AW: "~@7 f4@2 ~@6 [e3,g#3]@3 ~@14",
  AX: "~@8 [c3,e4] ~@14 d4@2 ~@7, ~@7 c4@2 ~@23, ~@4 g3 ~@11", // C
  AY: "[~@7 g2@2 ~@15 g3@2 ~@5 g2@3 ~@5 b3@2 ~@6 d4@2 ~@7 c4@3 ~@5, ~@23 d4@2 ~@30 a2@4 ~@5]/2",
  AZ: "~@7 [c4,d4]@2 ~@7 g3@10 ~@6, ~@15 g2@5 ~@12", // Csus2
})).s("gm_string_ensemble_1").gain(0.25).pan(0.2)

// other · string ensemble 1
const string_ensemble_1_4 = note(`<
  A ~ B C@3 D E F G ~ H I@2 J K L M ~@2 N O ~@2 P F Q R S T U V W R X Y Z AA AB AC@2 Y AD@4 AE AF AG AH AI@2 AJ AK@2 AL
  F AM AN AO@2 AP Y AQ AR@2 AS AT AU ~ AV@2 AW AX
>`.pickRestart({
  A: "~@24 g2@3 ~@5", B: "~@8 b3 ~@3 g3 ~@3",
  C: "[~@7 d4@2 ~@14 d3@3 ~@5 d4@2 ~@6 f#3@2 ~@6 g2@3 ~@13 b3@2 ~@14 b3@2 ~@6 d4@2 ~@7]/3", D: "~@7 g3@2 ~@23",
  E: "~@7 c#4@2 ~@14 d4@3 ~@6", F: "~@8 b3 ~@7", G: "~@4 b3 ~@3 [b3,d4] ~@7", H: "~@15 b3@2 ~@6 d4@2 ~@7",
  I: "[~@23 d2@3 ~@5 a3@2 ~@22 [d3,f#3]@2 ~@7]/2", J: "~@15 d4 ~@7 [g3,d4]@2 ~@7", K: "~@8 [a3,d4] ~@6 f#3@2 ~@15",
  L: "g3@2 ~@6 e4@2 ~@14 a3 ~@7, d4 ~@31", M: "~@15 d4@2 ~@6 [g3,b3,d4]@2 ~@7", N: "~@15 g3@2 ~@6 d4@2 ~@7",
  O: "d3@3 ~@5 [f#3,d4]@2 ~@6 [c4,d4] ~@14 b3", P: "~@7 f4 ~@16 a2@3 ~@5", Q: "~@24 [g3,d4] ~@7",
  R: "~@7 c4@2 ~@6 c4@2 ~@15", S: "~@7 b3@2 ~@23", T: "~@16 b3 ~@7 d4 ~@7", U: "~@15 d4@2 ~@15",
  V: "~@7 a3@2 ~@6 [d3,f#3,a3]@4 ~@13", W: "~@23 b3@2 ~@7", X: "~@7 d4@2 ~@7 d3@3 ~@13, ~@7 b3 ~@24",
  Y: "~@23 d4@2 ~@7", Z: "~@7 c#4@2 ~@6 f#3@2 ~@15, ~@7 a3 ~@24", AA: "a3 ~@6 a3 ~@7 [d3,f#3]@2 ~@15",
  AB: "~@8 d3@3 ~@13 f#3@2 ~@6", AC: "[~@16 d4@2 ~@13 [f#3,c4]@2 ~@7 d4@2 ~@22, ~@39 c4@2 ~@23]/2",
  AD: "[~@7 c4 ~@7 g3@2 ~@14 f#3@2 ~@6 f#3@2 ~@14 d4@2 ~@6 [g3,d4]@2 ~@30 d3@3 ~@5 f#3@2 ~@6 d4@2 ~@6 d3@2 ~@5 [c4,d4]@2, ~@103 c4 ~@24]/4", // G5 Csus2
  AE: "~@23 f#3@2 ~@7", AF: "d4@2 ~@13 d4@2 ~@6 [g3,d4]@2 ~@7", AG: "~@31 f#3", AH: "~@7 d4@2 ~@14 [f#3,d4]@3 ~@6",
  AI: "[~@15 g3@2 ~@6 d4@2 ~@6 g2@2 ~@6 [b3,d4]@2 ~@23]/2", AJ: "~@15 g2@2 ~@6 d4@2 ~@7",
  AK: "[b3@2 ~@13 d4@2 ~@14 e2@2 ~@7 g3@2 ~@6 g3@2 ~@14]/2", AL: "f#3 ~@14 a3@10 ~@7",
  AM: "~@8 g3@2 ~@5 d4@2 ~@15, ~@8 b3 ~@23", AN: "~@7 f#3 ~@16 b3 ~@7",
  AO: "[~@23 [b3,d4] ~@7 e2@2 ~@6 [e3,g3]@2 ~@6 b3@2 ~@15]/2", AP: "~@4 c#4 ~@3 a3@5 ~@3", AQ: "~@7 f#3@2 ~@23",
  AR: "[~@8 g3@3 ~@12 c4 ~@7 c4@2 ~@15 b3 ~@7 d4 ~@7]/2", AS: "~@7 [g3,b3]@2 ~@15 a3@4 ~@4, ~@23 a2@6 ~@3",
  AT: "~@8 d3@3 ~@21, ~@7 [c4,d4]@3 ~@22", AU: "~@8 g2@3 ~@12 g3@2 ~@7",
  AV: "[~@23 c4@2 ~@6 c4@2 ~@15 b3@2 ~@14, ~@23 f#3 ~@40]/2", AW: "~@15 g#3@2 ~@7 e4@3 ~@5",
  AX: "[g3,e4] ~@6 [d3,f#3]@2 ~@14 [g2,g4]@3 ~@6", // C D G
})).s("gm_string_ensemble_1").gain(0.2).pan(0.4)

// bass · acoustic bass
const bass = note(`<
  A B C D E F@2 G H@2 I C J K C L M N@2 O P@2 Q C R S T L U C V W X L U Y@2 Z AA AB U T AC I AA AD U AE@2 U AF@2 B C J
  AG C AH B AI@2 AJ C AK AL N@2 O C L U T R AM
>`.pickRestart({
  A: "~@24 g1@7 ~", B: "~@16 g1@7 ~@9", C: "~@8 g1@7 ~@17", D: "g1@7 ~@17 d2@8", E: "~@16 g1@9 ~@7",
  F: "[~@8 g1@8 ~@15 e1@8 ~@17 d2@7 ~]/2", G: "~@2 a1 ~ d2 ~ d2 ~", H: "[~@8 g1@8 ~@15 g1@8 ~@17 d2@7 ~]/2",
  I: "~@15 g1@8 ~@9", J: "e2 ~@2 d2", K: "~@8 a1@4 ~@3 d2@4 ~@4 d1@3 ~@6", L: "d2@7 ~@17 g1@6 ~@2",
  M: "~@2 c2 ~ d2@2 ~@2", N: "[~@7 g1@7 ~@17 g1@6 ~@10 e2@5 ~@3 a1@7 ~@2]/2", O: "~@7 d2@4 ~@4 g1@4 ~@4 g1@4 ~@5",
  P: "[~@8 g1@7 ~@16 d2@8 ~@17 g1@7 ~]/2", Q: "~@7 c2@5 ~@3 d2@9 ~@8", R: "g1@6 ~@9 e2@5 ~@4 a1@7 ~",
  S: "~@8 d2@3 ~@4 g1@4 ~@4 g1@4 ~@5", T: "~@7 g1@8 ~@17", U: "~@2 d2 ~", V: "a1@9 ~@7 d2@5 ~@2 a1@7 ~@2",
  W: "~@7 d2@5 ~@4", X: "~@9 g1@7 ~@16", Y: "[~@7 g1@8 ~@16 a1@8 ~@8 d2@5 ~@4 a1@8]/2",
  Z: "~@8 c#2@4 ~@3 d2@4 ~@4 d2@4 ~@5", AA: "~@7 d2@7 ~@18", AB: "d2@7 ~@17 d2@7 ~", AC: "c2@8 ~@15 d2@7 ~@2",
  AD: "d2@8 ~@15 d2@8 ~", AE: "[~@8 g1@8 ~@15 c2@8 ~@17 d2@7 ~]/2", AF: "[~@7 g1@9 ~@15 g1@9 ~@16 d2@7 ~]/2",
  AG: "~@8 a1@3 ~@5 d2@5 ~@2 d1@6 ~@3", AH: "g1@7 ~@16 d2@7 ~@2", AI: "[~@7 g1@7 ~@17 e2@8 ~@17 d2@7 ~]/2",
  AJ: "~@7 a1@3 ~@5 d2@6 ~@3 d2@4 ~@4", AK: "d2@8 ~@15 g1@7 ~@2", AL: "~@15 d2@8 ~@9",
  AM: "~@8 d2@3 ~@4 g1@4 ~@5 g1@3 ~@5",
})).s("gm_acoustic_bass").gain(0.29)

stack(string_ensemble_1, string_ensemble_1_2, string_ensemble_1_3, string_ensemble_1_4, bass)

More by Ludwig van Beethoven