I've created a simple program where I push the 'play' button, it plays a series of sound (using a for loop). When I press the stop button, it stops the sound. However, when I press the 'play' button again, I need the sound to start for the beginning and what's currently happening is the old sound is getting played along with the new sound. I've tried ctx.suspend()
and I've also tried ctx.close()
which does not allow the audiocontext
to restart. Any suggestions to make this play and stop buttons work? I've tried reloading the entire page when I press stop,but makes the page less user friendly and clunky (I want to add dropdown selections in the next version).
<script>
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
ctx = new AudioContext();
}
catch(e) {
alert('Web Audio API is not supported in this browser');
}
var btn = document.querySelector('button');
var btn_stop = document.querySelector('button_stop');
const gainNode = ctx.createGain();
fetch("http://localhost:8000/3saudio/C4v9.wav")
.then(data => data.arrayBuffer())
.then(arrayBuffer => ctx.decodeAudioData(arrayBuffer))
.then(decodedAudio => {
c4 = decodedAudio;
})
function playnote(note, delay) {
const playSound = ctx.createBufferSource();
detune = 0;
nt = c4;
playSound.buffer = nt;
var gainNode = ctx.createGain();
var convolver = ctx.createConvolver();
//console.log(nt)
gainNode.gain.value = 1;
gainNode.gain.setValueAtTime(1, ctx.currentTime+delay);
gainNode.gain.exponentialRampToValueAtTime(0.0005, ctx.currentTime + 1.25 + delay);
if (detune>0){
playSound.detune.value = detune;
}
playSound.connect(gainNode).connect(ctx.destination);
playSound.start(ctx.currentTime + delay);
}
function step51 () {
var del = 0
start = 12
for (let i = 0; i < 10 ; i++) {
playnote (keys[start+0],del + 0);
playnote (keys[start+0],del + .25);
playnote (keys[start+4],del + .5);
playnote (keys[start+4],del + .75);
playnote (keys[start+7],del + 1);
playnote (keys[start+7],del + 1.25);
}
}
document.querySelector('button');
btn.addEventListener('click', function() {
keys = ['c4','c4','c4','c4', 'c4']
if (ctx.state === "suspended") {
ctx.resume();
}
step51()
});
btn_stop.addEventListener('click', function() {
**ctx.suspend()
//ctx.close()**
**//window.location.reload()**
//history.go(0);
});
</script>
The AudioContext backs the entire audio graph of all the audio objects you create. Normally, you'll only have one AudioContext per page, and you would only suspend it in circumstances where you don't want to play audio any time soon.
That is, rather that suspending the AudioContext, you should be stopping your AudioBufferSourceNode.