title: Sound effects in JavaScript / HTML5
body: <p>I'm using HTML5 to program games; the obstacle I've run into now is how to play sound effects.</p>
  
  <p>The specific requirements are few in number:</p>
  
  <ul>
  <li>Play and mix multiple sounds,</li>
  <li>Play the same sample multiple times, possibly overlapping playbacks,</li>
  <li>Interrupt playback of a sample at any point,</li>
  <li>Preferably play WAV files containing (low quality) raw PCM, but I can convert these, of course.</li>
  </ul>
  
  <p>My first approach was to use the HTML5 <code>&lt;audio&gt;</code> element and define all sound effects in my page. Firefox plays the WAV files just peachy, but calling <code>#play</code> multiple times doesn't really play the sample multiple times. From my understanding of the HTML5 spec, the <code>&lt;audio&gt;</code> element also tracks playback state, so that explains why.</p>
  
  <p>My immediate thought was to clone the audio elements, so I created the following tiny JavaScript library to do that for me (depends on jQuery):</p>
  
  <pre><code>var Snd = {
    init: function() {
      $("audio").each(function() {
        var src = this.getAttribute('src');
        if (src.substring(0, 4) !== "snd/") { return; }
        // Cut out the basename (strip directory and extension)
        var name = src.substring(4, src.length - 4);
        // Create the helper function, which clones the audio object and plays it
        var Constructor = function() {};
        Constructor.prototype = this;
        Snd[name] = function() {
          var clone = new Constructor();
          clone.play();
          // Return the cloned element, so the caller can interrupt the sound effect
          return clone;
        };
      });
    }
  };
  </code></pre>
  
  <p>So now I can do <code>Snd.boom();</code> from the Firebug console and play <code>snd/boom.wav</code>, but I still can't play the same sample multiple times. It seems that the <code>&lt;audio&gt;</code> element is really more of a streaming feature rather than something to play sound effects with.</p>
  
  <p>Is there a clever way to make this happen that I'm missing, preferably using only HTML5 and JavaScript?</p>
  
  <p>I should also mention that, my test environment is Firefox 3.5 on Ubuntu 9.10. The other browsers I've tried - Opera, Midori, Chromium, Epiphany - produced varying results. Some don't play anything, and some throw exceptions.</p>