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

;;

;; EVENT BLOCKING

;;

;; Block and unblock start-sound events from executing

;;

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


; clear any existing audio graph info

(au:clear-graph)


; setup simple au graph

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

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

(au:update-graph)


; read a midi file

; change the file name, location and path to suit your setup.

(define score (io:read-midi-file "blues.mid"))


; play a MIDI track

; add tag to start-sound events by consing a number to

; the start time. This tells Impromptu that the event

; has a tag. This tag can be used to block execution of

; the events.

(define (play-track time inst midi-track)

   (map (lambda (t p v r)

           (au:start-sound (cons (+ time (* t *second*)) 101) inst p v r)

           (au:stop-sound (+ time (* t *second*) (* r (* .5 *second*))) inst p))

        (list-ref midi-track 0)

        (list-ref midi-track 1)

        (list-ref midi-track 2)

        (list-ref midi-track 3)))


; play first track of midi file

(play-track (now) buz (list-ref score 0))


; block start-sound events

(sys:set-block 101)


; unblock start-sound events

(sys:remove-block 101)


;; stuck notes?

; It is not uncommon for the sys:set-block function to 

; take effect during a note such that it started 

; but did not get a stop event - and is stuck on.

; The panic function sends a stop command to all notes.

; The "do" function first assigns a variable, followed by

; the conditions under which it is varied each repetition, 

; then its stop condition and, finally, the commnds to execute

; each repetition.

(define panic

   (lambda (inst)

      (do ((ch 0 (if (= ch 16) 0 (+ ch 1)))

           (i 0 (if (= ch 0) (+ i 1) i)))

         ((= i 127) '())

         (au:stop-sound (now) inst i ch))))


(panic buz)