Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Audio start and stop oscillator then start it again

I am trying to start and stop a sound. And that works. But I can't start the sound up again.

Do i really have to make another oscillator again? This just seems extremely un-intuitive. There must be a better way.

This is all i have that works:

oscillator1.noteOn(0);
oscillator1.noteOff(0);

Calling noteOn again doesnt do anything. Why? Is beyond me.

I also tried setting the volume, or in the context of the Web Audio people, "gain", equal to zero. But for some reason, a gain of zero makes sound. What value of gain would not make any sound?

man, i can't believe how difficult this is :/

like image 392
brettgag Avatar asked Mar 07 '13 00:03

brettgag


2 Answers

Actually, yes, you have to create a new oscillator node. The API is designed and optimised to work with that pattern.

The disconnect pattern in Taoist's code is basically a convoluted way of creating a new oscillator (it does every time oscOn is run). It never explicitly calls noteOff on the old oscillator that is disconnected, so it might still be running in the background (not sure how web audio handles this) though it's not audible since it's disconnected from the audio chain. So it could potentially stack oscillators in the background that are running and draining CPU.

Here's the same code, though using noteOff() properly. http://codepen.io/Theodeus/pen/afgqk

Here's the same code, though adapted using the gain node to control the oscillator and thus only using the same oscillator all the time (though this is not recommended, better to create a new oscillator for each note, I think) http://codepen.io/Theodeus/pen/aKFje

Edit April 2015
Since the code samples seems to be lost in cyberspace, here's a tutorial I wrote on oscillators that contains code examples that shows the one-shot nature of oscillators. It's not exactly the same code as the one referenced above, but it shows the same concept. http://codepen.io/Theodeus/blog/web-audio-synth-part-1-generating-sound - the gist of it is this:

//This won't work. Can't call play twice.
var context = new AudioContext(),
    oscillator = context.createOscillator();

oscillator.connect(context.destination);
oscillator.start(context.currentTime);
oscillator.stop(context.currentTime + 0.5);
oscillator.start(context.currentTime + 1);
oscillator.stop(context.currentTime + 1.5);


//this will work!
var context = new AudioContext(),
    oscillator;

function playOscillator(startTime, endTime) {
    oscillator = context.createOscillator();
    oscillator.connect(context.destination);
    oscillator.start(startTime);
    oscillator.stop(endTime);
}

playOscillator(context.currentTime, context.currentTime + 0.5);
playOscillator(context.currentTime + 1, context.currentTime + 1.5);
like image 78
Oskar Eriksson Avatar answered Sep 21 '22 14:09

Oskar Eriksson


You have to use the .disconnect() method (unless the spec has changed recently).

I wrote this up here:

http://en.wikiaudio.org/Web_Audio_API:Toggle_oscillator_on_and_off

EDIT

This response is old when I was just trying to learn how the Web Audio API worked. You don't need to use disconnect.

like image 22
William Avatar answered Sep 20 '22 14:09

William