Web MIDI Post-Mortem


After some more digging, I have found a way to get MIDI device inputs to work in a Web export with Godot 4.2

First, I found that the proper name for the format I sought to use is an API literally called Web MIDI. I'm not sure if I encountered its proper name before but if I did it slipped by me. Now I had something concrete to search for, though. That led to this post from six years ago:

https://gist.github.com/srejv/b7198e25587e2d8e0a66860781b56852 

where the JavaScript function navigator.requestMIDIAccess is used. It required some changes, and it's a bit messy as it uses a string to store the contents of the main JavaScript function (this may cause some security flags when uploaded? not sure, only tested with local host so far), but it does indeed give a way to read MIDI device messages.

The main change required was to either change several appearances of JavaScript to JavaScriptBridge, or to set a variable to do the same. I assume that either the person who wrote this example defined that elsewhere or some update to Godot since then introduced JavaScriptBridge and gave it the functions that are used in this example.

Also, whereas my MIDI setup for Desktop uses Godot's input event system and can run its own process on demand for each separate MIDI event, this system receives the MIDI data in an array containing all events since the prior update. I adjusted this to run it on the physics timestep instead, which was unused and so I could set its per-frame tick rate as desired (I picked 8x the frame rate, or 480 hz). Now it's outputting all MIDI events, if any occurred, on each of those 480hz ticks, which is close enough to normal MIDI latency that it's acceptable to me.

From there, I had to alter my existing polyphonic audio stream code to read the proper values from the MIDI event array on each physics step. The structure of the array is such that data[n][0] gives the message type for each event, and data[n][1] gives the MIDI note number. Velocity is not needed in this setup, but is accessible from data[n][2]. Using a for loop and the size of the data array, each event in the array can be run through the polyphonic audio stream code to check for note on and off signals and pitch data as normal. It just works.

If anyone is looking to do a similar implementation and having trouble figuring it out(, and you happen to see this... ), feel free to reach out. Also, I plan to update the web version of my game once the Jam's ratings period is over, as I cannot make changes to it until then.

Get Stumpville

Leave a comment

Log in with itch.io to leave a comment.