; random-walk returns a random deviation to an input value ; current-value is the starting position for the walk ; walk-distance is the maximum distance for the walk ; (note that the walk can be either in a positive or negative direction) ; the (float) function ensures that the walk is always a decimal (real) number (defun random-walk (current-value walk-distance) (if (< (random 1.0) 0.5) (+ current-value (random (float walk-distance))) (- current-value (random (float walk-distance))))) ; produce a list of values generated by random walk (defun make-random-walk (start-value steps walk-distance) (if (> steps 0) (cons start-value (make-random-walk (random-walk start-value walk-distance) (- steps 1) walk-distance)))) ; "reflect" a random walk value so that it is constrained inside ; an upper and a lower threshold (defun barrier-test (test-value lower-boundary upper-boundary) (cond ((< test-value lower-boundary) (barrier-test (+ lower-boundary (abs (- lower-boundary test-value))) lower-boundary upper-boundary)) ((> test-value upper-boundary) (barrier-test (- upper-boundary (abs (- test-value upper-boundary))) lower-boundary upper-boundary)) (t test-value))) ; produce a list of values generated by reflected random walk (defun make-random-walk-reflected (start-value steps walk-distance lower-boundary upper-boundary) (if (> steps 0) (cons start-value (make-random-walk-reflected (barrier-test (random-walk start-value walk-distance) lower-boundary upper-boundary) (- steps 1) walk-distance lower-boundary upper-boundary)))) ; compare an input number to a lower and higher value ; and return the closer of the two comparison values (defun proximity-test (test-value lower-comparison upper-comparison) (if (>= (- test-value lower-comparison) (- upper-comparison test-value)) upper-comparison lower-comparison)) (defun map-element-to-scale (value ordered-scale) (cond ((null ordered-scale) nil) ; if the scale is empty return nil ((= (length ordered-scale) 1) (car ordered-scale)) ; if the scale has one value return it ((<= value (car ordered-scale)) (car ordered-scale)) ; if the value is less than the first scale element, return the first scale element ((and (> value (car ordered-scale)) (< value (cadr ordered-scale))) (proximity-test value (car ordered-scale) (cadr ordered-scale))) ; if the value is between the first and second scale element, try a proximity test (t (map-element-to-scale value (cdr ordered-scale))))) ; otherwise, try again, discarding the first element of the scale (defun map-list-to-scale (value-list ordered-scale) (if value-list (cons (map-element-to-scale (car value-list) ordered-scale) (map-list-to-scale (cdr value-list) ordered-scale)))) (defparameter rw-scale (list 48 50 51 53 54 56 57 59 60 62 63 65 66 68 69 71 72 74 75 77 78 80 81 83 84)) #| (map-list-to-scale (make-random-walk-reflected 60 30 6 21 109) rw-scale) |# (defun make-notes (start-time pitches interonsets durations amplitudes) ; duration is here expressed as a percentage of the interonset time: 0.0 - 1.0 (if (and pitches interonsets durations amplitudes) (cons (new midi :time start-time :keynum (car pitches) :duration (* (car interonsets) (car durations)) :amplitude (car amplitudes)) (make-notes (+ start-time (car interonsets)) (cdr pitches) (cdr interonsets) (cdr durations) (cdr amplitudes))))) #| (events (make-notes 0 (map-list-to-scale (make-random-walk-reflected 60 30 6 48 84) rw-scale) (make-random-walk-reflected 1 30 0.2 0.2 2.4) (make-random-walk-reflected 1 30 0.2 0.1 0.99) (make-random-walk-reflected 1 30 0.2 0.1 0.90)) "test.mid") (events (append (make-notes 0 (map-list-to-scale (make-random-walk-reflected 60 30 6 48 84) rw-scale) (make-random-walk-reflected 1 30 0.2 0.2 2.4) (make-random-walk-reflected 0.9 30 0.2 0.1 0.99) (make-random-walk-reflected 1 30 0.2 0.1 0.90)) (make-notes 0 (make-random-walk-reflected 60 50 6 21 109) (make-random-walk-reflected 0.4 50 0.2 0.1 0.8) (make-random-walk-reflected 0.9 50 0.2 0.1 0.99) (make-random-walk-reflected 0.9 50 0.2 0.5 0.99)) (make-notes 0 (make-random-walk-reflected 60 50 6 21 109) (make-random-walk-reflected 0.4 50 0.2 0.1 0.6) (make-random-walk-reflected 0.3 50 0.2 0.1 0.5) (make-random-walk-reflected 0.9 50 0.2 0.3 0.99))) "test.mid") |# ; next step - simulate GENDYN breakpoints as pitch contours (defun random-walk-sequence (generations values walk-distance lower-boundary upper-boundary) (if (> generations 0) (append values (random-walk-sequence (- generations 1) (mapcar #'(lambda (x) (barrier-test (random-walk x walk-distance) lower-boundary upper-boundary)) values) walk-distance lower-boundary upper-boundary)))) #| (events (make-notes 0 (random-walk-sequence 10 (list 60 62 64 66 68 70) 3 21 109) (random-walk-sequence 10 (list 0.5 0.3 0.1 0.2 0.1 0.2) 0.2 0.1 1.4) (random-walk-sequence 10 (list 0.5 0.6 0.7 0.8 0.9 0.8) 0.2 0.1 0.9) (random-walk-sequence 10 (list 0.9 0.8 0.7 0.6 0.5 0.4) 0.2 0.3 0.9)) "test.mid") (events (append (make-notes 0 (random-walk-sequence 10 (list 60 62 64 66 68 70) 3 21 109) (random-walk-sequence 10 (list 0.5 0.3 0.1 0.2 0.1 0.2) 0.2 0.1 1.4) (random-walk-sequence 10 (list 0.5 0.6 0.7 0.8 0.9 0.8) 0.2 0.1 0.9) (random-walk-sequence 10 (list 0.9 0.8 0.7 0.6 0.5 0.4) 0.2 0.3 0.9)) (make-notes 0 (random-walk-sequence 10 (list 36 39 42 45 48 51) 3 21 109) (random-walk-sequence 10 (list 0.5 0.3 0.1 0.2 0.1 0.2) 0.2 0.1 1.4) (random-walk-sequence 10 (list 0.5 0.6 0.7 0.8 0.9 0.8) 0.2 0.1 0.9) (random-walk-sequence 10 (list 0.5 0.4 0.3 0.2 0.3 0.4) 0.2 0.3 0.9))) "test.mid") (events (append (make-notes 0 (random-walk-sequence 10 (list 60 62 64 66 68 70) 3 21 109) (random-walk-sequence 10 (list 0.5 0.3 0.1 0.2 0.1 0.2) 0.2 0.1 1.4) (random-walk-sequence 10 (list 0.5 0.6 0.7 0.8 0.9 0.8) 0.2 0.1 0.9) (random-walk-sequence 10 (list 0.9 0.8 0.7 0.6 0.5 0.4) 0.2 0.3 0.9)) (make-notes 0 (random-walk-sequence 10 (list 73 77 81 85 89 93) 2 21 109) (random-walk-sequence 10 (list 0.5 0.3 0.1 0.2 0.1 0.2) 0.2 0.1 1.4) (random-walk-sequence 10 (list 0.5 0.4 0.3 0.2 0.3 0.4) 0.2 0.1 0.9) (random-walk-sequence 10 (list 0.9 0.8 0.7 0.6 0.5 0.4) 0.2 0.3 0.9)) (make-notes 0 (random-walk-sequence 10 (list 36 39 42 45 48 51) 3 21 109) (random-walk-sequence 10 (list 0.5 0.3 0.1 0.2 0.1 0.2) 0.2 0.1 1.4) (random-walk-sequence 10 (list 0.5 0.6 0.7 0.8 0.9 0.8) 0.2 0.1 0.9) (random-walk-sequence 10 (list 0.5 0.4 0.3 0.2 0.3 0.4) 0.2 0.3 0.9))) "test.mid") |#