Skip to content

Instantly share code, notes, and snippets.

@michaelhood
Last active April 1, 2021 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelhood/925adcc5345e80c2b4e1d7f49f1676fd to your computer and use it in GitHub Desktop.
Save michaelhood/925adcc5345e80c2b4e1d7f49f1676fd to your computer and use it in GitHub Desktop.
webmidi hax
<div id="devices"></div>
<br/>
<h3>Select your midi device, play some notes.</h3>
<br/>
<div id="letters"></div>
// depends on https://cdn.jsdelivr.net/npm/webmidi@2.5.1
// via https://github.com/djipco/webmidi
WebMidi.enable(function (err) {
dbox = document.getElementById("devices")
if (err) {
console.log("WebMidi failed", err)
throw "that's bad"
} else {
console.log("WebMidi enabled")
di=0;
WebMidi.inputs.forEach(d=>{
if (di == 0) { checked = 'checked'; } else { checked = ''; }
dbox.insertAdjacentHTML("beforeend", '<input type="radio" '+checked+' id="device-'+d.id+'" name="indevice" value="' + d.id + '"><label for="device-'+d.id+'">&nbsp;'+d.name+'</label><br>');
++di;
})
const m = {}
m.in = WebMidi.inputs[0]
// m.out = WebMidi.outputs[0]
ltrbox = document.getElementById("letters")
var sustained = false
const midiRange = [0, 127]
const asciiRange = [48,126]
const rmap1 = (x1, y1, x2, y2, v) => Math.max(Math.min(Math.floor((v - x1) * (y2 - x2) / (y1 - x1) + x2), y2), x2)
const rmap = (v) => rmap1(midiRange[0], midiRange[1], asciiRange[0], asciiRange[1], v)
window.rmap=rmap
const noteHandler = function (e) {
lowestData = Math.min.apply(null, Array.from([e.data[1], e.data[2]]))
console.log(e.data[0], e.data[1], e.data[2])
s = String.fromCharCode(rmap(lowestData)).toLowerCase()
if (sustained) {
// shouting mode enabled
s = s.toUpperCase()
}
ltrbox.insertAdjacentHTML("beforeend", s)
}
const sustainer = function(e) {
// yay global state manipulation
if (e.data[1] == 64 && e.data[2] == 127) {
sustained = true
}
if (e.data[1] == 64 && e.data[2] == 0) {
sustained = false
}
}
dbox.addEventListener("change", function(evt) {
m.oldIn = m.in
m.in = WebMidi.getInputById(evt.target.value)
console.log("changed devices", evt.target.value)
m.oldIn.removeListener()
m.in.addListener("noteon", "all", noteHandler)
m.in.addListener("controlchange", "all", sustainer)
})
dbox.querySelector("input").dispatchEvent(new Event("change", { bubbles: true } ))
}
});
<script src="https://cdn.jsdelivr.net/npm/webmidi@2.5.1"></script>
body {
margin: 18px;
}
h3 {
margin: 0;
display: inline;
}
#devices {
width: 600px;
}
#letters {
width: 600px;
min-height: 150px;
padding: 9px;
overflow-wrap: break-word;
border: thin solid;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment