0
votes

Using Opera 44.0, I was fiddling around with the Audio API and tried a simple example:

var ac = new AudioContext();
var osc = ac.createOscillator();

osc.connect(ac.destination);
osc.start();
osc.stop(2);

It works as expected, the sound is played for 2 seconds and then it stops.

Then I tried to step up a little, playing a sound when a button is clicked:

function play(){
  var osc = ac.createOscillator();
  osc.connect(ac.destination);
  osc.start();
  osc.stop(2);
}

var ac = new AudioContext();

var playBtn = document.querySelector("#play");
playBtn.addEventListener("click", play);

It doesn't work. The function is called when I click the button (I checked using console.log() inside the function), but no sound is played. I tried refreshing the page, restarting the browser.. nothing.

After some research I found out that the oscillator is thrown away when stop() is called, so I have to create a new oscillator every time. Pretty much all the examples I found revolve around that concept, which is why I am creating it inside the function. But with no errors whatsoever, I can't figure out why it's not working.

So, where is the problem here?

1

1 Answers

0
votes

Digging through the documentation, I managed to solve the problem.

Originally, I assumed that the argument passed to osc.stop(2) was the playing time in seconds, something like "play for 2 seconds, then stop". That's not correct though: the argument is "...the audio context time when the oscillator should stop".

By logging ac.currentTime inside the play() function, the value returned when I clicked on the button was ~5. So, what happened is that by passing 2 to osc.stop() i'm telling the osc to stop when the context time is 2, which is already passed!

The solution is simple:

function play(){
  var osc = ac.createOscillator();
  osc.connect(ac.destination);
  osc.start();
  //take into account the current time of the context
  osc.stop(ac.currentTime + 2);
}

Words of wisdom now echo into my brain... R....T.....F...M...