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

;;

;; Example code using the Matrix Mixer AU

;;

;; The matrix mixer has FOUR types of gain control

;; 1) Master Gain (all output channesl)

;; 2) Input Gains (master gain for each input channel)

;; 3) Output Gains (master gain for each output channel)

;; 4) CrossPoint Gains (the gain from any input to any output)

;;

;; IMPORTANT!

;; Channels are added to the mixer in the order that they are connected

;; So for example, if you have 3 input busses and the first bus is stereo

;; the second bus is mono and the 3rd bus is quad then the input channels into the 

;; matrix mixer will be as such:

;;

;; stereo -> 0 1

;; mono -> 2

;; quad -> 3 4 5 6

;;

;; So to send the quad's second channel to the outputs 8th channel you would set

;; the crosspoint to be:

;; (set-crosspoint-gain mixer 4 7 1.0)

;; to stop sending the signal (and remove processing overhead) turn gain to 0.0

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


(define inst1 (au:make-node "aumu" "SMD2" "UHfX"))

(define inst2 (au:make-node "aumu" "SMD2" "UHfX"))

;; force mixer output to 8 channels (for my MOTU)

(define mixer (au:make-node "aumx" "mxmx" "appl" 8))


;; before we connect the mixer we must set the number of input and output busses

(define dat (objc:data:make 4))

(objc:data:set-uint32 dat 0 1) ;; one bus output (straight to the output node)

(au:set-property mixer 11 *au:output-scope* 0 (objc:call dat "bytes") 4) 

(objc:data:set-uint32 dat 0 8) ;; two input busses (inst1 and inst2)

(au:set-property mixer 11 *au:input-scope* 0 (objc:call dat "bytes") 4)


;; now just connect everything as normal.

;; make sure you have enough busses on the mixer to connect all the things you might need.

;; better to create more than less because you can't change this in the future.

(au:connect-node inst1 0 mixer 0)

(au:connect-node inst2 0 mixer 1)

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


;; update the graph and print out its state

(au:update-graph)

(au:print-graph)


;; this is how we send a signal from any input to any output

(define set-crosspoint-gain

   (lambda (mixer input output gain)

      (au:set-param (now) mixer 0 *au:global-scope* (+ (* 65536 input) output) gain)))


;; set global volume to MAX

(au:set-param (now) mixer 0 *au:global-scope* #xFFFFFFFF 1)


;; set input volumes to MAX (4 in this example - 2 * stereo inputs)

;; the element number is the channel (not the bus)

(au:set-param (now) mixer 0 *au:input-scope* 0 1)

(au:set-param (now) mixer 0 *au:input-scope* 1 1)

(au:set-param (now) mixer 0 *au:input-scope* 2 1)

(au:set-param (now) mixer 0 *au:input-scope* 3 1)


;; set output volumes to MAX (8 in this example - as defined in au:make-node)

;; the element number is the channel (not the bus)

(au:set-param (now) mixer 0 *au:output-scope* 0 1)

(au:set-param (now) mixer 0 *au:output-scope* 1 1)

(au:set-param (now) mixer 0 *au:output-scope* 2 1)

(au:set-param (now) mixer 0 *au:output-scope* 3 1)

(au:set-param (now) mixer 0 *au:output-scope* 4 1)

(au:set-param (now) mixer 0 *au:output-scope* 5 1)

(au:set-param (now) mixer 0 *au:output-scope* 6 1)

(au:set-param (now) mixer 0 *au:output-scope* 7 1)


;; set up a loop so we make some noise.

(define loop

   (lambda (beat)

      (play inst1 60 80 1)

      (play inst2 55 80 1)

      (callback (*metro* (+ beat (* .5 1))) 'loop (+ beat 1))))


(loop (*metro* 'get-beat 4))


;; send the 


;; set input channel 1 (i.e. 0) to go to output channel 6 (i.e. 5) set the volume to 0.5

(set-crosspoint-gain mixer 0 5 0.5)

;; also send input channel 1 (note that we can send the same channel to multiple outputs)

;; to output channel 2

(set-crosspoint-gain mixer 0 1 0.5)

;; set input channel 4 to output channel 1

(set-crosspoint-gain mixer 3 0 0.5)

;; etc..