Last active
April 1, 2021 14:56
-
-
Save michaelhood/925adcc5345e80c2b4e1d7f49f1676fd to your computer and use it in GitHub Desktop.
webmidi hax
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="devices"></div> | |
<br/> | |
<h3>Select your midi device, play some notes.</h3> | |
<br/> | |
<div id="letters"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// depends on https://cdn.jsdelivr.net/npm/[email protected] | |
// 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+'"> '+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 } )) | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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