Web Audio API Oscillators

Web Audio API Oscillators

UPDATED ON: December 11, 2014

Web Audio API Oscillators is a tutorial that will give you an understanding of how to generate sounds with the Web Audio API in your browser. Web Audio API Oscillators builds on what we’ve covered in Web Audio API Basics, the first tutorial in the series. Web Audio API Oscillators will attempt to cover what oscillators are, how to create them, changing waveforms, setting frequency, and layering multiple oscillators together to create rich sounds. We’ll finish by applying what we’ve learned to create a working example. After covering the basics in this tutorial, we’ll get into some techniques for toggling oscillators on and off and even how to use the API to make a synthesizer in the browser.

Web Audio API Oscillators

Web Audio API Oscillators

The Web Audio API allows us to generate oscillating wave forms quite easily. You might be asking yourself, “Aren’t those the building blocks of a synthesizer?” Well, yes. The Web Audio API enables us to create our own synths! Before we get ahead of ourselves, let’s go over the fundamentals.

What is an Oscillator?

So, what do we need to know about oscillators? An oscillator is a circuit that produces a repetitive, oscillating signal. Along with audio filters and audio controllers, audio oscillators are one of the basic elements required for modern analog subtractive synthesizers.

Let’s Create an Oscillator

Now that we’ve covered the basics, we’ll create a simple oscillator. The OscillatorNode is the interface that represents an audio source generating a periodic waveform. Unless otherwise specified, an oscillator defaults to a sine wave at 200 hertz. Notice we must connect the oscillator to the destination in order to hear it. Also, we specify a start value of zero to play the sound instantly.

oscillator = context.createOscillator(); // Create sound source
	
oscillator.connect(context.destination); // Connect sound to output
oscillator.start(0); // Play instantly

UPDATE: As of July 2014, oscillator.start() should be used instead of oscillator.noteOn().

Specify Type and Frequency

There are four commonly used waveforms that can easily be generated. Each type is specified by a number from 0-3. If we want a square wave, we change the oscillator type to 1. If we want a triangle wave, we set the oscillator type to 3. Custom waveforms can also be specified through the use of a WaveTable PeriodicWave object, but we’ll try to keep it simple for this tutorial.

UPDATE: As of July 2014, oscillator type must be specified as Web IDL value.

Commonly Used Waveforms

  • Sine wave is type = “sine”
  • Square wave is type = “square”
  • Sawtooth wave is type = “saw”
  • Triangle wave is type = “triangle”
  • Custom wave is type = “custom”

Also, we can adjust the pitch of the wave simply by setting a frequency value. The number used for the frequency value represents the actual frequency in hertz. A value of 440 would be an A because the note A4 is equal to 440 Hz. For now we won’t worry about the actual note we’re playing. We’ll just use a value of 100 to keep it simple.

oscillator.type = "square"; // Square wave
oscillator.frequency.value = 100; // frequency in hertz

Double the Fun

We can layer multiple oscillators to create a thicker sound. For a dual oscillator, we create two sound sources. Oscillator1 is set to the default type and frequency, and is played instantly. Oscillator2 is set to be a square wave at half the frequency of oscillator1. This will produce a tone that is one octave below the tone of oscillator1. Oscillator2 is also routed through a gainNode to reduce it’s volume to 30 percent. And finally, oscillator2 is played after two seconds. This allows the listener to differentiate the two sounds being layered.

oscillator1 = context.createOscillator(); // Create sound source 1
oscillator2 = context.createOscillator(); // Create sound source 2
gainNode2 = context.createGain(); // Create gain node 2

oscillator1.type = "sine"; // Sine wave
oscillator1.frequency.value = 200; // Default frequency in hertz 
oscillator1.connect(context.destination); // Connect sound source 1 to output
oscillator1.start(0); // Play sound source 1 instantly 
		
oscillator2.type = "square"; // Square wave
oscillator2.frequency.value = 100; // Frequency in hertz 
oscillator2.connect(gainNode2); // Connect sound source 2 to gain node 2
gainNode2.connect(context.destination); // Connect gain node 2 to output
gainNode2.gain.value = 0.3; // Set gain node 2 to 30 percent
oscillator2.start(2); // Play sound source 2 after two seconds

Now Create a Triple Oscillator on your Own

We can use the same technique to create more layers of sound. This time, see if you can figure it out before looking at the code below. Let’s create a triple oscillator. Leave oscillator1 and oscillator2 the same. Create a new sound source called oscillator3. Oscillator3 should be a triangle wave set to half the frequency of oscillator2, eighty percent volume, and is played after four seconds.

Go ahead and try it out on your own.

Did it work? Good job! If not, don’t worry. You can compare yours to the code below. The final code for your triple oscillator stack should look something like this.

var context = new AudioContext(); // Create audio container
oscillator1 = context.createOscillator(); // Create sound source 1
oscillator2 = context.createOscillator(); // Create sound source 2
oscillator3 = context.createOscillator(); // Create sound source 3
gainNode2 = context.createGain(); // Create gain node 2
gainNode3 = context.createGain(); // Create gain node 3

oscillator1.type = "sine"; // Sine wave
oscillator1.frequency.value = 200; // Default frequency in hertz
oscillator1.connect(context.destination); // Connect sound source 1 to output
oscillator1.start(0); // Play sound source 1 instantly
	
oscillator2.type = "square"; // Square wave
oscillator2.frequency.value = 100; // Frequency in hertz
oscillator2.connect(gainNode2); // Connect sound source 2 to gain node 2
gainNode2.connect(context.destination); // Connect gain node 2 to output
gainNode2.gain.value = 0.3; // Set gain node 2 to 30 percent
oscillator2.start(2); // Play sound source 2 after two seconds

oscillator3.type = "triangle"; // Triangle wave
oscillator3.frequency.value = 50; // Frequency in hertz
oscillator3.connect(gainNode3); // Connect sound source 3 to gain node 3
gainNode3.connect(context.destination); // Connect gain node 3 to output
gainNode3.gain.value = 0.8; // Set gain node 3 to 80 percent
oscillator3.start(4); // Play sound source 3 after four seconds

Well, that’s about it for Web Audio API Oscillators. Next, I’ll share some techniques for toggling oscillators on and off. I’m ready to explore the outer limits of imagination. Are you? The possibilities are endless. How are you going to use the Web Audio API to make the web awesome?

Other tutorials in this series

More examples of the Web Audio API in action


Comments

3 responses to “Web Audio API Oscillators”

  1. Creating Sound with the Web Audio API and Oscillators | Flippin' Awesome

    […] Web Audio API Oscillators by Obadiah Metivier […]

  2. Ken Driskell Avatar
    Ken Driskell

    On webpage:
    https://middleearmedia.com/web-audio-api-oscillators/

    In the triple oscillator code listing there is a typo.
    Original:
    oscillator3.connect(gainNode2); // Connect sound source 3 to gain node 3
    Should be:
    oscillator3.connect(gainNode3); // Connect sound source 3 to gain node 3

    1. Thanks for pointing that out Ken!

Leave a Reply

Your email address will not be published. Required fields are marked *