;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; On the fly audio-signal-processing
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define aucode1 (au:make-node "aumf" "code" "MOSO"))
(define aucode2 (au:make-node "aumf" "code" "MOSO"))
(define aucode3 (au:make-node "aumf" "code" "MOSO"))
(define mix (au:make-node "aumx" "smxr" "appl"))
(au:connect-node aucode1 0 aucode3 0)
(au:connect-node aucode3 0 mix 0)
(au:connect-node aucode2 0 mix 1)
(au:connect-node aucode3 0 mix 1)
(au:connect-node mix 0 *au:output-node* 0)
(au:update-graph)
;; simplest of the simple - whitenoise
(au:code:load aucode1 "dsp" (lambda (sample time channel data)
(* 0.1 (random))))
;; sinewave with phase information maintained
(define sinewave
(lambda (sample time channel data)
(let ((phase (objc:data:get-double data channel))
(freq (objc:data:get-double data 2))
(inc (* 2.0 3.141592 (/ freq 44100))))
(objc:data:set-double data channel (+ inc phase))
(* 0.3 (sin (+ inc phase))))))
;; create a data object to share with aucode1
(define dat (objc:data:make (* 8 3)))
;; set frequency in dat[2] save dat[0] and dat[1] for left and right phase
(objc:data:set-double dat 2 220.0)
;; load sinewave with dat into aucode1
(au:code:load aucode1 sinewave dat)
;; define simple fm
(define fm
(lambda (sample time channel data)
(let ((carrier-freq (objc:data:get-double data 4))
(mod-freq (objc:data:get-double data 5))
(carrier-phase (objc:data:get-double data (+ channel 0)))
(mod-phase (objc:data:get-double data (+ channel 2)))
(mod-width (objc:data:get-double data 6))
(carrier-inc 0.0)
(mod-inc 0.0))
(set! mod-inc (sin (* 3.141592 2 (/ mod-freq 44100))))
(set! carrier-inc (sin (* 3.141592 2 (/ carrier-freq 44100))))
(objc:data:set-double data (+ channel 0) (+ carrier-inc carrier-phase))
(objc:data:set-double data (+ channel 2) (+ mod-inc mod-phase))
(* .5 (cos (+ carrier-phase carrier-inc (* mod-width (cos (+ mod-phase mod-inc)))))))))
;; create a data object to share with aucode1
(define dat2 (objc:data:make (* 8 7)))
;; set frequency in dat[4] save dat[0-3] for phase information
(objc:data:set-double dat2 4 180.0)
(objc:data:set-double dat2 5 (* 180 2.5))
(objc:data:set-double dat2 6 0.5)
;; load sinewave with dat into aucode1
(au:code:load aucode2 fm dat2)
;; play frequencies - carrier with mod ratio
(define loop1
(lambda (beat)
(let ((freq (random 60 480)))
(objc:data:set-double dat2 4 freq)
(objc:data:set-double dat2 5 (* 2.5 freq))
(callback (*metro* (+ beat (* .98 8))) 'loop1 (+ beat 8)))))
(loop1 (*metro* 'get-beat 4))
;; and loop 2 fast for mod-width
(define loop2
(lambda (beat)
(objc:data:set-double dat2 6 (cosr 0.5 0.4 1/8))
(callback (*metro* (+ beat (* .5 1/32))) 'loop2 (+ beat 1/32))))
(loop2 (*metro* 'get-beat 4))
;; An example which operates as an effect
;; rather than a generator (i.e. effects an incoming signal)
;;
;; A simple low-pass filter
;;
;; first go back and redefine the original noise signal for aucode1
;;
;; there are aliases for setting and getting data objects
;; float 64 bit set = f64s = objc:data:set-double
;; float 64 bit get = f64g = objc:data:get-double
(define filter
(lambda (sample time channel data)
(let ((frequency (f64g data 0))
(p0 (f64g data 1))
(p1 (f64g data 2)))
(set! p0 (+ p0 (* frequency (- sample p0))))
(set! p1 (+ p1 (* frequency (- p0 p1))))
(f64s data 1 p0)
(f64s data 2 p1)
p1)))
(define filter-dat (objc:data:make (* 8 3)))
;; don't push frequency higher than 1.0
(objc:data:set-double filter-dat 0 0.5)
(au:code:load aucode3 "filter" filter filter-dat)
;; filter frequency sweep
(define loop3
(lambda (beat)
(objc:data:set-double filter-dat 0 (cosr .5 .4 1/12))
(callback (*metro* (+ beat (* .5 1/32))) 'loop3 (+ beat 1/32))))
(loop3 (*metro* 'get-beat 4))