{{{{ JavaScript - Sound }}}}

Play notes
Start of website

Alphabetical index

Summary of colours in code: green is HTML useful for JavaScript, red is JavaScript, blue is a name and everything else is grey.



Play notes

I don't quite understand the following, despite the attempts of a son and husband to explain! Never mind - it works....

This plays three notes.



<HTML>
<HEAD>
<SCRIPT>
var ctx
</SCRIPT>
</HEAD>

<BODY>

<SCRIPT>

// set everything up

if (ctx !== undefined) {ctx.close()}

ctx = new AudioContext();
st = ctx.currentTime
osc = ctx.createOscillator();
vol = ctx.createGain();
osc.frequency.setValueAtTime(440, st);
osc.start();
vol.gain.setValueAtTime(0, st);
osc.connect(vol);
vol.connect(ctx.destination);

// note C

osc.detune.setValueAtTime(-900, st);
vol.gain.setValueAtTime(1, st);
vol.gain.setValueAtTime(0, st+.5);

// note E

osc.detune.setValueAtTime(-700, st+1);
vol.gain.setValueAtTime(1, st+1);
vol.gain.setValueAtTime(0, st+1.5);

// note G

osc.detune.setValueAtTime(-400, st+2);
vol.gain.setValueAtTime(1, st+2);
vol.gain.setValueAtTime(0, st+2.5);
</SCRIPT>
</BODY>
</HTML>
Explanation

'ctx' needs to be a global variable, or you'll lose all the sound stuff before it plays anything.

Keep the setup exactly the same. You don't have to understand it!

'440 is the note that everything is relative to. It is A above middle C.

You will probably want to change the notes. The first statement gives the note relative to A. 100 is a semi-tone (counting black and white notes on a piano). So middle C is 9 semi-tones below A, hence -900. The other parameter is when the note starts. The next two statements deal with volume. The first is volume 1, and that starts the same time as the note. The next is volume 0 (or no sound) and that starts (in this case) half a second later, and stops the note. The times are all relative to 'st', the current time, which got set up at the start.

The other two notes have to start later (or they will obliterate the first note!) So E starts a second after the start, and again lasts half a second (or 1.5 seconds after the start). E is 7 semi-tones below A, so -700. G is 4 semi-tones, so -400.

Please see that these notes play at the appropriate point, but the rest of the code doesn't sit there waiting for them to finish!

If you replace

vol.gain.setValueAtTime(1, st);
vol.gain.setValueAtTime(0, st+.5);

with

vol.gain.linearRampToValueAtTime(2, st+.1);
vol.gain.exponentialRampToValueAtTime(0.2, st+.5);
vol.gain.setValueAtTime(0, st+.5);

you will get a shorter note, with a fast attack, and slow decay. You may think it sounds better.



Return to JavaScript index



Valid HTML 4.01!

© Jo Edkins 2020