#| week-11.lisp 11.24.2007 A "network" is a series of behaviors. Each behavior, or "state", is defined as a collection of possible MIDI events, plus a collection of possible transitions to other states. A network likes this allows us to define the general behavior and sequence of events over time, while still leaving the determination of individual events and properties to chance procedures. More specifically, the network is structured as follows: ((network-state-1 . ((list-of-next-states) (number-of-notes-in-output (pitch-gamut) (duration-gamut) (amplitude-gamut)))) (network-state-2 . ((list-of-next-states) (number-of-notes-in-output (pitch-gamut) (duration-gamut) (amplitude-gamut)))) ... (network-state-n . ((list-of-next-states) (number-of-notes-in-output (pitch-gamut) (duration-gamut) (amplitude-gamut))))) Note that every state in the list of possible transitions is as likely to occur as every other state. If you want to bias the probabilities towards a particular state, include that state multiple times in the list. "nil" is the terminating state, which ends progress through the network. |# (defun network (current-state network-structure) (if current-state (let* ((state-values (cdr (assoc current-state network-structure))) (state-transitions (car state-values)) (outputs (cadr state-values)) (next-state (choose-element state-transitions))) (cons outputs (network next-state network-structure))))) (defun choose-element (input-list) (nth (random (length input-list)) input-list)) (defun process-network-output (start-time network-output) (if network-output (let* ((first-output (car network-output)) (number-events (car first-output)) (pitch-gamut (nth 1 first-output)) (duration-choice (choose-element (nth 2 first-output))) (amplitude-choice (choose-element (nth 3 first-output)))) (append (make-output-midi start-time number-events pitch-gamut duration-choice amplitude-choice) (process-network-output (+ start-time duration-choice) (cdr network-output)))))) (defun make-output-midi (start-time number-events pitch-gamut duration amplitude) (if (> number-events 0) (cons (new midi :time start-time :keynum (choose-element pitch-gamut) :duration duration :amplitude amplitude) (make-output-midi start-time (- number-events 1) pitch-gamut duration amplitude)))) (defparameter melodic-network '((grace-note . ((grace-note grace-note grace-rest first-note first-chord) (1 (84 85 87 90 94 99 105) (0.05 0.07) (0.5 0.6 0.7)))) (grace-rest . ((grace-note grace-note first-note first-chord) (1 (20) (0.05 0.07) (0.0)))) (first-note . ((first-note first-note second-chord periodic-riff) (1 (35 46 47 57 58 59 68 69 70 71) (0.4 1.4 1.5 1.6 1.9 2.1) (0.7 0.8 0.9)))) (first-chord . ((first-note first-note second-chord) (4 (35 46 47 57 58 59 68 69 70 71) (1.4 1.5 1.6 1.9 2.1) (0.7 0.8)))) (second-chord . ((second-chord second-chord second-chord second-chord periodic-riff) (3 (34 37 38 42 43 45 46 50 51 53 54 58 59 61 62 66 67 69) (0.3 0.4 0.6) (0.4 0.5 0.6)))) (periodic-riff . ((periodic-riff periodic-riff periodic-riff nil) (1 (105 104 99 98 97 94 93 92 90 89 88 87 83 82 80 77 74 70 65) (0.22) (0.75 0.85 0.95)))))) ; (events (process-network-output 0 (network 'grace-note melodic-network)) "test.mid") #| (events (append (process-network-output 0 (network 'grace-note melodic-network)) (process-network-output 5 (network 'grace-note melodic-network)) (process-network-output 8 (network 'grace-note melodic-network)) (process-network-output 10 (network 'grace-note melodic-network)) (process-network-output 11 (network 'grace-note melodic-network))) "test.mid") |#