Mozart’s Musikalisches Würfelspiel

Revision as of 10:39, 30 January 2026 by Gabriel Ellsworth (talk | contribs) (I changed the apostrophe in “Mozart’s” to curly (typographical) punctuation.)

Mozart’s Musikalisches Würfelspiel (score available on IMSLP) is a system to create a waltz by choosing each measure from a list of possibilities, with 759,499,667,166,482 possible waltzes in total. This is an implementation of the Würfelspiel using a bit of Scheme code to select the measures at random, producing a different waltz at each compilation. The code is an instructive example of creating music functions and manipulating music in Scheme.

\version "2.24"

rhMeasureEight = \relative {
  \tag generation \alternative {
    \volta 1 { <g' b d g>4 r8 }
    \volta 2 { <g b d g>4 r8 }
  }
  \tag table {
    <g b d g>4 r8
  }
}

lhMeasureEight = \relative {
  \tag generation \alternative {
    \volta 1 { g,8 g'16 f! e d }
    \volta 2 { g,8 b'16 g fis e }
  }
  \tag table {
    << { g,8^"Volta 2" b'16 g fis e } \\ { g,8_"Volta 1" g'16 f! e d } >>
  }
}

rhData = \relative {
  | f''8 d g
  | a,8 fis16 g b g'
  | g8 c, e
  | g8 d4\trill
  | \rhMeasureEight
  | g,8 c e
  | e16 c e g c g
  | c,4 r8
  | <c e>8 <b d> r8
  | b16 a b c d b
  | e16 c b a g fis
  | <e c'>8 8 8
  | c'8( g e)
  | c'4 r8
  | e8 g16 e c8
  | a'8( fis d)
  | c16 g c e g, c
  | g8( c e)
  | e16 c e8 g
  | g8 b16 d d,8
  | c16 e g d a fis'
  | e8 c g
  | f'16 e d e f g
  | \rhMeasureEight
  | d,16 fis a d fis a
  | <c, e>8 8 8
  | f16 e f d c b
  | fis'16 d a a' fis d
  | b16 d g d b8
  | \rhMeasureEight
  | e16[ c g8] e'
  | g,8 c e
  | \rhMeasureEight
  | e16 c d b g8
  | a8 d fis
  | a,16 e' d g fis a
  | g16 b g d b8
  | c8 g e'
  | g8 g, g
  | c16 b c e g, c
  | c16 b c e g,8
  | b16 c d b a g
  | g'8 f16 e d c
  | a8 f'16 d a b
  | c16 b c g e c
  | g''8 b16 g d b
  | g'8 g16 d b'8
  | e,8 c16 e g c
  | e,8( c g)
  | c8 e16 c g8
  | c16 g e' c g' e
  | d16( cis) d f g, b
  | <c e>8 16 <d f> <e g>8
  | <e, c'>8 8 8
  | g'8 b d,
  | d16 b g8 r8
  | e'8 c g
  | g'8 e c
  | g'8 c, e
  | g8 f16 e d c
  | c8 e16 c g'8
  | e16 c b g a fis
  | e'16 c b c g8
  | e'16 g c g e c
  | d16 a d8 fis
  | fis8 a fis
  | c16 b c e g, c
  | g'8 b16 g d g
  | g8( e c)
  | fis8 a16 fis d fis
  | g16 b d b g8
  | f16 e d c b d
  | g8 e c
  | c'16 b c g e c
  | <d fis>8 8 8
  | c'16 b c g e c
  | g'16 b g8 d
  | c8 c, r
  | c'4 r8
  | d8 a\turn fis'
  | \rhMeasureEight
  | d16[ b g8] g'
  | c,4 r8
  | c16 g e' c g' e
  | c8 e g,
  | d'8 d16 g b8
  | g8 c, e
  | g16 d g b g d
  | f16 e d8 g
  | fis16 a d a fis a
  | \rhMeasureEight
  | <b, d>8 g'16 b d,8
  | c4 r8
  | \rhMeasureEight
  | g'8 e c
  | e8 c g
  | g'16 fis g d b g
  | c8 g e'
  | fis8 a d,
  | \rhMeasureEight
  | e16 d e g c g
  | fis16 d a8 fis'
  | c16 e c g e8
  | e'16 d e g c g
  | fis8 a16 fis d fis
  | a,8 d16 c b a
  | \rhMeasureEight
  | e'8( g c)
  | d,16 f d f b, d
  | <b d>16( <a c>) q( <g b>) q( <fis a>)
  | c'4 r8
  | e8 c g
  | f'8 d b
  | <b d>8 q q
  | c16 g e' c g' e
  | d16 f a f d b
  | d16 a d fis a fis
  | e16 a g b fis a
  | e16 c g' e c' g
  | d'8 a16 fis d a
  | g'8 b16 g d8
  | g16 fis g b d,8
  | \rhMeasureEight
  | <e, c'>8 8 8
  | g'16 e d b g8
  | c16 g c e g <c, e>
  | \rhMeasureEight
  | b8 d g
  | a16 g fis g d8
  | <e, c'>8 8 8
  | c'4 r8
  | <c e>8 <b d>16 <g b> g8
  | d'8 g16 d b d
  | a16 e' <b d> <a c> <g b> <fis a>
  | fis'8 fis16 d a'8
  | c16 b c g e c
  | c8 g e'
  | <a, d fis>8 fis'4\trill
  | g16 b g b d,8
  | a8 a16 d fis8
  | d16 e f d c b
  | c8 g e'
  | g8 d16 b g8
  | g'8 c, e
  | d16 f a, d b d
  | <fis, d'>8 <d' fis> <fis a>
  | e16 c' b g a fis
  | c'16 b c g e c
  | f16 d a8 b
  | <g c e>8 e'4\trill
  | c4 r8
  | g'8 f16 e d c
  | d16 a fis' d a' fis
  | d16 cis d fis a fis
  | g16 b g d b g
  | c16 g e' c g'8
  | e16 d e g c g
  | b,8 d16 b a g
  | e'16 g d c b a
  | c16 b c e g, c
  | <fis, d'>8 8 8
  | e'16 d e g c g
  | g16 fis g d b g
  | d'8 g,4
  | d'8( b g)
  | d'16 b' g d b8
  | c8 c16 d e8
  | g8 f16 e d c
  | e16 g d g a, fis'
  | c4 r8
  | b16 c d e f d
  | c4 r8
  | f16 a a,8 b16 d
  | g,8 c e
  | e16 c b d g8
  | a16 g b g d g
}

lhData = \relative {
  | f8 d g
  | <b, g'>4 r8
  | <c e>4 r8
  | g16 b g'8 b,
  | \lhMeasureEight
  | <c e>4 r8
  | <c g'>4 r8
  | c8 g c,
  | g''4 g,8
  | g'4 r8
  | c,8 d d,
  | c'8 8 8
  | <e g>4 8
  | c8 g c,
  | <c' g'>4 <c e>8
  | <d fis>4 <c fis>8
  | <e g>4 r8
  | <c e>4 <c g'>8
  | <c g'>4 <c e>8
  | b4 r8
  | c8 d d,
  | c'4 r8
  | f16 e d e f g
  | \lhMeasureEight
  | d4 c8
  | c16 e g e c' c,
  | <g' b>4 r8
  | <c, a'>4 r8
  | g'4 g,8
  | \lhMeasureEight
  | <c g'>4 8
  | <c e>4 r8
  | \lhMeasureEight
  | g'4 r8
  | <d fis>4 <c a'>8
  | c8 d d,
  | <b' d>4 r8
  | <c e>16 g' q g q g
  | b,16 d g d b g
  | <c e>4 r8
  | <c e>4 r8
  | g4 r8
  | <c e>4 r8
  | f4 g8
  | <e g>4 r8
  | <b d>4 r8
  | q4 r8
  | <c g'>4 <c e>8
  | <c e>16 g' q g q g
  | <e g>4 r8
  | <c e>4 r8
  | f4 g8
  | c,4 r8
  | c8 8 8
  | <b d>4 r8
  | <g g'>4 g'8
  | <c, e>16 g' q g q g
  | q16 g q g q g
  | q16 g q g q g
  | <c, e>4 r8
  | <e g>4 r8
  | c8 d d,
  | c'4 r8
  | <c g'>4 8
  | <d fis>4 r8
  | << { a'8 fis d } \\ { d8 d c } >>
  | <c e>4 <e g>8
  | b4 r8
  | <c e>4 r8
  | d4 c8
  | <b d>4 8
  | f'4 g8
  | <c, e>16 g' q g q g
  | <c, e>4 r8
  | c8 8 8
  | <c e>4 <c g'>8
  | <b d>4 <b g'>8
  | c4 c,8
  | c'8 g c,
  | c'4 r8
  | \lhMeasureEight
  | <b g'>4 <b d>8
  | c8 g c,
  | <c' e>4 r8
  | <e g>4 r8
  | <b g'>4 r8
  | <c e>4 <c g'>8
  | <b d>4 8
  | f'16 e d8 g
  | <c, a'>4 8
  | \lhMeasureEight
  | <g g'>4 g'8
  | c,8 g c,
  | \lhMeasureEight
  | <c' e>4 r8
  | c4 r8
  | <b d>4 <b g'>8
  | <c e>16 g' q g q g
  | <c, a'>4 8
  | \lhMeasureEight
  | <c g'>4 <c e>8
  | <c a'>4 8
  | <e g>4 r8
  | c4 r8
  | c4 r8
  | c8 d d,
  | \lhMeasureEight
  | <c' g'>4 <c e>8
  | <f a>4 <g d'>8
  | c,8 d d,
  | c'8 g c,
  | <c' e>16 g' q g q g
  | <g b>4 r8
  | g8 8 8
  | <c, e>4 r8
  | f4 g8
  | <d fis>4 r8
  | c8 d d,
  | <c' e>4 r8
  | <d fis>4 <c fis>8
  | <b g'>4 r8
  | <b d>8 8 <b g'>
  | \lhMeasureEight
  | c8 8 8
  | g'8 g, r
  | e'4 e16 c
  | \lhMeasureEight
  | g4 r8
  | <b d>8 8 <b g'>
  | c8 8 8
  | c8 g c,
  | g''8 g, r8
  | <b g'>4 r8
  | c8 d d,
  | << { d'8 d d } \\ { c8 c c } >>
  | << e4 \\ c4 >> r8
  | <c e>16 g' q g q g
  | d,16 d' cis d c d
  | b4 r8
  | <c fis>8 8 <c a'>
  | <b g'>4 g8
  | <c e>4 r8
  | <b d>4 8
  | <c e>16 g' q g q g
  | f4 g8
  | c,8 8 8
  | c8 d d,
  | <c' e>4 r8
  | f4 g8
  | c,16 b c d e fis
  | c8 g c,
  | <c' e>4 r8
  | c4 r8
  | c4 r8
  | <b d>4 r8
  | <e g>4 r8
  | c4 r8
  | g4 r8
  | c8 d d,
  | <c' e>4 8
  | c8 8 8
  | <c g'>4 <c e>8
  | <b d>4 r8
  | g'16 fis g d b g
  | b4 r8
  | <g' b>4 r8
  | <c, e>4 r8
  | <c e>4 <e g>8
  | c8 d d,
  | c'8 g c,
  | <g' g'>4 <b g'>8
  | c8 g c,
  | f'4 g8
  | <c, e>16 g' q g q g
  | g8 g, r8
  | <b d>4 8
}

table = #'(
#(96 32 69 40 148 104 152 119 98 3 54)
#(22 6 95 17 74 157 60 84 142 87 130)
#(141 128 158 113 163 27 171 114 42 165 10)
#(41 63 13 85 45 167 53 50 156 61 103)
#(105 146 153 161 80 154 99 140 75 135 28)
#(122 46 55 2 97 68 133 86 129 47 37)
#(11 134 110 159 36 118 21 169 62 147 106)
#(30 81 24 100 107 91 127 94 123 33 5)
#(70 117 66 90 25 138 16 120 65 102 35)
#(121 39 139 176 143 71 155 88 77 4 20)
#(26 126 15 7 64 150 57 48 19 31 108)
#(9 56 132 34 125 29 175 166 82 164 92)
#(112 174 73 67 76 101 43 51 137 144 12)
#(49 18 58 160 136 162 168 115 38 59 124)
#(109 116 145 52 1 23 89 72 149 173 44)
#(14 83 79 170 93 151 172 111 8 78 131)
)

#(define choices
   (map (lambda (possibilities)
          (1- (vector-ref possibilities (random 11))))
        table))

#(define (split-measures music)
   (let ((elements (ly:music-property
                     (ly:music-property music 'element)
                     'elements)))
     (let loop ((elts (reverse elements))
                (measure '())
                (measures '()))
       (cond
        ((null? elts)
         (list->vector measures))
        ((or (music-is-of-type? (car elts) 'bar-check) ;; until 2.25.5
             (music-is-of-type? (car elts) 'bar-check-event)) ;; since 2.25.6
         (let ((measure-music (make-sequential-music measure)))
           (loop (cdr elts) '() (cons measure-music measures))))
        (else
         (loop (cdr elts) (cons (car elts) measure) measures))))))

applyChoices =
#(define-music-function (music) (ly:music?)
   (let* ((measures (split-measures music))
          (chosen-measures
           (map (lambda (i) (vector-ref measures i))
                choices))
          (first-part (make-sequential-music (take chosen-measures 8)))
          (second-part (make-sequential-music (drop chosen-measures 8))))
     #{
       \repeat volta 2 { #first-part }
       \repeat volta 2 { #second-part }
     #}))

\header {
  title = "Valse"
  composer = "Mozart"
}

randomWaltz =
\keepWithTag generation
\new PianoStaff <<
  \new Staff {
    \time 3/8
    \applyChoices \rhData
  }
  \new Staff {
    \clef bass
    \applyChoices \lhData
  }
>>

\score {
  \layout { }
  \randomWaltz
}

\score {
  \midi { }
  \unfoldRepeats \randomWaltz
}

% Uncomment to display the table of all possible measures ("Notentafel")
%{
\score {
  \layout {
    \context {
      \Score
      barNumberVisibility = #all-bar-numbers-visible
      \override BarNumber.break-visibility = #end-of-line-invisible
      centerBarNumbers = ##t
    }
  }
  \keepWithTag table <<
    \new Staff {
      \time 3/8
      \rhData
    }
    \new Staff {
      \clef bass
      \lhData
    }
  >>
}
%}