;;; ;;; Chapter 13 ;;; Algorithms and Processes ;;; ;;; Examples and Interactions from processes.html ;;; generated from Common Music 2.4.1 on 19 Jan 2004, 08:23:15. ;;; ;;; ;;; Example 1: The strum1 definition. ;;; (define (strum1 key1 key2 rate dur amp) (let ((step (if (< key2 key1) -1 1)) (diff (abs (- key2 key1)))) (loop repeat (+ diff 1) for key = key1 then (+ key step) for beg from 0 by rate collect (new midi :time beg :duration dur :amplitude amp :keynum key)))) ;;; ;;; Example 2: Converting the strum algorithm into a process description. ;;; (define (strum2 key1 key2 rate dur amp) (let ((step (if (< key2 key1) -1 1)) (diff (abs (- key2 key1)))) (process repeat (+ diff 1) for key from key1 by step for beg from 0 by rate output (new midi :time beg :duration dur :amplitude amp :keynum key)))) ;;; ;;; Interaction 1: Using the strum2 process. ;;; (events (strum2 48 60 .1 1 .4) "midi-port.pm") ;;; ;;; Example 3: A process with changing run times. ;;; (define (strum3 key1 key2 rate dur amp) (let ((step (if (< key2 key1) -1 1)) (diff (abs (- key2 key1)))) (process repeat (+ diff 1) for key from key1 by step for beg = (now) output (new midi :time beg :duration dur :amplitude amp :keynum key) wait rate))) ;;; ;;; Interaction 2: Listening to strum3. ;;; (events (strum3 84 72 .1 1 .4) "midi-port.pm") (events (list (strum3 48 60 .1 1 .4) (strum3 84 72 .1 1 .4)) "midi-port.pm") (events (list (strum3 48 60 .1 1 .4) (strum3 84 72 .15 1 .4)) "midi-port.pm") ;;; ;;; Example 4: Helper Functions from Chapter 6 and 8. ;;; (define (chance? prob) (< (random 1.0) prob)) (define (keynum->pc k) (mod k 12)) (define (retrograde-row row) (reverse row)) (define (transpose-row row to) (loop for pc in row collect (keynum->pc (+ pc to)))) (define (invert-row row) (loop for pc in row collect (keynum->pc (- 12 pc)))) ;;; ;;; Example 5: Basic row playing. ;;; (define row1 '(0 1 6 7 10 11 5 4 3 9 2 8)) (define row2 (invert-row row1)) (define row3 (retrograde-row row1)) (define row4 (retrograde-row row2)) (define (ttone1 reps row key beat amp) (process with len = (length row) repeat reps for i from 0 for p = (mod i len) for pc = (list-ref row p) ; i mod 12 for k = (+ key pc) output (new midi :time (now) :duration (* beat 2) :keynum k :amplitude amp) wait beat)) ;;; ;;; Interaction 3: Listening to ttone1 ;;; (events (ttone1 36 row1 60 .2 .5) "midi-port.pm") ; transposition (events (ttone1 12 (transpose-row row1 1) 60 .2 .5) "midi-port.pm") ; retrograde (events (ttone1 12 (retrograde-row row1) 60 .2 .5) "midi-port.pm") ; inversion (events (ttone1 12 (invert-row row1) 60 .2 .5) "midi-port.pm") ;;; ;;; Example 6: A pointillistic row. ;;; (define (ttone2 len row key beat amp) (process repeat len for i from 0 for pc = (list-ref row (mod i 12)) for n = (if (chance? .5) (+ key 12) (- key 12)) for k = (+ n pc) output (new midi :time (now) :duration (* beat 2) :keynum k :amplitude amp) wait beat)) ;;; ;;; Interaction 4: Listening to ttone2. ;;; (events (ttone2 36 row1 60 .2 .5) "midi-port.pm") (events (ttone2 12 row1 60 .2 .5) "midi-port.pm") ;;; ;;; Example 7: A pointillistic row with random waits. ;;; (define (ttone3 len row key beat amp) (process repeat len for i from 0 for pc = (list-ref row (mod i 12)) for w = (* beat (random 4)) for n = (if (= w 0) (if (chance? .5) (+ key 12) (- key 12)) key) for k = (+ n pc) output (new midi :time (now) :duration (* beat 2) :keynum k :amplitude amp) wait w)) ;;; ;;; Interaction 5: Listening to ttone3 ;;; (events (ttone3 12 row1 60 .2 .5) "midi-port.pm") (events (list (ttone3 36 row1 40 .2 .5) (ttone3 36 row1 60 .2 .5)) "midi-port.pm" '(0 4)) ;;; ;;; Example 8: Defining sections and instrumentation. ;;; (define (ttone4 dur row key beat amp chan) (process while (< (now) dur) for i from 0 for pc = (list-ref row (mod i 12)) for r = (* beat (random 4)) for n = (if (= r 0) (if (chance? .5) (+ key 12) (- key 12)) key) for k = (+ n pc) output (new midi :time (now) :duration (* beat 2) :keynum k :amplitude amp :channel chan) wait r)) ;;; ;;; Interaction 6: Playing a little 12-tone etude. ;;; (events (list (ttone4 16 row1 40 .2 .5 0) (ttone4 12 row2 60 .2 .5 1) (ttone4 8 row3 80 .2 .5 2)) "midi-port.pm" '(0 4 8)) (events (list (ttone4 16 row1 40 .2 .5 0) (ttone4 12 row2 60 .2 .5 6) (ttone4 8 row3 80 .2 .5 12)) "midi-port.pm" '(0 4 8)) ;;; ;;; Example 9: Helper functions for ghosts. ;;; (define (pick-list lst) (let* ((len (length lst)) (pos (random len))) (list-ref lst pos))) (define (pick-range low high) (let ((rng (- high low))) (if (> rng 0) (+ low (random rng)) 0))) (define (bpm->seconds bpm) (/ 60.0 bpm)) (define (rhythm->seconds rhy tempo) (* rhy 4.0 (bpm->seconds tempo))) ;;; ;;; Example 10: Defining gestures for ghosts. ;;; (define (hitone knum at) ;; create a long tone two octave above knum (new midi :time at :keynum (+ knum 24) :duration at :amplitude .5)) (define (thump knum at) ;; make two percussive events below knum (list (new midi :time at :keynum (- knum 18) :duration .05 :amplitude .4) (new midi :time at :keynum (- knum 23) :duration .05 :amplitude .4))) (define (riff knum rhy) ;; generate an upward strum of notes (let ((rate (rhythm->seconds (/ rhy 4) 60))) (process repeat 5 for k from (+ 39 (mod knum 13)) by 13 output (new midi :time (now) :keynum k :amplitude .3 :duration 10) wait rate))) ;;; ;;; Interaction 7: A sample thump and strum. ;;; (events (hitone 60 0) "thump.mid") (events (thump 60 0) "thump.mid") (events (riff 60 1/8) "riff.mid") ;;; ;;; Example 11: The ghosts process. ;;; (define (ghosts) (process repeat 12 for here = (now) for ahead = (* (+ here .5) 2) for main = (pick-range 53 77) for high? = (>= main 65) for amp = (if high? .6 .4) for rhy = (pick-list '(1/16 1/8 3/16)) ;; output main melody output (new midi :time here :keynum main :duration (rhythm->seconds rhy 60 ) :amplitude amp) when high? sprout (hitone main ahead) and sprout (riff main rhy) at (* ahead 2) when (= rhy 3/16) sprout (thump main (+ here .5)) wait (rhythm->seconds rhy 60 ))) ;;; ;;; Interaction 8: Listening to ghosts. ;;; (events (ghosts ) "ghosts.mid") (events (ghosts ) "ghosts.mid")