On Github cwilso / WebAudioSlides
<audio> hides the steps of loading, decoding and playing
<audio controls src="mysound.ogg"></audio>
var myBuffer = null;
var context = new AudioContext(); // webkit prefix alert!
function loadDogSound(url) {
var request = new XMLHttpRequest();
request.open("GET", "dogBarking.mp3", true);
request.responseType = "arraybuffer";
request.onload = function() {
context.decodeAudioData( request.response,
function(buffer) { myBuffer = buffer; } ); }
request.send();
}
function playSound( buffer ) {
var sourceNode = audioContext.createBufferSource();
sourceNode.buffer = myBuffer;
sourceNode.connect( audioContext.destination );
sourceNode.start( 0 );
}
Web Audio runs in a separate thread, so audio and graphics don't compete as much.
You schedule Web Audio events in the future, and the system takes care of them.
function playEverySecondForTenSeconds( myBuffer ) {
for (var i=0; i<10; i++) {
var sourceNode = context.createBufferSource();
sourceNode.buffer = myBuffer;
sourceNode.connect( context.destination );
sourceNode.start( context.now + i );
}
}
interface AudioParam {
attribute value;
// Parameter automation
void setValueAtTime( value, time );
void linearRampToValueAtTime( value, time );
void exponentialRampToValueAtTime( value, time );
void setTargetAtTime( target, time, timeConstant );
void setValueCurveAtTime( values, time, duration );
void cancelScheduledValues( startTime );
}
var envelope = context.createGain(); mySoundNode.connect( envelope ); envelope.connect( context.destination ); var now = context.currentTime; envelope.gain.setValueAtTime( 0, now ); envelope.gain.linearRampToValueAtTime( 1.0, now + 2.0 ); envelope.gain.linearRampToValueAtTime( 0.0, now + 4.0 ); mySoundNode.start(0);
window.addEventListener('load', function() {
navigator.requestMIDIAccess().then(
onMIDIInit,
onMIDISystemError );
});
function onMIDIInit( midi ) {
var list=midi.outputs();
for (var i=0; i<list.length; i++) {
list[i].send( [0x90, 3, 32] );
}
}
function onMIDIInit( midi ) {
for (var input of midiAccess.outputs.values())
input.send( [0x90, 3, 32] );
}
function onMIDIInit( midi ) {
var list=midi.inputs();
for (var i=0; i<list.length; i++)
list[ i ].onmidimessage = midiMessageReceived;
}
function onMIDIInit( midi ) {
for (var input of midiAccess.inputs.values())
input.onmidimessage = midiMessageReceived;
}
function midiMessageReceived( ev ) {
var cmd = ev.data[0] >> 4;
var channel = ev.data[0] & 0xf;
var noteNumber = ev.data[1];
var velocity = 0;
if (ev.data.length > 2)
velocity = ev.data[2];
// MIDI noteon with velocity=0 is the same as noteoff
if ( cmd==8 || ((cmd==9)&&(velocity==0)) ) { // noteoff
noteOff( noteNumber );
} else if (cmd == 9) { // note on
noteOn( noteNumber, velocity);
} else if (cmd == 11) { // controller message
controller( noteNumber, velocity);
} else {
// probably sysex!
}
}