|
Play notes |
Start of website Alphabetical index |
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> |
'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.
© Jo Edkins 2020