[CM] yuk yuk yuk
Rick Taube
taube@uiuc.edu
Wed, 24 Mar 2004 12:55:45 -0600
well its spring break. here is an implementation of "max" (three
functions) so you can pretend you're composing too. the first patch
works anywhere the second example is an interactive composition (etude
for openmcl/midishare)
;;
;; "max" patching
(defun box (fn &rest args)
(vector fn args '()))
(defun box-> (box &rest boxes)
(setf (elt box 2) boxes) ; make boxes the "outlets" of box
box)
(defun bang! (box &rest args)
;; allow override of box's current args
(when args (setf (elt box 1) args))
;; call fn on args and collect results
(let ((res (multiple-value-list
(apply (elt box 0)
(elt box 1)))))
;; "send" args to any forward boxes and
;; bang! them in left-to-right order
(dolist (o (elt box 2))
(setf (elt o 1) res)
(bang! o))
(values)))
;;
;; example patch that prints random message
(defparameter box1 (box #'(lambda () (random 100))))
(defparameter box2 (box #'(lambda (x) (list :hiho! :interaction x))))
(defparameter box3 (box #'print))
(box-> box1 box2)
(box-> box2 box3)
(bang! box1)
;;
;; look Ma, im an interactive composer!
(defparameter midiin
;; "send" along the received event.
(box (lambda (e) e)))
(defparameter midiout
;; "send" out to midishare
(box (lambda (e) (output e))))
(defparameter midiran
;; random note with same dynamic
(box (lambda (e)
(ms:new typeNote
:duration (between 100 1000)
:keynum (between 20 100)
:velocity (ms:vel e)))))
(defparameter miditrans
;; transpose event on octave
(box (lambda (e)
(let ((n (ms:MidiCopyEv e)))
(ms:pitch n (+ 12 (ms:pitch e)))
n))))
(box-> midiin midiout miditrans midiran)
(box-> miditrans midiout)
(box-> midiran midiout)
(midi-open)
(receive #'(lambda (e) (bang! midiin e)))
(receive)