Created
May 1, 2016 23:07
-
-
Save rudle/1007b15e84d70423fb59675182d3c4e0 to your computer and use it in GitHub Desktop.
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
var ChordSpeller = { | |
chord: {}, // this represents the cord the user is holding down. map[string] -> int | |
chordView: null, // cached chord view | |
self: this, | |
init: function() { | |
console.log("requesting MIDI access"); | |
if (navigator.requestMIDIAccess) { | |
navigator.requestMIDIAccess({ | |
sysex: false | |
}).then(ChordSpeller.onMIDISuccess, ChordSpeller.onMIDIFailure); | |
} else { | |
alert("No MIDI support in your browser."); | |
} | |
return; | |
}, | |
onMIDIMessage: function(event) { | |
console.log(event.data) | |
switch (event.data[0] & 0xf0) { | |
case 0x90: | |
if (event.data[2]!=0) { // if velocity != 0, this is a note-on message | |
ChordSpeller.noteOn(event.data[1]); | |
return; | |
} | |
// if velocity == 0, fall thru: it's a note-off. MIDI's weird, y'all. | |
case 0x80: | |
ChordSpeller.noteOff(event.data[1]); | |
return; | |
} | |
}, | |
onMIDIFailure: function(error) { | |
// when we get a failed response, run this code | |
console.log("No access to MIDI devices or your browser doesn't support WebMIDI API. Please use WebMIDIAPIShim " + error); | |
}, | |
// midi functions | |
onMIDISuccess: function(midiAccess) { | |
midi = midiAccess; | |
var inputs = midi.inputs.values(); | |
// loop over all available inputs and listen for any MIDI input | |
for (var input = inputs.next(); input && !input.done; input = inputs.next()) { | |
// each time there is a midi message call the onMIDIMessage function | |
console.log("detected input: " + input.value.manufacturer + " " + input.value.name); | |
input.value.onmidimessage = ChordSpeller.onMIDIMessage; | |
} | |
}, | |
noteNumberToLetter: function(noteNumber, bias) { | |
if (bias === null){ | |
bias = "#"; | |
} | |
switch (noteNumber % 12) { | |
case 0: | |
return "C"+bias; | |
break; | |
case 1: | |
return "C#"+bias; | |
break; | |
case 2: | |
return "D"+bias; | |
break; | |
case 3: | |
return "D#"+bias; | |
break; | |
case 4: | |
return "E"+bias; | |
break; | |
case 5: | |
return "F"+bias; | |
break; | |
case 6: | |
return "F#"+bias; | |
break; | |
case 7: | |
return "G"+bias; | |
break; | |
case 8: | |
return "G#"+bias; | |
break; | |
case 9: | |
return "A"+bias; | |
break; | |
case 10: | |
return "A#"+bias; | |
break; | |
case 11: | |
return "B"+bias; | |
break; | |
default: | |
console.log("math is broken"); | |
break; | |
} | |
}, | |
MIDIMessageEventHandler: function (event) { | |
// Mask off the lower nibble (MIDI channel, which we don't care about) | |
switch (event.data[0] & 0xf0) { | |
case 0x90: | |
if (event.data[2]!=0) { // if velocity != 0, this is a note-on message | |
noteOn(event.data[1]); | |
return; | |
} | |
// if velocity == 0, fall thru: it's a note-off. MIDI's weird, y'all.; | |
case 0x80: | |
noteOff(event.data[1]); | |
return; | |
} | |
}, | |
renderChord: function() { | |
console.log(ChordSpeller.chord) | |
if (this.chordView === null) { | |
this.chordView = document.getElementById('chord'); | |
} | |
this.chordView.innerHTML = Object.keys(this.chord).join(" "); | |
}, | |
addToChord: function(noteNumber) { | |
name = ChordSpeller.noteNumberToLetter(noteNumber); | |
ChordSpeller.chord[name] = true; // TODO store velocity instead | |
ChordSpeller.renderChord(); | |
}, | |
removeFromChord: function(noteNumber) { | |
name = ChordSpeller.noteNumberToLetter(noteNumber); | |
delete ChordSpeller.chord[name]; | |
ChordSpeller.renderChord(); | |
}, | |
noteOn: function(noteNumber) { | |
return this.addToChord(noteNumber); | |
}, | |
noteOff: function(noteNumber) { | |
return this.removeFromChord(noteNumber); | |
}, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment