play   macro


Defined in:  https://github.com/lambdamusic/extempore-extensions/blob/main/init/init_play.xtm

Implementation

;    
;    
;    
;; 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.)) 
        )))


Back to Index

Similar Entries