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.