Skip to content

Instantly share code, notes, and snippets.

@nealey
Created March 18, 2018 16:46
Show Gist options
  • Save nealey/4fba3cc29559d850e5d049e23c6f6dce to your computer and use it in GitHub Desktop.
Save nealey/4fba3cc29559d850e5d049e23c6f6dce to your computer and use it in GitHub Desktop.
WebMIDI explorer: prints all MIDI messages, and lets you craft messages to send
<!DOCTYPE html>
<html>
<head>
<title>Web MIDI explorer</title>
<style>
.message span {
padding: 0.5em;
}
.message .type {
font-weight: bold;
}
.message .device {
color: blue;
}
</style>
<script>
function print(type, device, s) {
let output = document.querySelector("#output");
let line = document.createElement("div");
let typeEl = document.createElement("span");
let deviceEl = document.createElement("span");
let strEl = document.createElement("span");
typeEl.textContent = type;
deviceEl.textContent = device;
strEl.textContent = s;
line.classList.add("message");
typeEl.classList.add("type");
deviceEl.classList.add("device");
strEl.classList.add("str");
line.appendChild(typeEl);
line.appendChild(deviceEl);
line.appendChild(strEl);
output.appendChild(line);
line.scrollIntoView();
}
function hexlify(vals) {
return vals.map(x => "0x" + x.toString(16)).join(" ");
}
function midimessage(e) {
let input = e.target;
let data = Array.from(e.data);
print(input.type, input.name, hexlify(data));
}
function addOutput(output) {
let outputList = document.querySelector("#devices");
let dev = document.createElement("option");
dev.textContent = output.name;
dev.device = output;
outputList.appendChild(dev);
}
function send(e) {
e.preventDefault();
let outputList = document.querySelector("#devices");
let output = outputList.selectedOptions[0].device;
let valuesStr = document.querySelector("#values").value;
let dataStr = valuesStr.split(/ +/);
let data = dataStr.map(Number);
output.send(data);
print("output", output.name, hexlify(data));
}
function accessEvent(e) {
print("meta", "", "access event state change, see console (reload to probe devices again)");
console.log(e);
}
window.inputs = []
window.outputs = []
function run(access) {
for (let input of access.inputs.values()) {
let n = window.inputs.length;
window.inputs.push(input);
print("meta", input.name, "assigned window.inputs[" + n + "]");
input.addEventListener("midimessage", midimessage);
}
for (let output of access.outputs.values()) {
let n = window.outputs.length;
window.outputs.push(output);
print("meta", output.name, "assigned window.inputs[" + n + "]");
addOutput(output);
}
access.addEventListener("statechange", accessEvent);
document.querySelector("form").addEventListener("submit", send);
}
function request() {
print("meta", "", "Use the JavaScript console for more advanced tomfoolery.");
print("meta", "", "detecting MIDI devices...");
navigator.requestMIDIAccess().then(run);
}
window.addEventListener("load", request);
</script>
</head>
<body>
<h1>Web MIDI explorer</h1>
<form>
<select id="devices"></select>
<input id="values">
<button type="submit" id="send">send</button>
</form>
<div id="output" style="height: 12em; overflow: auto;"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment