[CM] append seq one after the other in cm
Rick Taube
taube@uiuc.edu
Sun, 9 Apr 2006 10:50:14 -0500
> i want to output each seq one after the other in
> midifile or whatever.
>
> thanks stf
ok, say you have a few seqs contaings time sorted objects but you dont
know how long or many their are. the most flexible way to "time append"
these is to simply shift each seq by the amount of time the previos seq
claims including an optional "pad" value that you can add to the actual
end time of each seq to shift it forward or backward relative to the
previos seq's end. first you need a little function that returns the
"time length" of a seq. this is easy since the last object in the seq
has the last time value:
(defun seq-time-length (seq &optional (pad 0))
(let ((last-event (first (last (subobjects seq)))))
(if last-event
(+ (object-time last-event) pad)
pad)))
given this function you can write another little function that takes a
sereies of sequences and optional pad values and increments the start
time of each seq by the amount claimed by the previos seq + any pad
between them:
(defun seq-time-append (&rest seqs-and-pads)
(let ((time 0))
(loop for s in seqs-and-pads
if (numberp s) do (incf time s)
else do (progn (sv s :time time)
(incf time (seq-time-length s)))
and collect s)))
Here is a test
;;;--------------------------
(defun ranmidis (n r)
(loop with x = 0 repeat n
collect (new midi :time x :keynum (between 60 90))
do (incf x r)))
(defparameter seq1 (new seq :subobjects (ranmidis 4 .25)))
(list-objects seq1)
(seq-time-length seq1)
(defparameter seq2 (new seq :subobjects (ranmidis 4 .25)))
(list-objects seq2)
(seq-time-length seq2)
(defparameter seq3 (new seq :subobjects (ranmidis 4 .25)))
(list-objects seq2)
(seq-time-length seq3)
(cd )
(events (seq-time-append seq1 seq2 1 seq3) "test.mid")
(events (seq-time-append seq1 .25 seq2 -.5 seq3) "test.mid")