Created
February 6, 2012 16:11
-
-
Save jussi-kalliokoski/1752949 to your computer and use it in GitHub Desktop.
A simple proposal for the interfaces needed for useful MIDI access
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
// Example usage, a MIDI proxy that picks the first available MIDI input and routes its messages to the first MIDI outputs | |
navigator.getUserMedia({midi: true}, function (MIDIAccess) { | |
try { | |
var input = MIDIAccess.getInput(MIDIAccess.enumerateInputs()[0]); | |
var output = MIDIAccess.getOutput(MIDIAccess.enumerateInputs()[0]); | |
} catch (e) { | |
console.error("Couldn't find suitable MIDI devices"); | |
} | |
console.log('Input:', input.deviceManufacturer, input.deviceName); | |
console.log('Output:', output.deviceManufacturer, output.deviceName); | |
input.addEventListener('midimessage', function (e) { | |
e.MIDIEvents.forEach(function (e) { | |
console.log('Received a MIDI event (status:', e.status, 'data:', e.data, ')'); | |
output.sendMIDIMessage(e); | |
}); | |
}); | |
}); |
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
// This example shows how to interpret key presses and releases from the MIDI data, extracted from the first available input device. | |
var noteNames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']; | |
navigator.getUserMedia({midi: true}, function (MIDIAccess) { | |
// Try to get access to the first available MIDI input | |
try { | |
var input = MIDIAccess.getInput(MIDIAccess.enumerateInputs()[0]); | |
} catch (e) { | |
console.error("Couldn't find a suitable input"); | |
return; | |
} | |
input.addEventListener('midimessage', function (e) { | |
// Discard all but NoteOff and NoteOn | |
if (e.status !== 0x8C && e.status !== 0x9C) return; | |
// Calculate the note name. | |
var note = noteNames[e.data[0] % 12] + (Math.floor(e.data[0] / 12) - 1); | |
// Log the input | |
console.log(e.status === 0x8C ? 'NoteOn' : 'NoteOff', ':', note, 'velocity:', e.data[1]); | |
}); | |
}); |
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
// This example shows how to create a simple JS sequencer that can be enumerated by DAW software and then chosen by the user to play a virtual instrument or whatever. | |
var sequence = [36, 48, 55, 48]; // C3 C4 G4 C4 | |
var seqPos = 0; | |
navigator.getUserMedia({midi: true}, function (MIDIAccess) { | |
// Attempt to create a virtual output device. | |
try { | |
var outputID = MIDIAccess.createVirtualDevice("JS Sequencer", "World Wide Web"); | |
var output = MIDIAccess.getOutput(outputID); | |
} catch (e) { | |
console.error("The system doesn't support creating virtual MIDI devices."); | |
} | |
console.log('Output:', output.deviceManufacturer, output.deviceName); | |
setInterval(function () { | |
// Send NoteOff for the previous note | |
output.sendMIDIMessage( | |
MIDIAccess.createMIDIMessage(0x9C, sequence[seqPos], 127) | |
); | |
// Progress the sequencer | |
seqPos = (seqPos + 1) % sequence.length; | |
// Send NoteOn for the current note | |
output.sendMIDIMessage( | |
MIDIAccess.createMIDIMessage(0x8C, sequence[seqPos], 127) | |
); | |
}, 250); | |
}); |
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
interface MIDIMessage { | |
readonly attribute unsigned long timeStamp; | |
readonly attribute short status; | |
readonly attribute Uint8Array data; | |
readonly attribute short channel; | |
} | |
interface MIDIDataEvent : Event { | |
readonly attribute sequence<MIDIMessage> MIDIMessages; | |
} | |
partial interface ProcessMediaEvent implements MIDIDataEvent { | |
// FIXME: This should be a property of the MIDIMessage's in the MIDIMessageSequence of MIDIDataEvent. | |
readonly attribute float sampleTime; | |
} | |
interface MIDIDevice implements EventTarget { | |
readonly attribute string deviceName; | |
readonly attribute string deviceManufacturer; | |
readonly attribute string deviceVersion; | |
// A unique ID for a certain device, up to the browser vendor to detect how it's generated, because it doesn't really matter, as long as they're unique. | |
readonly attribute string deviceFingerprint; | |
attribute EventListener ondevicedisconnect; | |
} | |
interface MIDIInputDevice { | |
readonly attribute string deviceType = "INPUT"; | |
attribute EventListener onmidimessage; | |
} | |
interface MIDIOutputDevice { | |
readonly attribute string deviceType = "OUTPUT"; | |
// Return success | |
boolean sendMIDIMessage(MIDIMessage); | |
} | |
interface MIDIAccess { | |
sequence<MIDIDevice> enumerateInputs(); | |
sequence<MIDIDevice> enumerateOutputs(); | |
// Return the deviceFingerprint of the created device, throw an exception if feature not implemented. | |
string createVirtualDevice(string deviceName, string deviceManufacturer); | |
MIDIInputDevice getInput(MIDIDevice target); | |
MIDIOutputDevice getOutput(MIDIDevice target); | |
MIDIInputDevice getInput(String targetFingerprint); | |
MIDIOutputDevice getOutput(String targetFingerprint); | |
MIDIMessage createMIDIMessage(short status, short data1 = 0, short data2 = 0, short channel = 0, timeStamp = CURRENT_TIME); | |
MIDIMessage createMIDIMessage(short status, Uint8Array data, timeStamp = CURRENT_TIME); | |
} | |
partial interface ProcessedMediaStream { | |
void addInput(MIDIInputDevice device); | |
void addOutput(MIDIOutputDevice device); | |
} | |
partial dictionary MediaStreamOptions { | |
boolean midi; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment