;
;
; PLAYARP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Play notes in sequence by adding them on top of each other,
; like an arpeggio, till the last note has played.
; The total time is given by the sum of all durations.
;
;
; Args:
; ----
;; 1st: [OPTIONAL:offset default = 0]
;; 2nd: midi channel, 1-based
;; 3rd: pitch-list
;; 4th: vol or vols-list
;; 5th: dur or durs-list
;
; durst & vols: if an atom is passed, it's 'expanded' into a list (= same for all notes)
; (durs => the dur of each note, before the following one kicks in)
;
;
; Requires:
; --------
; beat
; *mididevice*
;
;
; Example:
; --------
; (define piano 1) ;; midi ch
; (let ((beat (*metro* 'get-beat)))
; (playarp piano '(60 67) 90 4)
; (playarp 2 piano '(60 67) 90 4) ;; 2 = offset
; (playarp piano (:mkchord c4 '^ 4) (list 90 50) (:mklist 4 (oneof 1 2 3)))
; )
;
; Dependencies:
; -------------------------------
; * helper:arpeggio
; * play (midi version)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(impc:aot:do-or-emit
(define-macro (playarp . args)
; (println (car args) (len args))
(cond ((length-equal? args 4)
;; 4 args: ch // plist // vols // durs
;; ==> memo: helper:arpeggio takes: beat offset notes durations volumes ch
`(begin
(when #f (println 'arp: ,@args))
(if (atom? ,(cadr args))
(log-error 'arp: 'expects 'a 'list 'of 'notes.)
(helper:arpeggio beat 0 ,(cadr args) ,(cadddr args) ,(caddr args) ,(car args) )))
)