anchor.diff:  (in-package :cl-patterns)
   
  -;; FIX: make versions of these generic functions that will work with supercollider ugens; put them in cl-collider-extensions.lisp..
  +;; FIX: make versions of these generic functions that will work with supercollider ugens; put them in supercollider.lisp..
   ;; FIX: need to test weird scales/tunings to make sure they're converting correctly, etc.
   
   ;;; event glue
  
positive.code: (defparameter *event-special-slots* (list)
    "Plist mapping event special slots to their case lists.")
  
  (defun raw-set-event-value (event slot value)
    "Set the value of SLOT to VALUE in EVENT without running any conversion functions."
    (with-slots (other-params) event
      (setf other-params (plist-set other-params (alexandria:make-keyword slot) value))))
  
  (defun set-event-value (event slot value)
    "Set the value of SLOT to VALUE in EVENT, running any conversion functions that exist."
    (let* ((slot (alexandria:make-keyword slot))
           (cases (getf *event-special-slots* slot)))
      (when (cadr cases) ;; remove-keys
        (let ((keys (remove-if (lambda (c) (eq c t)) (keys (car cases)))))
          (loop :for i :in keys
             :do (remove-event-value event i))))
      (if (fboundp (list 'setf slot))
          (funcall (fdefinition (list 'setf slot)) value event)
          (raw-set-event-value event slot value))))
  
  (defun remove-event-value (event slot)
    "Removes SLOT from EVENT."
    (with-slots (other-params) event
      (setf other-params (alexandria:remove-from-plist other-params (alexandria:make-keyword slot)))))
  
  (defun raw-get-event-value (event slot)
    "Get the value of SLOT in EVENT without running any conversion functions."
    (getf (slot-value event 'other-params) (alexandria:make-keyword slot)))
  
  (defun get-event-value (event &optional slot)
    "Get the value of SLOT in EVENT, running any necessary conversion functions.
  
  Returns 2 values: the value of the slot, and the name of the slot the value was derived from (or t if the default value of the slot was used, or nil if no value or default was provided)."
    (when (null slot) ;; if called like (get-event-value :foo) then assume *event* is the event and :foo is the slot.
      (assert (typep event 'symbol))
      (return-from get-event-value (get-event-value *event* event)))
    (when (null event)
      (return-from get-event-value (values nil nil)))
    (let* ((slot (alexandria:make-keyword slot))
           (cases (car (getf *event-special-slots* slot)))
           (cases (if (not (position slot (keys cases)))
  
negative.code: 
  (define-event-special-slot delta (:dur (get-event-value event :dur)
                                         t (get-event-value event :dur))
    :remove-keys nil)
  
  (defgeneric delta (item))
  
  (defmethod delta ((item event))
    (get-event-value item :delta))
  
  ;; (defgeneric (setf delta) (value item))
  
  ;; (defmethod (setf delta) (value (item event))
  ;;   (set-event-value item :delta value))
  
  (define-event-special-slot dur (:delta (raw-get-event-value event :delta)
                                         t 1)
    :remove-keys nil)
  
  (defgeneric dur (item))
  
  (defmethod dur ((item event))
    (get-event-value item :dur))
  
  ;; (defgeneric (setf dur) (value item))
  
  ;; (defmethod (setf dur) (value (item event))
  ;;   (set-event-value item :dur value))
  
  ;; sustain/legato
  
  (define-event-special-slot sustain (t (* (get-event-value event :legato)
                                           (get-event-value event :dur)))
    :remove-keys (:legato))
  
  (defgeneric sustain (item))
  
  (defmethod sustain ((item event))
    (get-event-value item :sustain))
  
  ;; (defgeneric (setf sustain) (value item))
  
  ;; (defmethod (setf sustain) (value (item event))
  ;;   (set-event-value item :sustain value))
  
  (define-event-special-slot timing-offset (t 0))
  
  (define-event-special-slot legato (:sustain (* (raw-get-event-value event :sustain)
                                                 (get-event-value event :dur))
                                              t 0.8)
    :remove-keys (:sustain))
  
  (defgeneric legato (item))
  
  (defmethod legato ((item event))
    (get-event-value item :legato))
  
  ;; (defgeneric (setf legato) (value item))
  
  ;; (defmethod (setf legato) (value (item event))
  ;;   (set-event-value item :legato value))
  
  ;;; quant
  
  