domingo, 2 de septiembre de 2012

Play Sound on Hover – Web Audio API Edition

Play Sound on Hover – Web Audio API Edition:
I got an email from a Notary Sojac who saw my tutorial on playing a sound on hover. In that tutorial we had to resort to some fairly hackish behavior to get the sound to react nicely to our events. Notary Sojac had an update to make the existing code work better, but more importantly, was looking into the Web Audio API for doing stuff like this. I didn't even know that was a thing. Turns out it's not controlling HTML5 audio elements, it's deeper level access than that.
The following is a guest post by Notary Sojac explaining all that.
We're all impressed with the capabilities of HTML5 canvas. The idea of creating a standardized and logical way of performing 2d drawing operations opened the door to an amazing new world where one programmer could learn one language and develop amazing products that could be deployed to all relevant platforms! Think about how critical this is for a moment. Now think about who would want an amazing graphics application that has a buggy, glitchy sound system that only makes sounds moments after you clicked and sometimes forgets to make sounds all together? That's the kind of product you get (especially in mobile platforms) if you go the HTML5 <audio> element route. It's better in desktop browsers, but unfortunately will never be perfected due to reasons beyond the scope of this article. But as of now, for the desktop, there is still hope. And there is hope in the future for mobile applications as well. That hope is named...

Web Audio API

The web audio API is designed for high precision and low level access. You can literally write bits of data to the samples. I'm not 100% sure what a sample is, but I think it has to do with air pressure against a microphone (aka, the microphone's driver position) at a single moment in time. That's pretty low level if you ask me. In Google Chrome, all audio functions are handled by a separate thread to ensure non-wonkyness.
On August 21st, Mozilla began making public the fact that they're dropping their original, pioneering "Audio Data API" and are beginning to implement Google's "Web Audio API" in their browser. But that means, at the time of this writing, you'll need to use a fallback for Firefox.
You can hear a great deal of good information from this Google I/O talk by Chris Wilson:

How To Use It

Unfortunately you need to use a lot more JavaScript with the Web Audio API than you do with plain old HTML5 audio elements, but often times the precision of the Web Audio API is imperative.
First we need to load the sound, which can be done with a function like this:
// you'll put the PCM audio in here
var audioBuffer = null;  
var context = new webkitAudioContext();

function loadDogSound(url, variableToBufferSound) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.responseType = 'arraybuffer';

  // Decode asynchronously
  request.onload = function() {
    context.decodeAudioData(request.response, function(buffer) {
      variableToBufferSoundIn = buffer;
    }, onError);
  }
  request.send();
}
Then we play the buffer, with a function like this:
function playSound(buffer) {

  // creates a sound source
  var source = context.createBufferSource();

  // tell the source which sound to play
  source.buffer = buffer;          

  // connect the source to the context's destination (the speakers)           
  source.connect(context.destination);       
  
  // play the source now
  source.noteOn(0);                          
}
That's a heck of a lot more code than we need as designers, just trying to play simple mouseover sound effects. Luckily, I snapped together a little JavaScript framework for using the Web Audio API.
With this new API, all one needs to do is:
  1. Create an AudioContext
  2. Load a sound into that AudioContext
  3. Play the sound
All of these steps are one liners! Fallbacks to good old HTML5 are included!
<script src="javascripts/webAudioApiForDesigners.js"></script>

<script>
// 1
var context = initializeNewWebAudioContext();

// 2
context.loadSound('audio/beep.ogg', 'beep');

$("#nav-one a")
  .mouseenter(function() {
    // 3
   context.playSound('beep');
  });
</script>
View Demo

List of reasons why HTML5 audio elements may be a bad choice

  • Wonky latency problems where sounds are heard at wrong times
  • Unexplainable popping sounds when playing multiple sound files at once
  • Limit to number of HTML5 audio elements that can play simultaneously

Reasons why HTML5 might be more suitable to your project

  • Very simple and straightforward to use
  • Can play background music just fine
  • Eventually (wild guess: no sooner than within the next 3 years) the bugs will be ironed out of these sorts of html DOM elements

More Information

HTML5 Rocks has a solid introduction.
Play Sound on Hover – Web Audio API Edition is a post from CSS-Tricks

JavaScript Slideshow Code + CSS3 Transitions

JavaScript Slideshow Code + CSS3 Transitions:
JavaScript Slideshow Code
TinyFader2 is a 2KB JavaScript slider code that is completely configurable through robust options. It is an upgrade to the previous TinyFader version adding a number of requested features and making additional improvements. It gracefully degrades without JavaScript support and is totally customizable using CSS.
Here are the current features:
  • CSS3 hardware transition support for Firefox and Webkit browsers
  • Automatic or manual slide rotation
  • Option to resume play after interruption
  • Toggle to pause auto play on slide hover
  • Set the initial slide index with a parameter
  • Pass a navigation ID of a list and have the script bind either click or hover events for navigating the slideshow
  • Ability to move to previous or next slide
  • Functions to play and pause the automatic slideshow
  • Parameter to set the transition duration
Other improvements include setting the opacity to 0 on slides besides the current one, cycling the z-index, improving code readability, upgrading the codebase to HTML5, and a handful of other tweaks.
To initialize the script use the following:
var ss = new TINY.fader.init("ss", {
 id: "slides", // ID of the slideshow list container
 position: 0, // index where the slideshow should start
 auto: 0, // automatic advance in seconds, set to 0 to disable auto advance
 resume: true, // boolean if the slideshow should resume after interruption
 navid: "pagination", // ID of the slide nav list
 activeClass: "current", // active class for the nav relating to current slide
 pauseHover: true, // boolean if the slideshow should pause on slide hover
 navEvent: "click", // click or mouseover nav event toggle
 duration: .25 // duration of the JavaScript transition in seconds, else the CSS controls the duration, set to 0 to disable fading
});
The first parameter is the variable name used for the object instance. This script has been tested in all major browsers and is available free of charge for both personal or commercial projects under the GNU GPL v3.0 license.

Click here for the demo.



Click to download
Downloaded 3 Times