     (let [old-devs     (set (keys @midi-devices*))
           devs         (midi-sources)
           devs         (filter #(not (old-devs (:device %))) devs)
+          devs         (map #(assoc % ::dev-num (next-id (str (:vendor %) (:name %) (:description %)))) devs)
+          devs         (map #(assoc % ::full-device-key (midi-mk-full-device-key %)) devs)
           receivers    (doall (filter
                                (fn [dev]
                                  (try

  arbitrarily ordered."
  [control-key]
  (let [control-agents (swap! midi-control-agents*
                             (fn [prev]
                               (if (get prev control-key)
                                 prev
                                 (let [new-control-agent (agent 0)]
                                   (on-sync-event control-key
                                             (fn [msg]
                                               (send new-control-agent
                                                     (fn [old-val]
                                                       (:data2 msg))))
                                             (mk-control-key-keyword-for-agent control-key))
                                   (assoc prev control-key new-control-agent)))))]
    (get control-agents control-key)))

          dev-map      (apply hash-map (interleave (map :device devs) receivers))]
      (swap! midi-devices* merge dev-map)
      (when (pos? n-devs)
        (log/info "Connected " n-devs " midi devices: " device-names)))
    (catch Exception ex
      (println "Got exception in detect-midi-devices!" (.printStackTrace ex)))))

;; The rate at which we poll for new midi devices
(def MIDI-POLL-RATE 2000)

(defonce __DEVICE-POLLER__
  (detect-midi-devices))
;;  (every MIDI-POLL-RATE #'detect-midi-devices INTERNAL-POOL :desc "Check for new midi devices"))

(defn midi-poly-player
  "Sets up the event handlers and manages synth instances to easily play
