           (let [connected (connect-midi-out output)]
                (doseq [handler @new-device-handlers]
                  (handler connected)))
+          (catch MidiUnavailableException e)  ; If we can't have it, give up gracefully
           (catch Throwable t
             (timbre/error t "Unable to connect MIDI output" output))))))
   (vals @midi-outputs))

  * Otherwise, the filter accepts all ports."
  (delay
   (cond
    (and (mac?) (cm4j-installed?))
    cm4j-device?  ;; Only use devices provided by CoreMIDI4J if it is installed.

    (and (mac?) (mmj-installed?))
    (fn [device]
      (let [mmj-descriptions (set (map :description (filter mmj-device? (overtone.midi/midi-sources))))]
        (or (mmj-device? device)
            ;; MMJ returns devices whose descriptions match the names of the
            ;; broken devices returned by the broken Java MIDI implementation.
            ;; But it does not wrap all devices, e.g. the Traktor Virtual Output,
            ;; so we need to only screen out devices which are supported.
            ;; MMJ support is only left in place to support Java 6 environments,
            ;; in particular Max/MSP, where CoreMIDI4J is not available.
            (not (mmj-descriptions (:name device))))))

    :else
    identity)))

(defn- incoming-message-handler
  "Attached to all midi input devices we manage. Puts the message on a

  (swap! new-device-handlers disj f))

(defonce ^{:private true
           :doc "Functions to be called when a device disappears from
  the MIDI environment. Keys are the `javax.sound.midi.MidiDevice`
  whose departure is of interest, and values are a set of functions to
  be called if and when that device ceases to exist. They will be
