Post Generation Event-By-Event Processing
A helper function for processing events post-processing (e.g. for setting dynamics)
;; Process a set of events over pattern with function ;; pattern is a list of durations (events to skip over), which will be looped over the returned events ;; provided function should take event as argument (so if you need player etc., figure it out) (defun process-events (sc player pattern function &optional (attacks t) (start-bar 1) (end-bar nil)) (next-event sc player attacks start-bar);initialise slurping (loop for ne = (next-event sc player attacks nil end-bar) while ne for i from 0 with patt-pointer = 0 with next-e = (nth patt-pointer pattern) do (when (equalp i next-e) (funcall function ne) (setf patt-pointer (mod (1+ patt-pointer) (length pattern))) (incf next-e (nth patt-pointer pattern)))))
The point of the
pattern thing is that I can use it to apply arbitrarily complex patterns on which events to select for the given player, e.g.
(loop for ins in '(p1 p2 p3 p4 p5) for patt in '((5) (15 10) (10 5 10) (5 10 10) (5 20)) do (process-events opus ins patt #'(lambda (ne) (setf (amplitude ne) (min 1 (* 2 (amplitude ne))))) nil))
Which will select every 5th event in p1, every 5th then every 10th (then the next 5th etc.) for p2, and so on.