; (progn (load "pload") (in-package gtk)) ;;; ;;; Example 1 ;;; (defparameter pw (plotter :zoom .5 (loop for x from 0 to 1 by .2 for y = (random 1.0) collect x collect y) (loop for x from 0 to 1 by 1/10 for y from 0 to 1 by 1/10 collect x collect y) (loop for x from 0 to 1 by .25 for y = (expt 10 (- x)) collect x collect y))) ;;; ;;; Example 2 ;;; (defparameter pw (let* ((maxh 0) (hist (make-list 100 :initial-element 0)) (rans (loop for x from 0 below 100 for y = (floor (+ (random 100) (random 100) ) 2) collect x collect y do (incf (elt hist y)) (setf maxh (max (elt hist y) maxh)))) (bars (loop for y in hist for x from 0 when (> y 0) collect x and collect (* (/ y maxh) 100)))) (plotter :title "Mean distribution and histogram" :x-axis (axis :percentage) :y-axis (axis :percentage) :view '(:point :bar) :color '("plum4" "dark red") :point-size 6 rans bars))) ;;; ;;; Example 3 ;;; (defaxis :unary () :minimum -1 :maximum 1 :increment 1/2 :labeler "~,2F" :ticks-per-increment 2) (defaxis :radians () :minimum 0 :maximum (* pi 2) :increment (/ pi 2) :ticks-per-increment 2 :labeler (lambda (x) (format nil "~Spi" (rationalize (/ x pi))))) (defparameter pw (plotter :y-axis (axis :unary) :x-axis (axis :radians ) :x-slot 'x :y-slot 'y :point-size 5 :view '(:line :bar-and-point) (loop for x from 0 to 1 by 1/100 for r = (* 2 pi x) collect r collect (sin r)) (loop for x from 0 to 1 by 1/20 for r = (* 2 pi x) collect r collect (sin r)))) ;;; ;;; Example 4 ;;; (defparameter pw (let ((fund 110) (harms 16)) (plotter :x-axis (axis :hertz :slot 'x :minimum fund :maximum (* fund harms)) :y-axis (axis :normalized :slot 'y) :color "dark violet" :view ':bar-and-point :point-size 5 (loop for h from 1 to harms collect (* fund h) collect (/ 1 h))))) ;;; ;;; Example 5, Sequencing micro-tonal MIDI data using :box view. ;;; Musical example by Michael Klingbeil, taken from Chapter 10 of ;;; Notes from the Metalevel. ;;; (defparameter ct9 '(t 0 8)) ; micro-tuning first 9 channels (defun arpeggiate-exprhy (keynums time rate midpoint-frac amplow amphi legato bass-legato bass-cutoff last-legato) (let* ((segs (length keynums)) (last (1- segs)) (midpoint (floor (* segs midpoint-frac))) ;; deltas below midpoint follow one curve, above another. (deltas (append (explsegs midpoint (* midpoint-frac time) rate) (explsegs (- segs midpoint) (* (- 1 midpoint-frac) time) (/ 1 rate))))) (process for i from 0 for k in keynums for d in deltas for r = (if (< k bass-cutoff) bass-legato (if (= i last) (* last-legato d) (* legato d))) for a = (between 0.45 0.5) then (drunk a 0.1 :low amplow :high amphi ) output (new midi :time (now) :keynum k :amplitude a :duration r) wait d))) (defun distort-harmonics (fund distort) (loop for h from 1 below (floor (/ 25.0 distort)) if (odds (* 0.9 distort)) collect (keynum (* fund (expt h distort)) :hz t))) (defun arpa-harmonic (note dur gap) ;; spawn overlapping arpeggios with mean duration of dur and mean ;; gap between arpeggio starts of gap seconds. each arpeggio is ;; upward with the general direction of arpeggio starting notes ;; moving downward (process with fund = (hertz note) for distort from 0.7 below 1.05 by 0.05 for notes = (distort-harmonics fund distort) sprout (arpeggiate-exprhy notes (* (vary dur 0.1) distort) (between 4.0 0.25) (between 0.3 0.6) 0.3 ; amplow 0.8 ; amphi ; bass-legato (* dur distort 0.7) 2.0 ; legato 59 ; bass cutoff 1.0) ; last-legato wait (vary gap 0.4))) (defparameter pw (plotter :x-axis (axis :seconds :maximum 60 :labeler (lambda (x) (prin1-to-string (floor x))) :slot '(time duration)) :y-axis (axis :keynum :minimum 24 :maximum 96 :pixels-per-increment 96 :labeler (lambda (x) (format nil "~A" (note x))) :slot 'keynum) :view :box :point-height 6 (events (arpa-harmonic 'g1 7.0 5.0) (new seq)) (events (arpa-harmonic 'g1 7.0 5.0) (new seq)))) (events (plotter-data pw) "arpa.mid" :channel-tuning ct9)