anchor.diff:  (defmethod backend-proxys-node (id (backend (eql :alsa-midi)))
     nil)
   
  -(defmethod backend-control-node-at (time (node number) params (backend (eql :alsa-midi)))
  -  (midihelper:ev-noteon node note velocity))
  +(defmethod backend-control-node-at (time (channel number) params (backend (eql :alsa-midi)))
  +  ;; FIX
  +  #+nil (midihelper:ev-cc channel note velocity))
   
   (defmethod backend-control-node-at (time node params (backend (eql :alsa-midi)))
     nil)
   
   (defmethod backend-play-event (event task (backend (eql :alsa-midi)))
  -  (let* ((type (event-value event :type))
  -         (channel (midi-truncate-clamp (or (event-value event :channel) 0) 15))
  -         (pgm (midi-truncate-clamp (multiple-value-bind (value from) (event-value event :instrument)
  -                                     (if (eql t from)
  -                                         0
  -                                         (if (integerp value) value 0))))) ;; FIX: provide an instrument translation table to automatically translate instrument names to program numbers
  -         (note (midi-truncate-clamp (event-value event :midinote)))
  -         (velocity (unipolar-1-to-midi (event-value event :amp))) ;; FIX: maybe this shouldn't be linear?
  -         (time (or (raw-event-value event :timestamp-at-start) (local-time:now)))
  -         (extra-params (loop :for key :in (keys event)
  -                             :for cc-mapping := (midi-remap-key-value key (event-value event key))
  -                             :if cc-mapping
  -                               :collect cc-mapping)))
  -    (bt:make-thread
  -     (lambda ()
  -       (sleep (max 0 (local-time:timestamp-difference time (local-time:now))))
  -       (when (and pgm
  -                  (not (= pgm (nth channel *alsa-midi-channels-instruments*))))
  -         (midihelper:send-event (midihelper:ev-pgmchange channel pgm)))
  -       (dolist (param extra-params)
  -         (midihelper:send-event (midihelper:ev-cc channel (car param) (cadr param))))
  -       (unless (eql type :set)
  -         (midihelper:send-event (midihelper:ev-noteon channel note velocity))
  -         (sleep (max 0 (dur-time (sustain event) (tempo (slot-value task 'clock)))))
  -         (midihelper:send-event (midihelper:ev-noteoff channel note velocity))))
  -     :name "cl-patterns temporary alsa midi note thread")))
  +  (let ((pgm (alsa-midi-instrument-program-number (event-value event :instrument))))
  +    (when (or pgm (find :alsa-midi (ensure-list (event-value event :backend))))
  +      (let* ((type (event-value event :type))
  +             (channel (midi-truncate-clamp (or (event-value event :channel) 0) 15))
  +             (pgm (or pgm 0))
  +             (note (midi-truncate-clamp (event-value event :midinote)))
  +             (velocity (unipolar-1-to-midi (event-value event :amp))) ;; FIX: maybe this shouldn't be linear?
  +             (time (or (raw-event-value event :timestamp-at-start) (local-time:now)))
  +             (extra-params (loop :for key :in (keys event)
  +                                 :for cc-mapping := (alsa-midi-remap-key-value key (event-value event key))
  +                                 :if cc-mapping
  +                                   :collect cc-mapping)))
  +        (bt:make-thread
  +         (lambda ()
  +           (sleep (max 0 (local-time:timestamp-difference time (local-time:now))))
  +           (when (and pgm
  +                      (not (eql pgm (nth channel *alsa-midi-channels-instruments*))))
  +             (midihelper:send-event (midihelper:ev-pgmchange channel pgm))
  +             (setf (nth channel *alsa-midi-channels-instruments*) pgm))
  +           (dolist (param extra-params)
  +             (midihelper:send-event (midihelper:ev-cc channel (car param) (cadr param))))
  +           (unless (eql type :set)
  +             (midihelper:send-event (midihelper:ev-noteon channel note velocity))
  +             (sleep (max 0 (dur-time (sustain event) (tempo (slot-value task 'clock)))))
  +             (midihelper:send-event (midihelper:ev-noteoff channel note velocity))))
  +         :name "cl-patterns temporary alsa midi note thread")))))
   
   (defmethod backend-task-removed (task (backend (eql :alsa-midi)))
     ;; FIX
  
positive.code:           nil))))
  
  ;; set default cc mappings
  (mapc (lambda (x) (apply 'set-alsa-midi-cc-mapping x))
        '((1 "Vibrato/Modulation" :vibrato unipolar-1-to-midi)
          (8 "Balance" :balance bipolar-1-to-midi)
          (10 "Pan" :pan bipolar-1-to-midi)
  
negative.code:   (midihelper:stop-midihelper))
  
  (defmethod backend-instrument-controls (instrument (backend (eql :alsa-midi)))
    (keys *alsa-midi-cc-map*))
  
  (defmethod backend-all-nodes ((backend (eql :alsa-midi)))
    nil)
  