TSW Web Audio Primer – Conclusion

I hope that this series has helped to show off some of the capabilities of the Theresa’s Sound World framework by Stuart Memo. There are many more features to explore, and I will come back to TSW from time to time. Here are links to the full series:

Part 1 – Play a pitch

Part 2 – Change the pitch

Part 3 – Change the oscillator type

Part 4 – Play notes using a keyboard

Part 5 – Playing a chord

Part 6 – Playing a scale

Part 7 – Fun with filters

Now, to paraphrase Stuart Memo, “Here is how to use TSW – now go make some apps!”

 

TSW Web Audio Primer – Part 7

You have seen examples of how to play notes, chords, and scales using TSW. Now, let’s swing back to how you can modify the sounds that you can create with TSW. We will start with a single pitch sine wave and see how different filters sound.

TSW contains a function that creates a filter node, which removes certain frequencies from any audio passed through it. Here is the sample code from the TSW website:

var filter = tsw.filter({

type: 'lowpass',

frequency: 200,

Q: 1

});

There are three inputs: the filter type, the cutoff frequency, and a quality factor (Q).

The Biquad Filter Node page on the Mozilla Developer Network site gives an excellent description of the filter types that are supported in TSW. Let’s explore the first one in the list (lowpass filter). From the lowpass filter description, input frequencies that are lower than the cutoff frequency pass through. When the input frequency is larger than the cutoff frequency, the input is attentuated (gets softer). Let’s explore how this works. Our oscillator frequency is set to 600 Hz. Let us start with the filter cutoff frequency set to 800. This should result in no change to the sound.

Add the following functions to pitch.js:

function turn_on_filter() {

var filter = tsw.filter({

type: 'lowpass',

frequency: 800,

Q: 1

});

osc = tsw.oscillator (frequency, oscType);

tsw.connect(osc, filter, volume, tsw.speakers);

osc.start();

};

function turn_off_filter() {

osc.stop();

};

Next, we will add two new buttons to turn the filtered sound on and off.

FROM:

<p>Test function <button onclick="playScale();">Scale Test</button></p>

TO:

<p>Test function <button onclick="playScale();">Scale Test</button></p>
<p>Press Play to hear how the filtered pitch sounds. <button onclick="turn_on_filter();">Play</button></p>
<p>Press Stop to turn the filtered pitch off. <button onclick="turn_off_filter();">Stop</button></p>

Load index.html in your browser and you should see the following:

ex07_01

Click the Play and Stop button for the filtered pitch, then click the Play and Stop buttons at the top of the page. The volume of the pitches should sound the same.

Next, change the cutoff frequency for the filter to 500, then 200. You should hear a slight decrease in volume at 500, and a noticeable decrease at 200. The other parameter of the filter that can be varied is the Q factor. The greater the value of Q, the greater the peak around the cutoff frequency. To see this effect, set the cutoff frequency to 590, then start increasing the value of Q. At values of 50 and above, you should hear some interesting distortion of the pitch.

The second type of filter (highpass) works in the opposite manner as the lowpass filter. Frequencies above the cutoff frequency are not affected, but frequencies below the cutoff frequency are attenuated (gets softer). To demonstrate this effect, you can change the type definition in the filter to ‘highpass’. Next, you can start increasing the cutoff frequency above the oscillator frequency (600) to hear the effects of the filter. You will have to increase the cutoff frequency above 1500 to start hearing some decrease in volume.

The third type of filter (bandpass) works over a range of frequencies from the cutoff frequency. Inputs within the range pass through unchanged, but inputs with frequencies outside of the range are attenuated (play softer). The size of the range of frequencies is controlled by the value of Q (large Q = large range around the cutoff frequency). To demonstrate, set the filter type to ‘bandpass’ and the value of Q to 100. Next, click the Play button, then change the pitch using the slider control. Moving the control to the left or right will result in a decrease in volume along with the change in pitch.

The next three filters (lowshelf, highshelf, and peaking) are similar to the lowpass, highpass, and bandpass filters in that inputs below the cutoff frequency, above the cutoff, or within a range are affected. The effect can be either an increase or a decrease in volume, depending on the gain setting of the filter. The tsw.filter function does not have a way to set this gain directly, so to be able to manipulate the filter gain, we will have to use the tsw.context function in TSW. This allows the user to be able to create nodes using native Web Audio API functions. Here is a modified example of the turn_on function using this feature:

function turn_on() {

biquadFilter = tsw.context().createBiquadFilter();

// Manipulate the Biquad filter

biquadFilter.type = "peaking";

biquadFilter.frequency.value = 435;

biquadFilter.gain.value = 25;

biquadFilter.Q.value = 100;

osc = tsw.oscillator (440, 'sine');

tsw.connect(osc, biquadFilter, volume, tsw.speakers);

osc.start();

};

One note on this example code: I was not able to get an attenuation (decrease in volume) when the filter gain value was negative.

The final two filter options are the notch and allpass filters. For the notch filter, if the filter frequency and Q value is such so that the input frequency is outside the range of the filter, there is no effect on the output of the filter. As the filter frequency approaches the frequency of the input, the sound is attenuated (gets softer), with the initial sound of the attack followed by a softer tone. When the frequencies are the same, the only sound is the initial attack (sounds like a beep!).

For the allpass filter, as the filter frequency approaches the frequency of the input, the sound begins to change (phase change). When the two frequencies are the same, there is a slight delay in the start of the sound for Q = 1. As the value of Q increases, interesting things start to happen with the sound. At 100, the sound attack is normal volume, then decreases, then increases (like a “wow-wow” effect).

To make it easier to experiment with filters, I have created a new user interface just focusing on filter experiments:

ex07_02

You can go to the demo of this application and try it for yourself. The example source code is also available on Github.

Resources:

Mozilla Developer Network: Page on biquad filters

O’Reilly.com: Boris Smus book on Web Audio API, link to chapter on filters

 

TSW Web Audio Primer – Part 6

Now that we can play a chord, how about playing a scale? The TSW library can also create a list of notes for a scale. Let’s start with modifying our initial playChord function to see how the scale function works:

function playScale() {

var testScale;

testScale = tsw.scale('A', 'major');

console.log(testScale);

};

This function will write the contents of the scale list to the Javascript console. To call this function, we will add a line of HTML to create a new button that will call this function. The button logic in index.html should be changed as follows:

FROM:

<p>Press Play to hear how the pitch sounds. <button onclick="turn_on();">Play</button></p>
<p>Press Stop to turn it off. <button onclick="turn_off();">Stop</button></p>
<p>Start Chord <button onclick="playChord();">Start Chord</button></p>
<p>Stop Chord <button onclick="stopChord();">Stop Chord</button></p>

TO:

<p>Press Play to hear how the pitch sounds. <button onclick="turn_on();">Play</button></p>
<p>Press Stop to turn it off. <button onclick="turn_off();">Stop</button></p>
<p>Start Chord <button onclick="playChord();">Start Chord</button></p>
<p>Stop Chord <button onclick="stopChord();">Stop Chord</button></p>
<p>Test function <button onclick="playScale();">Scale Test</button></p>

<span style="font-size: 14px; line-height: 1.5em;">

When you click the Scale Test button, you should see the following in the Javascript console:

[“A”, “B”, “C#”, “D”, “E”, “F#”, “G#”, “A”]

We can reuse the functions from part 5 for playing the chord, but we need to give the notes a duration. How do we do that? The Web Audio API sets a timer when a new AudioContext is created. When TSW is being used, that AudioContext is automatically created when the TSW code is loaded in your web page. The way that you can access this timer is through the tsw.now() function. Update the playScale function as follows:

function playScale() {
var testScale;
testScale = tsw.scale('A', 'major');
console.log(testScale);
console.log(tsw.now());
};

Refresh index.html, and you should see something like this in your Javascript console:

[“A”, “B”, “C#”, “D”, “E”, “F#”, “G#”, “A”]

1.1493877551020408

When we play a note in the turn_on function, we use the following command:

osc.start();

The note starts playing immediately. However, we can delay that start for a period of time by including a number in the parentheses. This number represents the number of seconds after the time that the AudioContext was created.

When we stop a note in the turn_off function, we use the following command:

osc.stop();

Again, the note stops immediately. As with the start function, we can delay the stopping of the note by including a number in the parentheses. Again, this number represents the number of seconds after the time that the AudioContext was created.

Let’s say that you would like a one second delay in starting the note and stopping the note. We should reference the time being passed in to the time that the command is executed. We can do this using the tsw.now function as follows:

osc.start(tsw.now() + 1.0);
osc.stop(tsw.now() + 1.0);

If you modify the turn_on and turn_off functions with the above changes, you should here that there is a one second delay when you click the Play and Stop buttons at the top of the web page.

Now, let us create a function where we play the notes in a scale, with each note played for one second, starting one second after we click the button. We could make a table of the times as follows:

Note Start Stop
1     0     1
2     1     2
3     2     3
4     3     4
5     4     5
6     5     6
7     6     7
8     7     8

The TSW scale function does not accept a note with an octave (like “E3”). The function only wants a note name (A, B, C, D, E, F, G). To avoid modifying the TSW scale function, we will set the octave in a separate variable. We can then append the octave to the note name generated by the scale function. However, the octave should change when the scale sequences reaches “C” (change octave from three to four, for example).

Here are two functions that will perform the scale:

function playScale() {
var testScale;
var startTime = tsw.now();
var octave, octave_plus;

// Generate base scale
testScale = tsw.scale('E', 'major');

// Set base octave and next octave, then convert to strings
octave = 3;
octave_plus = octave + 1;
octave_string = octave.toString();
octave_text_plus = octave_plus.toString();

// Check for C in scale sequence and append next octave when that happens
for (i = 0; i &lt; testScale.length; i++) {
if ((testScale[i] === "C")||(testScale[i] === "C#")){
octave_string = octave_text_plus;
}
testScale[i] = testScale[i] + octave_string;
}

// Play each note in the scale for one second
for (i = 0; i &lt; testScale.length; i++) {
playScaleNote(tsw.frequency(testScale[i]), startTime + i, startTime + i + 1);
}

};

function playScaleNote(frequency, startTime, stopTime) {
var osc;
var oscType = 'sine';
osc = tsw.oscillator (frequency, oscType);
tsw.connect(osc, volume, tsw.speakers);
osc.start(startTime);
osc.stop(stopTime);
};

When you click the Scale Test button, you should hear the E major scale starting with E3.

You can also go to the demo of this application and see if you can play the scale.

Download the source code for all of the examples in this series from Github.

TSW Web Audio Primer – Part 5

Well, playing one note at a time is fun for a little while, but it would be nice to play more than one note at a time. In using the Web Audio API, the easiest way to do this is to use a separate oscillator for each note. Let us define some new functions:

playChord

Define notes in chord

For each note in the chord, call PlayNote

playNote

Create an oscillator object, start the note, and push it into an array of oscillators

stopChord

For each entry in the array of oscillators, use the osc.stop function in TSW

First, let’s work on the playChord function. We can use the use the tsw.chord function to get a list of the notes in the chord. Here is a first cut:

function playChord() {

var testChord;

testChord = tsw.chord('A4', 'major');

console.log(testChord);

};

This function will write the contents of the list to the Javascript console. To call this function, we will add a line of HTML to create a new button that will call this function. The button logic in index.html should be changed as follows:

FROM:

<p>Press Play to hear how the pitch sounds. <button onclick="turn_on();">Play</button></p>
<p>Press Stop to turn it off. <button onclick="turn_off();">Stop</button></p>

TO:

<p>Press Play to hear how the pitch sounds. <button onclick="turn_on();">Play</button></p>
<p>Press Stop to turn it off. <button onclick="turn_off();">Stop</button></p>
<p>Test function <button onclick="playChord();">Start Chord</button></p>

In Google Chrome, you can see the Javascript console by clicking on the menu button in the upper right corner of the window, then selecting the Tools menu option, then the Javascript Console sub-menu option.

By clicking on the Test button, you should see the following in the console:

[“A”, “C#”, “E”, “A”]

Now, add more logic to test working with the elements of the array:

function playChord() {
var testChord;
testChord = tsw.chord('A4', 'major');
console.log(testChord);
for (i = 0; i &lt; testChord.length; i++) {
console.log(testChord[i]);
}
};

Our result is as follows:

[“A”, “C#”, “E”, “A”]

A

C#

E

A

Now, we can use the tsw.frequency function to get the frequency for the notes in the array.

function playChord() {
var testChord;
testChord = tsw.chord('A4', 'major');
console.log(testChord);
for (i = 0; i &lt; testChord.length; i++) {
console.log(testChord[i], tsw.frequency(testChord[i]));
}
};

<span style="font-size: 14px; line-height: 1.5em;">

We then see:

[“A”, “C#”, “E”, “A”]

A 440

C# 277.1826309768721

E 329.6275569128699

A 440

Now, create the playNote function and pass in the frequency of each note. This will look like the turn_on function created earlier, except that the oscillator object will be created in the function rather than be a global variable outside the function.

function playNote(frequency) {
var osc;
var oscType = 'sine';
osc = tsw.oscillator (frequency, oscType);
tsw.connect(osc, volume, tsw.speakers);
osc.start();
}:

In addition, we will now add some logic in playChord to call playNote for the notes in the chord, but will skip the note in the first element in the array, since it is the same as the first note. Update the function as follows:

function playChord() {
var testChord;
testChord = tsw.chord('A4', 'major');
console.log(testChord);
for (i = 0; i &lt; testChord.length; i++) {
console.log(testChord[i], tsw.frequency(testChord[i]));
}
for (i = 1; i &lt; testChord.length; i++) {
playNote(tsw.frequency(testChord[i]));
}
};

After these updates, you should be able to hear the notes in the chord play when you click the Test button. Now, the last part is to be able to turn the notes off.

Since we are creating a new oscillator object for each note, we need to have a way to turn those objects off. We will add logic to push those objects into an array, and then loop through the array to turn them off.

Change the variable declarations as follows:

FROM:

var testChord;

TO:

var testChord;
var chordOscillators = [];

Update the function playNote to be as follows:

function playNote(frequency) {
var osc;
var oscType = 'sine';
osc = tsw.oscillator (frequency, oscType);
tsw.connect(osc, volume, tsw.speakers);
osc.start();
chordOscillators.push(osc);
};

Now add the following function:

function stopChord() {
for (i = 0; i &lt; chordOscillators.length; i++) {
chordOscillators[i].stop();
}
};

In index.html, we will add a new button to call the stopChord function:

FROM:

<span style="color: #222222;"> <span style="font-family: 'Times New Roman', serif;"><span> <p>Test function <button onclick="playChord();">Start chord</button></p>
</span></span></span>

TO:

<span style="color: #222222;"> <span style="font-family: 'Times New Roman', serif;"><span> <p>Start Chord <button onclick="playChord();">Start Chord</button></p>
<p>Stop Chord <button onclick="stopChord();">Stop Chord</button></p>
</span></span></span>

When you press the Start Chord button, you should hear the chord play. When you press the Stop Chord button, the chord will stop!

You can also go to the demo of this application and see if you can play the chord.

Download the source code for all of the examples in this series from Github.

TSW Web Audio Primer – Part 4

Now that you have had some fun with changing a note via a slider, let’s move on to playing a note using a keyboard. Stuart Memo has created a virtual keyboard app called Qwerty Hancock for his site demo, source code at Github. We will modify our app to use this keyboard app to play a note in addition to the Play button.

First, we will make some changes to index.html. We will need to add a <div> element for the keyboard, add a <script> tag for the Qwerty Hancock logic, and move the <script> tag for pitch.js to be below the <script> tag for Qwerty Hancock. In the <head> element, make the following change:

FROM:

<script src="tsw.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="pitch.js"></script>
<!-- Custom styles for this template -->

TO:

<script src="tsw.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Custom styles for this template -->

After the <form> closing tag, add the following:

FROM:

</form>
</div>

</div><!-- /.container -->

TO:

</form>
</div>
<div id="keyboard"></div>
<script src="qwerty-hancock.js"></script>
<script src="pitch.js"></script>

</div><!-- /.container -->

In pitch.js, we will add the following new logic at the end of the file:

var context = new AudioContext();

var settings = {

id: 'keyboard',

width: 600,

height: 150,

startNote: 'A2',

whiteNotesColour: '#fff',

blackNotesColour: '#000',

borderColour: '#000',

activeColour: 'yellow',

octaves: 2

};

var keyboard = new QwertyHancock(settings);

keyboard.keyDown = function (note, frequency) {

turn_on();

changePitch(frequency)

};

keyboard.keyUp = function (note, frequency) {

turn_off();

};

This is logic taken from the Qwerty Hancock demo page. The functions turn_on and turn_off from the earlier examples are being used to start and stop the note and the changePitch function is used to get the frequency for the note corresponding to the key pressed on the keyboard.

Load index.html in your browser and you should see the following:

ex04_01

When you click on any of the keys in the virtual keyboard, you should hear a note. You can still use the radio buttons above to change the oscillator type. You can also use letter keys on the physical keyboard to play notes (“A” through “,” for white keys, “W” through “]” for black keys). If you press more than one key at a time, you will hear a note for each key, but then the notes will not stop when the keys are released. You can refresh the web app to stop the notes.

You can also go to the demo of this application and see if you can change the oscillator type.

Download the source code for all of the examples in this series from Github.

 

TSW Web Audio Primer – Part 3

In part 2 of this series, you learned how to change the pitch of a note. In this part, you will learn how to change the oscillator type. Add the following HTML logic after the slider logic from Part 2 to set up a form with radio buttons:

FROM:

<center><p><input class="slider-width200" id="slider" type="range" min="0" max="1000" value="600" onchange="changePitch(this.value)"></p></center>

TO:

<center><p><input class="slider-width200" id="slider" type="range" min="0" max="1000" value="600" onchange="changePitch(this.value)"></p></center>
<form>
<input type="radio" name="oscType" value="sine" onclick="getOscType(this.value);" checked>Sine
<input type="radio" name="oscType" value="square" onclick="getOscType(this.value);">Square
<input type="radio" name="oscType" value="triangle" onclick="getOscType(this.value);">Triangle
<input type="radio" name="oscType" value="sawtooth" onclick="getOscType(this.value);">Sawtooth
</form>

Next, we will make several changes to pitch.js. First, add a variable for the type of oscillator:

FROM:

var osc;

var volume;

TO:

var osc;

var oscType = 'sine';

var volume;

Next, we will change the turn_on function to use the new oscType variable.

FROM:

function turn_on() {

osc = tsw.oscillator (600, 'sawtooth');

tsw.connect(osc, volume, tsw.speakers);

osc.start();

};

TO:

function turn_on() {

osc = tsw.oscillator (600, oscType);

tsw.connect(osc, volume, tsw.speakers);

osc.start();

};

Finally, we will add a new function as follows:

function getOscType(value)

{

oscType = value;

osc.type(oscType)

}

This function will be called whenever a new radio button is selected, and will change the oscillator type for the current note being played.

Load index.html in your browser and you should see the following:

ex03_01

As before, click the Play button to start playing. You can change the pitch using the slider, and when you select a different radio button, the oscillator type will change for the pitch being played.

You can also go to the demo of this application and see if you can change the oscillator type.

Download the source code for all of the examples in this series from Github.

 

TSW Web Audio Primer – Part 2

In part 1 of this series, we played a pitch using the Web Audio API. Let us set up a way to change the pitch of the note. Add this logic to index.html from Part 1 to add a slider element:

FROM:

<div class="starter-template">
<p>Press Play to hear how the pitch sounds. <button onclick="turn_on();">Play</button></p>
<p>Press Stop to turn it off. <button onclick="turn_off();">Stop</button></p>
<center><p><input id="slider" type="range" min="0" max="1000" value="600" onchange="changePitch(this.value)"></p></center>
</div>

TO:

<div class="starter-template">
<p>Press Play to hear how the pitch sounds. <button onclick="turn_on();">Play</button></p>
<p>Press Stop to turn it off. <button onclick="turn_off();">Stop</button></p>
<center><p><input id="slider" type="range" min="0" max="1000" value="600" onchange="changePitch(this.value)"></p></center>
</div>

Next, create a file (slider.css) and add the following CSS logic to adjust the size of the slider:

.slider-width200

{

width: 200px !important;

}

The “!important” text is needed to override some default Bootstrap CSS logic.

Finally, in pitch.js, add the following function to be called when the position of the slider changes:

function changePitch(newValue)

{

osc.frequency(newValue);

};

When you have completed those changes, load index.html to see the following:

ex02_01

Click on the Play button, and you should hear the original pitch. Now move the slider to the right. When you release the slider, you should hear the pitch go up. If you move the slider to the left, the pitch will go down.

You can also go to the demo of this application and see if you can change the pitch.

Download the source code for all of the examples in this series from Github.

References:

WebTUTSDepot: Tutorial for HTML5 sliders

StackOverflow: How to Overwrite Styling In Twitter Bootstrap

 

 

TSW Web Audio Primer – Part 1

Introduction

This series will demonstrate how to use your web browser to make music! Thanks to the Web Audio API, modern web browsers have the ability to become a synthesizer. With the Javascript library Theresa’s Sound World (TSW) created by Stuart Memo, we can easily use the Web Audio API. Let’s get started!

Part 1 – What makes a sound?

The Web Audio API uses basic elements to create sounds – oscillators and filters. These are much like the early analog synthesizers. On these instruments, knobs and switches would be used to set up the oscillators and filters. In addition, patch cords would be used to connect the oscillators in different ways to make new sounds. We will start with using a single oscillator.

TSW provides an oscillator method which you can use to create a new oscillator node as follows:

var osc = tsw.oscillator (frequency, wave_type)

The frequency represents the frequency of the pitch to be played. The wave type is a text string and can be one of four values (‘sine’, ‘square’, triangle’, ‘sawtooth’). If no parameters are entered, the default is a 400 Hz sine wave oscillator. Here are some examples:

var osc = tsw.oscillator (600, 'sawtooth'); // Creates a 600 Hz sawtooth wave

var osc = tsw.oscillator (800, 'sine'); // Creates a 800 Hz sine wave

var osc = tsw.oscillator (1200, 'square'); // Creates a 1200 Hz square wave

var osc = tsw.oscillator (550, 'triangle'); // Creates a 550 Hz triangle wave

A table of pitch to frequency mappings can be found at http://peabody.sapp.org/class/st2/lab/notehz/.

We can change the volume of the tone we will create by using a gain node:

var volume;

volume = tsw.gain(0.25); // Set volume to 0.25 of normal

Once the oscillator node is created, the node needs to be connected to the final output node, called “speakers”. This is done using the connect method as follows:

tsw.connect (osc, tsw.speakers);

Finally, the note is started by calling the start method of the oscillator node object:

osc.start();

To stop the note, call the stop method for the oscillator:

osc.stop();

 

Let’s put this data and two functions (turn_on and turn_off) together in a file which can then be loaded from a web page (save as pitch.js):

var osc;

var volume;

&nbsp;

volume = tsw.gain(0.5);

&nbsp;

function turn_on() {

osc = tsw.oscillator (600, 'sawtooth');

tsw.connect(osc, volume, tsw.speakers);

osc.start();

};

&nbsp;

function turn_off() {

osc.stop();

};

Note that the oscillator is defined in the function turn_on instead of when the parameter osc is declared. There is a reason for setting up the oscillator this way. In the Web Audio API, once an oscillator is turned off or disconnected, it can no longer be used. If the oscillator was defined when the parameter osc was declared, it could not be started again if the user turns the oscillator on and off. With this design, a new oscillator instance will be created each time that the turn_on function is called.

Now we will use the Bootstrap user interface toolkit to create our application. We will use the starter-template file from the Bootstrap examples site. In the <head> element, make the following changes:

FROM:

<!-- Bootstrap core CSS -->
<link href="../../dist/css/bootstrap.min.css" rel="stylesheet">

TO:

<!-- Bootstrap core CSS -->

<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">

<script src="tsw.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="pitch.js"></script>

Remove the following HTML from the <head> element:

<link rel="icon" href="../../favicon.ico">

<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="../../assets/js/ie-emulation-modes-warning.js"></script>

<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>

<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->

Now replace the HTML within the <body> element in the div with with the following HTML to set up the buttons to call the two functions in pitch.js:

FROM:

<div>

<div>
<h1>Bootstrap starter template</h1>
<p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
</div>

</div><!-- /.container -->

TO:

<div>

<div>
<p>Press Play to hear how the pitch sounds. <button onclick="turn_on();">Play</button></p>
<p>Press Stop to turn it off. <button onclick="turn_off();">Stop</button></p>
</div>

</div><!-- /.container -->

Finally, replace the links at the bottom of index.html with the following:

 

FROM:

<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="../../dist/js/bootstrap.min.js"></script>

TO:

<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

Load up the HTML file index.html in your browser (the file does not have to be uploaded to a web server). You should see the following:

ex01_01

Click on the Play button, and you should hear the pitch. To turn off the pitch, click the Stop button.

You did it! You are making sounds in your browser using the Web Audio API. If you do not hear anything, check the HTML5Test  website to see if your browser supports the Web Audio API. You can also go to the demo of this application and see if you can use that to hear the pitch.

Download the source code for all of the examples in this series from Github.