audiocontext Samplerate returning null after being read 8 times

Viewed 1597

I have made a function to produce a drum sound how ever after being called 4 times it stops working with the error:

TypeError: null is not an object (evaluating 'audioCtx.sampleRate') Showing in the console.

What's wrong with this function? My code is:

drum = function(){
    var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    var frameCount = audioCtx.sampleRate/20
    var myArrayBuffer = audioCtx.createBuffer(1, frameCount, audioCtx.sampleRate);
    var nowBuffering = myArrayBuffer.getChannelData(0);
    for (var i = 0; i < frameCount; i++) {
        nowBuffering[i] =Math.sin(i**(1/1.8)/4)
    }

    var source = audioCtx.createBufferSource();
    source.buffer = myArrayBuffer; source.connect(audioCtx.destination);
    source.start();
}
2 Answers

In fact reusing one instance of AudioContext is not good solution as it's potential memory leak.

Such long-living AudioContext instance is killed by Safari when browser goes idle (when you switch to another iOS app). Once the Safari is opened again AudioContext instance is no longer available.

Proper solution is to create new context each time and close it when it's no longer needed.

With such approach no browser limit on AudioContext is applied.

const drum = () => {
  const audioCtx = new (window.AudioContext || window.webkitAudioContext)()
  // your stuff here…

  // Return cleanup function and call it when needed
  return () => {
    // Cleanup to prevent memory leaks
    audioCtx
      .close()
      .catch(() => {
        console.log('Closing AudioContext failed')
      })
  }
}
Related