;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; EAMPLE USING THREE CITTERS TO CONTROL AUDIO PARAMETERS
;;
;; Define three "critters" to crawl around the window
;; setting x/y coordinates (au parameters) as they
;; go.
;;
;; NOTE: This example uses the Automat AudioUnit but
;; you can replace it with another AU of your choosing
;; as long as you change the parameter choices to
;; something suiteable (and within the appropriate range).
;; Automat is free anad availible from:
;; http://www.alphakanal.de/snipsnap/space/automat
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; make sure that nothing is already connected
(au:clear-graph)
;; Setup AudioUnit chain
; Locate availible audio unit instruments
; This will list those installed on your machine in the log window.
(au:print-audiounits "aumu")
(au:print-audiounits "aufx")
; choose some units to work with
(define automat (au:make-node "aumu" "auto" "Alfa"))
(define delay (au:make-node "aufx" "dely" "appl"))
(define reverb (au:make-node "aufx" "mrev" "appl"))
(au:connect-node reverb 0 *au:output-node* 0)
(au:connect-node delay 0 reverb 0)
(au:connect-node automat 0 delay 0)
(au:update-graph)
;; Show the visual interface for the synth
(au:open-view automat)
;; Set some init params for the audio units
; Most audio units have ajustable parameters. They can
; be altered from Impromptu programatically. or via
; their visual interface which is exposed using au:open-view.
; The au:print-param-names function will list in the
; log window the parameters for the specified audio unit.
(au:print-params automat *au:global-scope*)
(au:set-param (now) automat 11 0 0 4) ; waveform
(au:set-param (now) automat 56 0 0 1) ; filter type
(au:set-param (now) automat 70 0 0 0.5) ; filter resonance
(au:set-param (now) automat 59 0 0 0.5) ; filter envelope
(au:set-param (now) automat 69 0 0 0.3) ; filter cutoff
(au:set-param (now) automat 36 0 0 0.0) ; osc 2 vol
(au:set-param (now) automat 51 0 0 0.0) ; osc 3 vol
(au:set-param (now) automat 14 0 0 0.0) ; osc 3 vol
(au:print-params reverb *au:global-scope*)
(au:set-param (now) reverb 0 0 0 30) ; wet/dry mix
; (au:set-param (now) reverb 1 0 0 20)
;; test?
; (play-note (now) automat 60 80 *second*)
(define *critter-canvas* (gfx:make-canvas))
(define *go* #t)
;; Function to move shape randomly within the Window frame
;; NOTE: expects to be using the 1st graphics window
(define (move-square time path)
(let ((winW (car (gfx:get-canvas-size *critter-canvas*)))
(winH (cdr (gfx:get-canvas-size *critter-canvas*)))
(pathX (car (gfx:get-path-bounds path)))
(pathY (cadr (gfx:get-path-bounds path)))
(x (random -20 21))
(y (random -20 21)))
(cond ((> (+ pathX x) (- winW 100)) (set! x -20))
((> (+ pathY y) (- winH 100)) (set! y -20))
((< (- pathX x) 20) (set! x 20))
((< (- pathY y) 20) (set! y 20)))
(gfx:move-path time path x y)))
;; wipe critters tails over time
(define (clearer time colour)
(gfx:clear-canvas time *critter-canvas* colour)
(if *go* (callback (+ time 10000) 'clearer (+ time 22050) colour)))
;; draw critters
(define (drawer time path au:node m fill stroke param-x param-y)
(gfx:draw-path time *critter-canvas* path stroke fill)
(let ((x (/ (car (gfx:get-path-bounds path))
(car (gfx:get-canvas-size *critter-canvas*))))
(y (/ (cadr (gfx:get-path-bounds path))
(cdr (gfx:get-canvas-size *critter-canvas*)))))
(au:set-param (now) au:node param-x 0 0 (* x m))
;; (print " x m = " (* x m) " y m =" (* y m))
(au:set-param (now) au:node param-y 0 0 (* y m))
(move-square (+ time 10) path)
(if *go* (callback (+ time 1000)
'drawer
(+ time 2000)
path au:node m fill stroke param-x param-y))))
;; Setup three critters to be started at 1 minute intervals
;; each critter controls two parameters and a primary colour
(define (start time)
(set! *go* #t)
(au:start-note (+ time 100) automat 60 80)
(drawer time
(gfx:make-circle 200 200 30)
automat
1.0
(list 0.5 0.0 0.0 0.5)
(list 0.3 0.0 0.0 1.0) 69 21) ; cutoff and volume
(drawer (+ time (* *second* 30))
(gfx:make-circle 200 200 30)
automat
24.0
(list 0.0 0.5 0.0 0.5)
(list 0.0 0.3 0.0 1.0) 14 20) ; tune and pan
(drawer (+ time *minute*)
(gfx:make-circle 200 200 30)
automat
1.0
(list 0.0 0.0 0.5 0.5)
(list 0.0 0.0 0.3 1.0) 19 17) ; ring mod and glide
(gfx:clear-canvas time *critter-canvas* '(0.0 0.0 0.0 1.0))
(clearer time '(0.0 0.0 0.0 0.2)))
;; Stop the sound
(define (stop)
(set! *go* #f)
(au:stop-note (now) automat 60 0))
(stop)
(start (+ (now) *second*))