Music 680, Fall 2005: Special Topics in Music Theory - Algorithmic Composition
Lecture 5: October 10, 2005 - Xenakis I: early works

Xenakis
	stochastics as a model of nature: bringing natural phenomena and processes into music
		Xenakis' wartime experiences as formative (mass demonstrations, street fighting)
		arguing in Formalized Music from (a kind of) first principles
	stochastics as a critique of serialism
		'La crise de la musique sˇrielle'
			"less of a polemic against serialism and more the renunciation of traditional polyphonic part
			writing" (Peter Hoffman, New Grove)
		looking for more perceptible control of polyphony, texture, and sound-mass
			(and note that even pre-stochastics these features are Xenakis' primary interests)
		while abandoning control of less perceptible features
			(consider Kreuzspiel as an instance where serial and perceptual formation are not aligned)
		register, density, articulation, playing technique rather than pitch
	stochastics as a compositional strategy, and not a performative one

	early strategies for the control of stochastics (Achorrripsis and the ST compositions)
		laying out a sectioned time-canvas: two-dimensional grid of time and timbre
		determining the density of each cell in the grid
			using half a Poisson curve: favoring no events, as many as four
			but  events are layered across the seven timbre types, so the piece doesn't favor silence
			defining density as a number of sounds per second
		composing out cells
			starting from density, and determining probabilities for salient features
			onset, duration, pitch [starting and ending, in the case of glissandi]
		abstracted version for the ST compositions
			define number of sections
			determine the duration of sections (independent around a defined mean)
			determine the density of each section (logarithmic/independent around a defined mean)
			determine the instrumental composition of each section
			determine the onset of each event within each section
			determine the instrument performing each event (dependent upon composition, onset)
			determine the pitch of each event (dependent upon instrument
			determine the duration, glissando speed, dynamic envelope

	"symbolic music" (Herma)
		as an approach to memory, perception, and syntax
		and thus to local details of pitch and event formation - moving towards gestures

controlled stochasticism in Scheme
	triangular and linear distributions as cheap Poisson and half-Poissons

(define (triangle)
  (let ((first-random (random 1.0))
        (second-random (random 1.0)))
    (/ (+ first-random second-random) 2)))

(define (linear)
  (let ((first-random (random 1.0))
        (second-random (random 1.0)))
    (if (< first-random second-random)
      first-random
      second-random)))

(define (triangular-mean mean)
  (* (triangle) mean 2))

(define (triangular-scaled mean scale)
  (+ (- (* (triangle) scale)
        (/ scale 2))
     mean))

(define (make-section density duration start-time)
  (if (<= density 0)
    nil
    (let* ((onset-in-section (* duration (random 1.0)))
           (onset-global (+ onset-in-section start-time))
           (sustain (* (- duration onset-in-section) (random 1.0))))
      (cons (new midi
              :time onset-global
              :keynum (+ 21 (round (* 88 (random 1.0))))
              :duration sustain
              :amplitude (triangle))
            (make-section (- density 1) duration start-time)))))

; simplest version - sections don't overlap
; section contents are entirely stochastic

(define (make-piece number-sections mean-density mean-duration start-time)
  (if (<= number-sections 0)
    nil
    (let* ((next-duration (triangular-mean mean-duration))
           (next-start (+ start-time next-duration))
           (next-density (triangular-mean mean-density)))
      (append (make-section next-density next-duration start-time)
              (make-piece (- number-sections 1)
                          mean-density
                          mean-duration
                          next-start)))))

; section definition with a little more intra-section consistency

(define (make-profiled-section density duration start-time mean-duration 
                               mean-amplitude amplitude-scale mean-pitch pitch-scale)
  (if (<= density 0)
    nil
    (let* ((onset-in-section (* duration (random 1.0)))
           (onset-global (+ onset-in-section start-time))
           (sustain (* (- duration onset-in-section) (triangular-mean mean-duration))))
      (cons (new midi
              :time onset-global
              :keynum (triangular-scaled mean-pitch pitch-scale)
              :duration sustain 
              :amplitude (abs (triangular-scaled mean-amplitude amplitude-scale)))
            (make-section (- density 1) duration start-time)))))

; piece definition which makes overlap a possibility, utilizes make-profiled-section

(define (make-overlapping-piece number-sections mean-density mean-section-duration start-time
                                mean-note-duration mean-note-amplitude mean-amplitude-scale
                                mean-note-pitch mean-pitch-scale)
  (if (<= number-sections 0)
    nil
    (let* ((next-duration (triangular-mean mean-section-duration))
           (next-start (+ start-time (triangular-mean mean-section-duration)))
           (next-density (triangular-mean mean-density)))
      (append (make-profiled-section next-density next-duration start-time 
                                     (triangular-mean mean-note-duration)
                                     (triangular-mean mean-note-amplitude)
                                     (triangular-mean mean-amplitude-scale)
                                     (triangular-mean mean-note-pitch)
                                     (triangular-mean mean-pitch-scale))
              (make-overlapping-piece (- number-sections 1) mean-density mean-section-duration 
                                      next-start mean-note-duration mean-note-amplitude
                                      mean-amplitude-scale mean-note-pitch mean-pitch-scale)))))

; (events (make-overlapping-piece 8 35 15 0 0.5 0.5 0.2 72 24) "test.mid")
; (events (make-overlapping-piece 8 45 7.5 0 0.1 0.1 0.05 96 3) "test.mid")

(define (make-overlap2 number-sections mean-density mean-section-duration start-time
                       mean-note-duration mean-note-amplitude mean-amplitude-scale
                       mean-note-pitch mean-pitch-scale)
  (if (<= number-sections 0)
    nil
    (let* ((next-duration (triangular-mean mean-section-duration))
           (next-start (+ start-time (* next-duration (random 1.0))))
           (next-density (triangular-mean mean-density)))
      (append (make-profiled-section next-density next-duration start-time 
                                     (triangular-mean mean-note-duration)
                                     (triangular-mean mean-note-amplitude)
                                     (triangular-mean mean-amplitude-scale)
                                     (triangular-mean mean-note-pitch)
                                     (triangular-mean mean-pitch-scale))
              (make-overlapping-piece (- number-sections 1) mean-density mean-section-duration 
                                      next-start mean-note-duration mean-note-amplitude
                                      mean-amplitude-scale mean-note-pitch mean-pitch-scale)))))

; (events (make-overlapping-piece 8 45 7.5 0 0.05 0.05 0.02 96 2) "test.mid")

; (load "your-file.scm")
; is the notation for loading (and interpreting) a complete Scheme file into 
the interpreter