22 Etudes, Op. 8: An Algorithmic Model of György Ligeti's Désordre

Example 22-1. Global tempo and amplitude.

(define eighth-pulse (rhythm 'e 76.0 'w))

(define (eighth-time number-of-eighths)
  ;; Convert duration in eighth notes
  ;; to time in seconds
  (* eighth-pulse number-of-eighths))

(define fg-amp .7)  ; foreground amp

(define bg-amp .5)  ; background amp

Example 22-2. Upper foreground mode and step patterns.

(define white-mode
  (new mode :steps '(c d e f g a b c)))

(define white-fg-steps
  '(0  0  1  0  2  1 -1             ; Phrase a
    -1 -1  2  1  3  2 -2            ; Phrase a'
    2  2  4  3  5  4 -1 0 3 2 6 5)) ; Phrase b

(define (make-white-fg-notes note)
  ;; convert note in MIDI scale to modal equivalent
  (let ((step (keynum note :to white-mode)))
    ;; pattern of steps is offset
    ;; from a constantly rising offset
    (new transposer 
      :of (new cycle :of white-fg-steps)
      :by (new range :initially step :by 1))))

Example 22-3. The upper foreground rhythmic pattern.

(define (make-white-fg-rhythms)
  (new cycle
    :of `(3 5 3 5 5 3 7             ; cycle 1
          3 5 3 5 5 3 7
          3 5 3 5 5 3 3 4 5 3 3 5
          3 5 3 4 5 3 8             ; cycle 2
          3 5 3 4 5 3 8
          3 5 3 4 5 3 3 5 5 3 3 4
          3 5 3 5 5 3 7             ; cycle 3
          3 5 3 5 5 3 7
          3 5 3 5 5 3 3 4 5 3 3 5
          3 5 3 4 5 2 7             ; cycle 4
          2 4 2 4 4 2 5
          2 3 2 3 3 1 1 3 3 1 1 3
          1 2 1 2 2 1 3             ; cycle 5
          1 2 1 2 2 1 3
          1 2 1 2 2 1 1 2 2 1 1 2
          1 2 1 2 2 1 3             ; cycle 6
          1 2 1 2 2 1 3
          1 2 1 2 2 1 1 2 2 1 1 2
          1 2 1 2 2 1 3             ; cycle 7
          1 2 1 2 2 1 2
          1 2 1 2 2 1 1 2 2 1 1 2
          1 2 1 2 2 1 2             ; cycle 8
          1 2 1 2 2 1 2
          1 2 1 2 2 1 1 2 2 1 1 2
          1 2 1 2 2 1 2             ; cycle 9
          1 2 1 2 1 1 2
          1 2 1 2 2 1 1 1 2 1 1 1
          1 2 1 1 1 1 2             ; cycle 10
          1 1 1 1 1 1 2
          1 1 1 1 1 1 1 1 1 1 1 1
          ,(new cycle
             :of
             (new cycle
               :of
               '(3 5 3 5 5 3 8   ; cycle 11-14
                 3 5 3 5 5 3 8
                 3 5 3 5 5 3 3 5 5 3 3 5))
             :for 3)
          3 5 3 5 5 3 8             ; cycle 14
          3 5 3 5 5 3 8
          3 5 3 5 5 3)))            ; cuts off here

Example 22-4. Lower foreground mode and step patterns.

(define black-mode 
  (new mode :steps '(cs ds fs gs as cs)))

(define black-fg-steps
  '(0  0  1  0  2  2  0               ; Phrase a
    1  1  2  1 -2 -2 -1               ; Phrase a'
    1  1  2  2  0 -1 -4 -3  0         ; Phrase b
    0 -1  3  2  1 -1  0 -3 -2 -3 -5))

(define (make-black-fg-notes note)
  (let* ((cycle-length (length black-fg-steps))
         (warp-point (+ (* cycle-length 7)
                        7 7 8))
         (step (keynum note :to black-mode)))
    (new transposer
      :of 
      (new transposer 
        :of (new cycle
              :of black-fg-steps)
        :stepping (new line 
                    :of 
                    (list (new cycle :of 0
                               :for warp-point)
                          20)))
      :by (new range :initially step :by -2))))

Example 22-5. The lower foreground rhythmic pattern.

(define (make-black-fg-rhythms)
  (new cycle
    :of '(3 5 3 5 5 3 8    ; cycle 1
          3 5 3 5 5 3 8
          3 5 3 5 5 3 3 5  5 3 3 5 3 5 3 5 5 3 8
          3 5 3 5 5 3 8    ; cycle 2
          3 5 3 5 5 3 8
          3 5 3 5 5 3 3 5  5 3 3 5 3 5 3 5 5 3 8
          3 5 3 5 5 3 8    ; cycle 3
          3 5 3 5 5 2 7
          3 4 3 4 4 2 2 4  4 2 2 3 2 3 1 3 3 1 4
          1 3 1 2 2 1 3    ; cycle 4
          1 2 1 2 2 1 3
          1 2 1 2 2 1 1 2  2 1 1 2 1 2 1 2 2 1 3
          1 3 1 2 2 1 3    ; cycle 5
          1 2 1 2 2 1 3
          1 2 1 2 2 1 1 2  2 1 1 2 1 2 1 2 2 1 2
          1 2 1 2 2 1 2    ; cycle 6
          1 2 1 2 2 1 2
          1 2 1 2 2 1 1 2  2 1 1 2 1 2 1 2 2 1 2
          1 2 1 2 2 1 2    ; cycle 7
          1 2 1 2 2 1 2
          1 2 1 2 2 1 1 2  1 1 1 2 1 1 1 1 1 1 2
          1 1 1 1 1 1 2    ; cycle 8
          1 1 1 1 1 1 2
          1 1 1 1 1 1 1 1  5 3 3 5 3 5 3 5 5 3 8
          3 5 3 5 5 3 8    ; cycle 9
          3 5 3 5 5 3 8
          3 5 3 5 5 3 3 5  6 3 3 5 3 5 3 6 5 3 8
          3 6 3 5 5 3 9    ; cycle 10
          3 5 3 5 6 3 8
          3 5 3 6 5 3 3 5  6 3 3 5 3 5 3 6 5 3 9
          3 7 3 8 9 3 13   ; cycle 11
          3 11 3 21)))     ; cuts off here

Example 22-6. Foreground process.

(define (fg-mono mode keynums rhythms)
  (process for key = (keynum (next keynums)
                             :from mode)
           for rhy = (eighth-time (next rhythms))
           output (new midi :time (now)
                       :keynum key
                       :amplitude fg-amp
                       :duration rhy)
           wait rhy
           until (eop? rhythms)))

Interaction 22-1. Play upper foreground.

cm> (events (fg-mono white-mode 
                     (make-white-fg-notes 'b4)
                     (make-white-fg-rhythms))
            "ligeti.mid")
"ligeti-1.mid"
cm>

Interaction 22-2. Play lower foreground.

cm> (events (fg-mono black-mode 
                     (make-black-fg-notes 'ds4)
                     (make-black-fg-rhythms))
            "ligeti.mid")
"ligeti-2.mid"
cm>

Interaction 22-3. Play both foregrounds together.

cm> (events (list
             (fg-mono white-mode 
                      (make-white-fg-notes 'b4)
                      (make-white-fg-rhythms))
             (fg-mono black-mode 
                      (make-black-fg-notes 'ds4)
                      (make-black-fg-rhythms)))
            "ligeti.mid")
"ligeti-3.mid"
cm>

Example 22-7. Add octaves and a fake background

(define (desordre-w/octaves mode ntes rhys)
  (let ((fg-time 0) 
        (fg-eighths 0)
        (mode-deg 0))
    (list
     ;; foreground process
     (process with dur and key
              set fg-time = (now)
              set mode-deg = (next ntes)
              set key = (keynum mode-deg :from mode)
              set fg-eighths = (next rhys)
              set dur = (eighth-time fg-eighths)
              output (new midi 
                       :time fg-time
                       :keynum key
                       :duration (- dur .01)
                       :amplitude fg-amp)
              output (new midi
                       :time fg-time
                       :keynum (+ key 12)
                       :duration (- dur .01) 
                       :amplitude fg-amp)
              wait dur
              until (eop? rhys))
     ;; background process fills in 8th note pulses with
     ;; randomly selected mode notes based on current 
     ;; foreground note.
     (let ((pat (new range
                  :from (pval mode-deg)
                  :stepping (new random
                              :of
                              '((1 :weight 3)
                                2 
                                (3 :weight .5
                                 :max 1)))
                  :for (pval fg-eighths))))
       (process repeat 1064
                for k = (keynum (next pat)
                                :from mode)
                unless (or (= (now) fg-time)
                           (not (<= 0 k 127)))
                output (new midi
                         :time (now)
                         :keynum k
                         :duration (- eighth-pulse
                                      .01)
                         :amplitude bg-amp)
                wait eighth-pulse)))))

Interaction 22-4. Listening to enhancement 1.

cm> (events (append
             (desordre-w/octaves white-mode
                                 (make-white-fg-notes 'b3)
                                 (make-white-fg-rhythms))
             (desordre-w/octaves black-mode
                                 (make-black-fg-notes 'ds3)
                                 (make-black-fg-rhythms)))
            "ligeti.mid")
"ligeti-4.mid"
cm>

Example 22-8. Process with foreground chords.

(define (desordre-voices mode ntes rhys chord
                         voimap fgchan bgchan)
  (let ((moct (scale-divisions mode))
        (fg-time 0)
        (fg-8ths 0)
        (mode-deg 0))
    (list
     ;; foreground process
     (process with rhy and voi and key
              and voices = 
              (new transposer
                :of (new heap :of chord
                         :for (pval voi))
                :on (pval mode-deg))
              for count from 0
              set fg-time = (now)
              set mode-deg = (next ntes)
              set key = (keynum mode-deg
                                :from mode)
              set fg-8ths = (next rhys)
              set rhy = (eighth-time fg-8ths)
              set voi = (lookup count voimap)
              output
              (new midi :time (now)
                   :channel fgchan
                   :keynum key
                   :duration rhy
                   :amplitude fg-amp)
              wait rhy
              if (equal? voi true)
              ;; add lower octave ...
              output 
              (new midi :time (now)
                   :channel fgchan
                   :keynum (- key 12) 
                   :duration rhy
                   :amplitude fg-amp)
              else 
              ;; ... else add cluster
              each k in (next voices true)
              output
              (new midi
                :channel fgchan
                :time (now)
                :keynum (keynum k :from mode)
                :duration (- rhy .01))
              until (eop? rhys))
     ;; background process. 
     (let ((notes
            (new range
              :from
              (pval (- mode-deg 
                       moct))
              :stepping
              (new random
                :of '((1 :weight 3)
                      2 
                      (3 :weight .5 :max 1)))
              :for (pval fg-8ths))))
       (process for i below 1064
                for k = (keynum (next notes)
                                :from mode)
                unless (or (= (now) fg-time)
                           (not (<= 0 k 127)))
                output (new midi 
                         :channel bgchan
                         :time (now)
                         :keynum k
                         :duration (- eighth-pulse
                                      .01)
                         :amplitude bg-amp)
                wait eighth-pulse)))))

Interaction 22-5. Listening to enhancement 2.

cm> (events (append 
             (desordre-voices white-mode
                              (make-white-fg-notes 'b4)
                              (make-white-fg-rhythms)
                              '(-1 -2 -3 -4 -5 -6)
                              '(0 #t 261 1 284 2 297 3)
                              0 1)
             (desordre-voices black-mode  
                              (make-black-fg-notes 'ds4)
                              (make-black-fg-rhythms)
                              '(-1 -2 -3 -4)
                              '(0 #t 254 1 286 2)
                              2 3))
            "ligeti.mid")
"ligeti-5.mid"
cm>

Chapter Source Code

The source code to all of the examples and interactions in this chapter can be found in the file ligeti.cm located in the same directory as the HTML file for this chapter. The source file can be edited in a text editor or evaluated inside the Common Music application.