;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; 

;; ENVELOPE

;;

;; An example that uses a breakpoint envelope for pitch

;; and velocity values

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;; clear au graph

(au:clear-graph)


;; load instrument

(define inst (au:make-node "aumu" "dls " "appl"))

(au:connect-node inst 0 *au:output-node* 0)

(au:update-graph)


; program change

(au:midi-out (now) inst *io:midi-pc* 0 8 0)


;; x is time and is spread at one beat intervals (i.e. 1.0 2.0 3.0 4.0 etc.)

;; y is random between 0 - 127

(define x (make-vector-with-proc 60 (lambda (i) i)))

(define y (make-vector-with-proc 60 (lambda (i) (random 40 100))))


;; create a combined vector of 60 points

(define points (make-vector 120))

(math:vector= points x '(0 60 2))

(math:vector= points y '(1 60 2))

(print points)


;; createv envelope from points

(define env (make-envelope points))


;; A predicate for calculating if pitch is in pc

;;

;; arg 1: pitch to check against pc

;; arg 2: pc to check pitch against

;; 

;; retuns true or false

;;

(define of-pc?

   (lambda (pitch pc)

      (if (list? (member (fmod pitch 12) pc))

          #t

          #f))) 


;; quantize pc

;; Always slelects a higher value before a lower value where distance is equal.

;;

;; arg 1: pitch to quantize to pc

;; arg 2: pc to quantize pitch against

;;

;; returns quntized pitch or #f if non available

;;

(define quantize-pc

   (lambda (pitch pc)

      (let loop ((inc 0))

         (cond ((of-pc? (+ pitch inc) pc) (+ pitch inc))

               ((of-pc? (- pitch inc) pc) (- pitch inc))

               ((< inc 7) (loop (+ inc 1)))

               (else (print-notification "no pc value to quantize to" pitch pc)

                     #f)))))



;; play for length of envelope (60.0 beats) choosing pitches and volumes from env

;; note: values retured from envelope may not be whole numbers and may need rounding

(define loop

   (lambda (time beats)

      (play-note time inst 

                 (quantize-pc (round (env beats)) '(0 2 4 7 9)) 

                 (- 127 (round (env beats)))

                 22050)

      (if (< beats 60) 

          (callback (+ time 2000) loop 

                    (+ time 2756) 

                    (+ 0.125 beats))

          (print "DONE"))))


;; start

(loop (now) 0.0)