With each new browser’s update, the web gets richer and richer. The features that were supposed to be hacked are now becoming built-in features of the browser. While talking about producing sound effects on the web, we didn’t have many capabilities before Web Audio API was introduced. Before the release of this API, we had to depend on the <audio> tag to do all kind of sound stuff on the web. You might be familiar with the hacks involving hiding the audio tag with some audio file loaded and playing it when needed.

 

We had to play with the same kind of tricks to provide users with sound effects on an action, like clicking on buttons in a game, on some other user inputs in web apps uncategorizable as typical sites. Using Web Audio API, not only you can play audio files but also generate sound in the browser itself using oscillators. In this post, we are going to learn to implement basic sound effects on user-input. Onwards!

 

The Basics

Initialising the ‘Audio Context’

The first think you need to do is create an audio context with the following constructor call

var ctx= new audioContext();

 

Creating an audio source.

The audio context has several sources available. For our purpose, we need ‘oscillator’ as the source:

var osc= ctx.createOscillator();

 

What is an oscillator? In the real world, your voice has vocal folds as oscillator, music instruments like piano, and guitar have strings as their oscillator. On the web, it’s just an audio-processing node representing a periodic waveform. Here’s how MDN puts it

“The OscillatorNode interface represents a periodic waveform, like a sine wave. It is an AudioNode audio processing module that causes a given frequency of sine wave to be created — in effect, a constant tone.”

 

You can just think of oscillator as being the oscillator of a piano. From the name piano, I remember you should really check this Chrome Audio Samples page out as an inspiration for the API being discussed.

 

Creating an Effect Filter

We need effect filter to control the source (e.g. to control the volume):

var gain= ctx.createGain();

 

Gain Node is one of the effect filters available. You can use it to control the volume of the source (oscillator in our case).

 

Establishing Connection

The connection is established using ‘connect’ method to the node we want to connect from. The node that we want to connect to is provided as the argument to the method.

 

We need to connect our source, the oscillator to effect filter:

osc.connect(gain);

 

And effect filter to Audio Destination i.e. the node we want to output the sound to (like speakers). This is what will make our audio output to the speakers-

gain.connect(aud.destination);

 

Now we’ve several methods available of ‘osc’

To start the oscillator, we call ‘start’ method on it

osc.start(); //sound starts

 

To set the frequency in ‘hertz’, we use frequency property

osc.frequency.value= 1000;

 

To control the volume, we do the following

gain.gain.value= 10;

 

An oscillator has five types namely “sine” (the default one), “sawtooth“, “square“, “triangle” and “custom

osc.type= "sawtooth";

 

Here is an example showing how oscillator sounds with each type and how it changes with frequency and gain.value (Make sure your speakers are up!)

[codepen_embed height=”507″ theme_id=”21620″ slug_hash=”xVqgjQ” default_tab=”result” user=”devstreak”]See the Pen <a href=’http://codepen.io/devstreak/pen/xVqgjQ/’>Sounds effect on User Input</a> by Devstreak (<a href=’http://codepen.io/devstreak’>@devstreak</a>) on <a href=’http://codepen.io’>CodePen</a>.[/codepen_embed]

 

We can stop the oscillator at any point by using

osc.stop();

 

But keep in mind that ‘start’ and ‘stop’ methods can be used only once. If you want ‘start’, ‘stop’ thing on an oscillator, set gain.value to zero and non-zero instead.

 

Creating Sound effects on User Input

Let’s get to the main purpose of this post. Using the knowledge we learned above, we are going to create a function which on calling will produce a sound of given type, frequency, gain and for a given time.

 

var ctx= new AudioContext(); //create audio context

function createSound(fr, time, _type, vol) {
  var osc= ctx.createOscillator(), //create oscillator (source)
  gain= ctx.createGain(); //create Gain Node (effect filter)

  //connect oscillator to gain 
  osc.connect(gain);

  //connect gain to speakers
  gain.connect(ctx.destination);

  //set oscillator's type
  osc.type= _type;

  //set frequency
  osc.frequency.value= fr;

  //set volume
  gain.gain.value= vol;

  //start the oscillator
  osc.start();

  //set the timer

  setTimeout(()=> {
    //stop the oscillator
    osc.frequency.value= 0;
    osc.stop();
  }, time);
}

var btn= document.querySelector("button");
btn.addEventListener("click". function() {
  createSound(500, 50, "sawtooth", 1);
});

 

When the button is clicked, ‘createSound‘ gets called which creates a new oscillator, sets ‘type‘ to “sawtooth“, ‘frequency’ to 500 and ‘gain.value’ to 1 as per the passed values and starts the oscillator. Oscillator is stopped after 50 milliseconds.

 

Here is a demo utilising the same code (just care about the code related to function above)-

 

Other user actions on which it will be appropriate to implement above kind of sound effects include ‘range‘, ‘checkbox‘, ‘radio‘ inputs, etc.
What we just did is just a drop in the ocean of possibilities of Web Audio API. For our purpose, we’re not limited to just using a single oscillator. There are endless possibilities like we could combine multiple oscillators and play them in a chain with different frequencies to create more complex sounds which I think you are rarely going to use for the purpose being illustrated here, but might be useful sometimes.

 

Don’t Abuse It

It would be weird to use the kind of effects we have created in this post in as simple UI as a website’s navbar. As far as I think, it would feel odd to a user to listen to beeps while interacting with the very basic UI. It would add extra elegance if you use it in the game UIs and other high-end UIs of complex web apps. Such sound effects should be implemented with extra care on mobile devices in which these are natively supported. Just make sure you don’t replace the native effects when possible.

 

Conclusion

Sound effects on user actions are one of the most needed things in games and ‘out of the box’ web apps. You can achieve such effects by using an audio file with <audio> tag and playing/pausing the player using JavaScript while user interacts but it’s appalling for performance as UI has to wait for the file to download before it can make use of it.

 

Web Audio API’s oscillator not only solves this problem but also gives us more control over the sound than we would have an audio file. Anytime you need some changes in your sound, you can do them right in the browser. Although sound effects on user-action is a nice addition to complex UIs, they shouldn’t be abused.

 

Do you prefer sounds on a web page in general? Share your thoughts and comments.

Share on Facebook Tweet on Twitter Post on Google+ Buffer