   (doseq [handler (vals (get-in @control-mappings [(:name (:device msg)) (:channel msg) (:note msg)]))]
     (handler msg)))
 
-(defonce ^:private ^{:doc "The channel used to hand MIDI events from
+(defonce ^:private ^{:doc "The queue used to hand MIDI events from
   the extension thread to our world, since there seem to be
   classloader compatibility issues, and the Java3d classes are not
   available to threads that are directly dispatching MIDI events."}
-  channel
+  midi-queue
+  (LinkedBlockingQueue.))
+
+(defonce ^:private ^{:doc "The thread used to hand MIDI events from
+  the extension thread to our world, since there seem to be
+  classloader compatibility issues, and the Java3d classes are not
+  available to threads that are directly dispatching MIDI events."}
+  midi-transfer-thread
   (atom nil))
 
 (defn- delegated-message-handler

            (not (mmj-descriptions (:name device))))))
    identity))

(defn- create-channel
  "Creates the core.async channel used to deliver MIDI events when needed."
  [old-channel]
  (or old-channel
      (let [c (chan 32)]
        (info "Created MIDI dispatch channel.")
        (future (delegated-message-handler))
        c)))

;; TODO: This and open-outputs will have to change once hot-plugging works.
(defn open-inputs-if-needed!
  "Make sure the MIDI input ports are open and ready to distribute events.
  Returns the opened inputs."
  []
  (swap! channel create-channel)
  (let [port-filter (create-midi-port-filter)
        result (swap! midi-inputs #(if (empty? %)
                                     (map connect-midi-in

(ns afterglow.midi
  "Handles MIDI communication, including syncing a show metronome to MIDI clock pulses."
  (:require [afterglow.rhythm :refer :all]
            [amalloy.ring-buffer :refer [ring-buffer]]
            [overtone.at-at :refer [now]]
            [overtone.midi :as midi]
            [taoensso.timbre :refer [info error]])
  (:import [java.util.regex Pattern]
           [java.util.concurrent LinkedBlockingQueue]))

(def ^:private max-clock-intervals
  "How many MIDI clock pulses should be kept around for averaging?"
