Created
March 6, 2015 19:26
-
-
Save RyanJ93/8c0d78323ab13787ea51 to your computer and use it in GitHub Desktop.
Simple web MIDI API example
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
<html> | |
<head> | |
<style type="text/css"> | |
.text{ | |
font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; | |
font-size:16px; | |
} | |
.title{ | |
font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; | |
font-size:24px; | |
} | |
.bold{ | |
font-weight:bold; | |
} | |
</style> | |
<script type="text/javascript"> | |
var waveForm = 'sine'; | |
var globalVolume = 0; | |
var midi = null; | |
var devices = new Array(); | |
var dev = null; | |
var oscillator = null; | |
var gain = null; | |
var context = null; | |
var instances = new Array(); | |
function getFrequency(value){ | |
return (Math.pow(2, ( ( parseInt(value) - 69 ) / 12 )) * 440); | |
} | |
function getVelocity(value){ | |
return ( ( value * 100 ) / 127 ); | |
} | |
window.AudioContext = window.AudioContext||window.webkitAudioContext; | |
try{ | |
window.AudioContext = window.AudioContext || window.webkitAudioContext; | |
context = new AudioContext(); | |
}catch(e){ | |
console.log(e); | |
alert('Web Audio API is not supported in this browser'); | |
} | |
try{ | |
navigator.requestMIDIAccess().then(_event_success, function(){ | |
console.log("ERR"); | |
}); | |
}catch(ex){ | |
console.log(ex); | |
alert("NOT SUPPORTED"); | |
} | |
function _event_success(access){ | |
midi = access; | |
inputs = midi.inputs; | |
iterator = inputs.values(); | |
var i = 0; | |
while((data = iterator.next()).done === false){ | |
if ( data.value.type.toLowerCase() == 'input' ){ | |
devices[i] = { | |
dev: data.value, | |
name: data.value.name, | |
manufacturer: data.value.manufacturer, | |
version: data.value.version | |
}; | |
addDevice(data.value.name, i); | |
i++; | |
} | |
} | |
changeDevice(0); | |
return true; | |
} | |
function addDevice(name, id){ | |
var wrapper = document.getElementById('devices'); | |
var element = document.createElement('option'); | |
element.text = name; | |
element.setAttribute('value', parseInt(id)); | |
wrapper.appendChild(element); | |
return true; | |
} | |
function changeDevice(id){ | |
if ( id == null ){ | |
var element = document.getElementById('devices'); | |
id = element.options[element.selectedIndex].value; | |
} | |
try{ | |
dev.removeEventListener("midimessage", handleMIDIMessage); | |
}catch(ex){} | |
dev = devices[id].dev; | |
instances = new Array(); | |
dev.addEventListener("midimessage", handleMIDIMessage); | |
document.getElementById('dev-name').textContent = devices[id].name; | |
document.getElementById('dev-manufacturer').textContent = devices[id].manufacturer; | |
document.getElementById('dev-version').textContent = devices[id].version; | |
return true; | |
} | |
function handleMIDIMessage(event){ | |
try{ | |
if ( typeof(instances[event.data[1]]) == 'undefined' || instances[event.data[1]] == null ){ | |
instances[event.data[1]] = { | |
oscillator: context.createOscillator(), | |
gain: context.createGain(), | |
data: event.data | |
} | |
instances[event.data[1]].oscillator.type = waveForm; | |
instances[event.data[1]].oscillator.frequency.value = getFrequency(event.data[1]); | |
instances[event.data[1]].gain.gain.value = ( getVelocity(event.data[2]) - globalVolume ); | |
console.log(( getVelocity(event.data[2]) - globalVolume )); | |
instances[event.data[1]].oscillator.connect(instances[event.data[1]].gain); | |
instances[event.data[1]].gain.connect(context.destination); | |
instances[event.data[1]].oscillator.start(); | |
}else{ | |
if ( event.data[2] <= 0 ){ | |
instances[event.data[1]].oscillator.stop(); | |
instances[event.data[1]] = null; | |
}else{ | |
} | |
} | |
}catch(ex){ | |
console.log(ex); | |
} | |
return true; | |
} | |
function changeWaveForm(){ | |
var element = document.getElementById('waveform'); | |
waveForm = element.options[element.selectedIndex].value; | |
newRendering(); | |
return true; | |
} | |
function changeVolume(){ | |
globalVolume = document.getElementById('volume').value; | |
newRendering(); | |
return true; | |
} | |
function newRendering(){ | |
var buffer = null; | |
try{ | |
instances.forEach(function(entry){ | |
if ( typeof(entry) != 'undefined' && entry != null ){ | |
try{ | |
entry.oscillator.stop(); | |
}catch(ex){} | |
buffer = entry.data; | |
entry = null; | |
entry = { | |
oscillator: context.createOscillator(), | |
gain: context.createGain(), | |
data: buffer | |
} | |
entry.oscillator.type = waveForm; | |
entry.oscillator.frequency.value = getFrequency(buffer[1]); | |
entry.gain.gain.value = getVelocity(buffer[2]) - globalVolume; | |
entry.oscillator.connect(instances[buffer[1]].gain); | |
entry.gain.connect(context.destination); | |
entry.oscillator.start(); | |
} | |
}); | |
}catch(ex){ | |
console.log(ex); | |
} | |
return true; | |
} | |
</script> | |
</head> | |
<body> | |
<h1 class="title">Basic web Audio API & web MIDI API example</h1> | |
<br /> | |
<table cellpadding="0" cellspacing="0"> | |
<tr> | |
<td align="left" valign="middle" width="200"> | |
<span class="text">Found devices:</span> | |
</td> | |
<td align="left" valign="middle"> | |
<select id="devices" onChange="changeDevice(null);"></select> | |
</td> | |
</tr> | |
<tr> | |
<td align="left" valign="middle" width="200"> | |
<span class="text">Actual device:</span> | |
</td> | |
<td align="left" valign="middle"> | |
<span class="text bold" id="dev-name"></span> <span class="text">manufactured by</span> <span class="text bold" id="dev-manufacturer"></span> <span class="text bold">version:</span> <span class="text bold" id="dev-version"></span> | |
</td> | |
</tr> | |
<tr> | |
<td align="left" valign="middle" width="200"> | |
<span class="text">General volume:</span> | |
</td> | |
<td align="left" valign="middle"> | |
<input type="range" min="0" max="100" value="0" onChange="changeVolume();" id="volume" /> | |
</td> | |
</tr> | |
<tr> | |
<td align="left" valign="middle" width="200"> | |
<span class="text">Wave form:</span> | |
</td> | |
<td align="left" valign="middle"> | |
<select id="waveform" onChange="changeWaveForm();"> | |
<option value="sine" selected>Sine</option> | |
<option value="square">Square</option> | |
<option value="sawtooth">Sawtooth</option> | |
<option value="triangle">Triangle</option> | |
</select> | |
</td> | |
</tr> | |
</table> | |
<br /><br /><br /> | |
<span class="text">Note: For use the MIDI APIs you must use Google Chrome Canary and activate the experimental flag on <pre>chrome://flags</pre></span> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment