WebAudio: oscillator in JS

October 27th, 2012. Tagged: JavaScript, Music, WebAudio

How about generating some noise in JavaScript?

Demo is here: oscillator.

How does this work?

Using HTML Web Audio you can synthesize audio with a given frequency. E.g. 440Hz is A ("la" in solfège)

This means you don't need an <audio> element or any mp3, ogg, wav, etc, no external files.

Let's see how.

Capable browser?

You need a browser that supports AudioContext. No such (major) browser at the time of writing, afaik. But there's webkitAudioContext supported in stable iOS Safari, Safari, Chrome. Also there could be browsers that support AudioContext but not the oscillator part. So starting off:

  // globals
  var audio_context, oscillator;
 
  // hello audio world
  (function init(g){
    try {
      audio_context = new (g.AudioContext || g.webkitAudioContext);
      oscillator = audio_context.createOscillator();
    } catch (e) {
      alert('No web audio oscillator support in this browser');
    }
  }(window));

Start/stop playing

Alright, next is a play(frequency /*number*/) function which makes noise with a given frequency.

  function play(freq) {
    oscillator = audio_context.createOscillator();
    oscillator.frequency.value = freq;
    oscillator.connect(audio_context.destination);
    oscillator.noteOn(0);
    fire('play', oscillator.frequency.value);
  }

(Don't mind fire(), it's just a poor man's event utility for logging what's going on)

The audio context provides a createOscillator(). You assign the frequency you need and connect this oscillator node to the audio destination (speaker).

There is a nice analogy going on in the Web Audio: you start with some input noise, say coming from microphone or an audio file, or, in this case, you generate the noise yourself. Then you connect that initial input to the output (destination) which is the system speaker/phones. In between though you can pass the noise through a bunch of nodes that can modify the noise.

In this simple example I only have an oscillator node which is connected directly to the audio destination.

noteOn(0) starts playing the noise we just generated.

Implementing stop() to silence the noise is just a question of calling noteOff(0) on the same oscillator node.

  function stop() {
    oscillator.noteOff(0);
    fire('stop');
  }

That's it, go play with the demo.

The demo plays 440Hz (A on 4th octave of the piano) and 880Hz (A on 5th octave) and also lets you punch in a number and see what happens. Probably nice to play with your dog and with sounds at frequencies you cannot hear.

A chord

Finally, an attempt to play a chord: three frequencies at the same time. C major is C, E and G tones. We have an array of the three frequencies, so loop over the array and create and noteOn three oscillator nodes.

  var cmajor = {};
  cmajor.yo = function () {
    var oscs = [], o, i, freqs = [261.63, 329.63, 392];
    freqs.forEach(function(freq) {
      o = audio_context.createOscillator();
      o.frequency.value = freq;
      o.connect(audio_context.destination);
      o.noteOn(0);
      oscs.push(o);
    });
    this.oscs = oscs;
    fire('play', '\n - ' + freqs.join('Hz\n - '));
  };
  
  cmajor.no = function () {
    this.oscs.forEach(function(o) {
      o.noteOff(0);
    });
    fire('stop');
  };

Thanks

Some links for learning more

Once again the demo is here: oscillator.

Intro: html5rocks.com

Educational demos: webaudiodemos.appspot.com/

Tell your friends about this post: Facebook, Twitter, Google+

8 Responses

  1. Thanks a lot.The articles of your site is really helpful and usable for visitors., one of the excellent blog in which i

  2. Hi just thought i would tell you something.. This is twice now i’ve landed on your blog in the last 2 days looking for completely unrelated things. Spooky or what?

  3. Hi my family member! I want to say that this post is amazing, great written and include approximately all important infos. I’d like to look more posts like this .

  4. Great blog site! Do you have any tips and hints for striving authors? I’m wanting to begin my own blog quickly however I’m a little lost on everything. Would you advise starting with a free platform like WordPress or opt for a paid choice? There are many choices out there that I’m totally overwhelmed. Any suggestions? Many thanks!

  5. Great blog site right here! Likewise your site tons up quickly! What web host are you making use of? Can I get your affiliate link to your host? I wish my website loaded up as fast as yours lol

  6. I’m very interested in creating some different frequencies that cannot be heard. I was leaning towards using oscillators to do this but I’m understanding now this can be done with java code. Can you send me some more information on this I have searched around a bit and I’m extremely interested.
    Thank you
    John

  7. Great example! The first one I found that was really simple but works out of the box on iOS.

  8. Wow great example, and it’s compatible with Android via webobject i guess, right ? Thanks for opening a new area to your users.

Leave a Reply