When I start my oscillator, stop it, and then start it again; I get the following error:
Uncaught InvalidStateError: Failed to execute 'start' on 'OscillatorNode': cannot call start more than once.
Obviously I could use gain
to "stop" the audio but that strikes me as poor practice. What's a more efficient way of stopping the oscillator while being able to start it again?
var ctx = new AudioContext();
var osc = ctx.createOscillator();
osc.frequency.value = 440;
osc.connect(ctx.destination);
function startOsc(bool = true) {
if (bool) {
osc.start(ctx.currentTime);
} else {
osc.stop(ctx.currentTime);
}
}
document.getElementById("start").addEventListener(`click`, () => startOsc(true));
document.getElementById("stop").addEventListener(`click`, () => startOsc(false));
Warning: this will play at full volume!
<button id="start">start</button>
<button id="stop">stop</button>
The best I could come up with was to rebuild new oscillators every time I need it to play and removing them on stop:
var ctx = new AudioContext();
var osc = ctx.createOscillator();
osc.frequency.value = 440;
osc.connect(ctx.destination);
function startOsc(bool = true) {
if (bool) {
osc = ctx.createOscillator();
osc.frequency.value = 440;
osc.start(ctx.currentTime);
osc.connect(ctx.destination);
} else {
osc.stop(ctx.currentTime);
osc.disconnect(ctx.destination);
osc = null;
}
}
document.getElementById("start").addEventListener(`click`, () => startOsc(true));
document.getElementById("stop").addEventListener(`click`, () => startOsc(false));
Warning: this will play at full volume!
<button id="start">start</button>
<button id="stop">stop</button>
A better way would be to start the oscillatorNode once and connect/disconnect the oscillatorNode from the graph when needed, ie :
var ctx = new AudioContext();
var osc = ctx.createOscillator();
osc.frequency.value = 8000;
osc.start();
$(document).ready(function() {
$("#start").click(function() {
osc.connect(ctx.destination);
});
$("#stop").click(function() {
osc.disconnect(ctx.destination);
});
});
This how muting in done in muting the thermin (mozilla web audio api documentation)