;
;
;
;; PLAY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Play a midi note, or a bunch of notes together (a chord).
;
; Args:
; --------
;; 1st: [OPTIONAL:offset default = 0]
;; 2nd: midi channel, 1-based
;; 3rd: pitch or pitch-list (floats -> int)
;; 4th: vol or vols-list (floats -> int)
;; 5th: dur or durs-list
;
; Requires:
; --------
; beat
; *mididevice*
;
;
; Example:
; --------
; (let ((beat (*metro* 'get-beat)))
; (play piano (:mkmelody 2 60 'dorian '(1 -1 2 -2)) 90 2 )
; (play piano (list c3 c4) 90 2 )
; (play piano c2 90 2 )
; )
; Using offsets:
; (let ((beat (*metro* 'get-beat)))
; (play '(1/2 3/2) piano (:mkmelody 2 60 'dorian '(1 -1 2 -2)) 90 2 )
; (play 1/2 piano (list c3 c4) 90 2 )
; (play piano c2 90 2 )
; )
;
; WARNING:
; --------
; 1) This function overrides the standard Extempore play function a midi version. To revert back: (sys:load_my_utils "init_midi_legacy.xtm")
;
; 2) The offset list needs to be the right length (as plist)
; Otherwise a "caar <- unzip1-with-cdr-iterative <- map" appears
; that I still haven't figured how to prevent..
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(impc:aot:do-or-emit
(define-macro (play . args)
;;; CASE1) 4 args: inst, pitch, vol, dur (no offset)
(cond ((length-equal? args 4)
`(if (list? ,(cadr args))
;; multi-notes: call helper
(helper:playchord
beat
0 ;; offset
,(car args) ;; ch
,(cadr args) ;; pitch
,(caddr args) ;; vol
,(cadddr args) ;; dur
)
;; single-note: send midi message
(play-midi-note (*metro* beat)
*mididevice*
(helper:midi-val (eval ,(cadr args))) ;; pitch
(helper:midi-val (eval ,(caddr args))) ;; vol
(*metro* 'dur
(* *play-midi-default-dur-factor* ,(cadddr args))
) ;; dur
;; channel // 0based in xtm, but here it is 1-based
(- (real->integer ,(car args)) 1)
))
)
;;; CASE2) 5 args: OFFSET, inst, pitch, vol, dur
((length-equal? args 5)
`(if (list? ,(caddr args))
;; multi-notes: call helper
(helper:playchord
beat
,(car args) ;; offset
,(cadr args) ;; ch
,(caddr args) ;; pitch
,(cadddr args) ;; vol
,(caddddr args) ;; dur
)
;; single-note: send midi message
(play-midi-note (*metro* (+ beat ,(car args)))
*mididevice*
(helper:midi-val(eval ,(caddr args)))
(helper:midi-val (eval ,(cadddr args)))
(*metro* 'dur
(* *play-midi-default-dur-factor*
,(cadr (cdddr args))))
(- (real->integer ,(cadr args)) 1)
))
)
(else (print 'Error: 'arguments 'could 'not 'be 'resolved.))
)))