The Web Audio API is a BEAST. Most tutorials I have come across focus on the amazing features set it has. But how the hell do we play a simple sound or music file? Read on and I will show you.

(Here is another post I wrote giving an introduction to what WebAudio is and its features)

I have seen web audio implemented in a few different ways. It’s up to you what suits you best in terms of understanding and readability.
My preferred system uses two Java Script files for code separation and clarity.

buffer-loader.js (loads and decodes the audio files we want to play)
web-audio-controller.js (creates the web audio objects and controls playing of sounds)
lets start with the Buffer Loader. This file acts as utility loader external audio files for use with Web Audio. You don’t need to focus too much on how it works or edit it, just make sure you import it before your web-audio controller.

function BufferLoader(context, urlList, callback) {
  this.context = context;
  this.urlList = urlList;
  this.onload = callback;
  this.bufferList = new Array();
  this.loadCount = 0;
}

BufferLoader.prototype.loadBuffer = function(url, index) {
  // Load buffer asynchronously
  var request = new XMLHttpRequest();
  request.open("GET", url, true);
  request.responseType = "arraybuffer";

  var loader = this;

  request.onload = function() {
    // Asynchronously decode the audio file data in request.response
    loader.context.decodeAudioData(
      request.response,
      function(buffer) {
        if (!buffer) {
          alert('error decoding file data: ' + url);
          return;
        }
        loader.bufferList[index] = buffer;
        if (++loader.loadCount == loader.urlList.length)
          loader.onload(loader.bufferList);
      },
      function(error) {
        console.error('decodeAudioData error', error);
      }
    );
  }

  request.onerror = function() {
    alert('BufferLoader: XHR error');
  }

  request.send();
}

BufferLoader.prototype.load = function() {
  for (var i = 0; i < this.urlList.length; ++i)
  this.loadBuffer(this.urlList[i], i);
}

 

Ok, so now lets move to out web-audio-controller, as this is where the magic happens and where you will be adding your audio clip references

 


window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();

//these are the variables which will be referenced by the index page
var snd_someSound1;
var snd_someSound2;
var snd_someMusic1;

//buffer loader loads
var bufferLoader;

//buffer loader is a js class used to load multiple files
bufferLoader = new BufferLoader(
    context,
    [
     'audio/some-sound1.mp3',
     'audio/some-sound2.mp3',
     'audio/some-music1.mp3'
    ],
    finishedLoading
 );

 bufferLoader.load();

 //callback once all the files have loaded
function finishedLoading(bufferList) {

	  //create the source sound containers
	  snd_someSound1 = context.createBufferSource();
	  snd_someSound2 = context.createBufferSource();
	  snd_someMusic1 = context.createBufferSource();

	  //add buffers to the containers and accociate them with the loaded files. (Same order they were loaded in
	  snd_someSound1.buffer = bufferList[0];
	  snd_someSound2.buffer = bufferList[1];
	  snd_someMusic1.buffer = bufferList[2];

	 //sounds are ready to be played
}

//We will call this function from the index file
//it might look messy/crazy, but every time you want to play/replay a sound in Web Audio, you need to re-create the contect and connection.
function playSound(sound, volume, loop)
{
	  //set some default values for the functions volume and loop parameters
	  volume = typeof volume !== 'undefined' ? volume : 1;
	  loop = typeof loop !== 'undefined' ? loop : false;

	  var source = context.createBufferSource(), g = context.createGain();
	  source.buffer = sound.buffer;
	  source.loop = loop;
	  g.gain.value = volume;
	  source.connect(g);
	  g.connect(context.destination);
	  source.start(0);
}

 

And finally the index file, from which we will use a simple JQuery click event to  play a sound through the controller we created above.


<!DOCTYPE HTML>
<html>

<head></head>

	<body>

	    $(document).ready(function () {

			<!-- touch or click the page to play sound -->
            $('body').on('click touchend', function(e){

				//play sound 1
                playSound(snd_someSound1);    

				//play music at the same time on a loop
                playSound(snd_someMusic1, 1, true);    

            });
        });	

			<script src="js/buffer-loader.js"></script>
			<script src="js/web-audio-controller.js"></script>
			<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	</body>

</html>

 

To make your life easier, i have bundled the sample project into a zipped folder, all you need to do is update the file paths in the web-audio-controller with your own.
Get project here