;
;
;; HELPER:PLAYCHORD
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Inner function used by PLAY: midi-play multiple notes at the same time
;
; Args:
;; 1st: beat
;; 2nd: offset, atom or list
;; 3rd: channel, 1-based
;; 4th: pitch-list
;; 5th: velocity/vol, atom or list
;; 6th: dur, atom or list
;
;
; (let ((beat (*metro* 'get-beat)))
; (helper:playchord beat 0 piano
; (list c4 g4)
; (:mklist 2 (random 10 90))
; (:mklist 2 (oneof 1 2 3)) )
; )
;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define helper:playchord
(lambda (beat offset_or_list ch plist vol_or_list dur_or_list)
(when #f (monitor beat offset_or_list ch plist vol_or_list dur_or_list))
;; make lists for vols and durs, if atoms are passed
(if (atom? offset_or_list)
(set! offset_or_list (list offset_or_list)))
(if (atom? vol_or_list)
(set! vol_or_list (list vol_or_list)))
(if (atom? dur_or_list)
(set! dur_or_list (list dur_or_list)))
; volumes & durs: ensure it's the right length
(let (
(offsets
(cl:expand-list offset_or_list (- (length plist) (length offset_or_list))))
(volumes (cl:expand-list vol_or_list (- (length plist) (length vol_or_list))))
(durs (cl:expand-list dur_or_list (- (length plist) (length dur_or_list))))
)
(when #f (monitor volumes durs))
(for-each (lambda (o p v d)
(play-midi-note (*metro* (+ beat o)) *mididevice*
(helper:midi-val (eval p))
(helper:midi-val (eval v))
(*metro* 'dur (* *play-midi-default-dur-factor* d))
;; NOTE ch is 0based in xtm, but user sends it as 1-based
(- ch 1)
))
offsets plist volumes durs)
)
)
)