I am trying to access MIDI inputs in a ClojureScript project, using something like, in JS:
if (navigator.requestMIDIAccess) {
console.log('WebMIDI is supported in this browser.');
navigator.requestMIDIAccess().then(onMIDISuccess, onMIDIFailure);
I figured out how to get this to work with the Promesa library do! capability... however, the returned object, in JS, has a list of MIDI inputs, and one needs to set a function as the value of the 'onmidimessage' property of the inputs you care about. In JS this would look like this:
function onMIDISuccess(midiAccess) {
var inputs = midiAccess.inputs;
for (var input of midiAccess.inputs.values()) {
input.onmidimessage = getMIDIMessage;
}}
In JS, getMIDIMessage will be called whenever a MIDI message comes in. How do I set a function as the value of the 'onmidimessage' property of the return value of navigator.requestMIDIAccess so that it will be called properly?
I tried variations of set! and aget and neither work. Perhaps I'm incorrectly or not setting the 'midiAccess' object globally... not sure.
UPDATE: overcame embarrassment and added my attempt:
(ns miditest.midi)
(defn onMIDISuccess [midiAccess]
(let [inputs (.values (.-inputs midiAccess))]
(js/console.log (first inputs))))
(defn onMIDIFailure []
(js/console.log "this browser does not support WebMIDI."))
(defn getMIDIMessage [message]
(let [command (first (.data message))
note (nth (.data message) 1)
velocity (nth (.data message) 2)]
(js/console.log (str command note velocity))))
(defn checkmidi []
(-> (.requestMIDIAccess js/navigator)
(.then #(onMIDISuccess %))
(.catch #(onMIDIFailure))
(.finally #(js/console.log "cleanup"))))
I'm not sure the .catch will work as I'm not sure how to get .requestMIDIAccess to fail.
You can use set!
.
(defn getMIDIMessage [message]
...)
(defn onMIDISuccess [midiAccess]
(-> midiAccess
.-inputs
(.forEach (fn [input key]
(set! input -onmidimessage getMIDIMessage)))))