;; implementation of classic chaos equation, the logistic map ;; from population biology ;; see http://www-camil.music.uiuc.edu/Classes/icbc/icbc/chaos/main.html ;; ;; needs to have prc96.ins loaded for tubebell voice ;; (compile-file "log" :verbose nil) ;; (load "log") ;; (l) ;; ;; ;; gv aaa.eps for 1st page of score, gv aaa-1.eps for 2nd pg, etc. ;; the system is very simple -- ;; here's a logistic map iterated 20 times with r in chaotic region of 4.0 ;; copy this direct into the lisp interpreter and then try r = 2.0, too ; (loop repeat 20 with x = 0.1 as r = 4.0 do (print (setf x (* r x (- 1.0 x))))) ;; function to set up context for a phrase or set of notes (defun init-globals (start chaos-level seed scr staff-name) (setf semit (expt 2.0 (/ 1.0 12.0))) (setf x seed) (setf r chaos-level) (setf now start) (setf stf (cmn::add-staff scr staff-name nil)) ) ;; function which will iterate logistic equation one time (defun lf () (setf x (* r x (- 1.0 x)))) ;; function to sound and score a note, notating at twice the time values (defun note (beg dur freq amp scr) (tubebell beg dur freq amp) (cmn::add-note-to-staff scr stf (* 2 beg) (* 2 dur) freq) ) ;; outer function to establish context and then run the whole process (defun l () (let* ( (scr (cmn::init-clm-input)) (n 52) dur pitch (thirty-second 0.125) ) (with-sound ;; spec sound output (:srate 48000 :output "/zap/test.wav" :channels 2) ;; initial a chaos series and add a stave for it, then loop throug its notes (loop for i from 0 below n initially (init-globals 0.0 4.0 0.1 scr "fib1") do (lf) (setf dur (* thirty-second (+ 1.0 (round (/ (* x 0.5) thirty-second))))) (setf pitch (* 440.0 (expt semit (round (/ x 0.05))))) (note now dur pitch 0.1 scr) (setf now (+ now dur)) ) ;; do it again on new stave, same chaos ;; but octave down, different seed and sixteenth-rest later (loop for i from 0 below n initially (init-globals 0.25 4.0 0.01 scr "fib2") do (lf) (setf dur (* thirty-second (+ 1.0 (round (/ (* x 0.5) thirty-second))))) (setf pitch (* 220.0 (expt semit (round (/ x 0.05))))) (note now dur pitch 0.1 scr) (setf now (+ now dur)) ) ) (cmn::finish-clm-input scr nil nil) )) ;; indent me, but change my file name & path to be correct first --below here-- ;; xemacs -batch -l ~/.emacs-indent-file -eval '(indent-file "~/220w/log.lisp")'