admin管理员组

文章数量:1355703

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();
}

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();
}
Share Improve this question edited Apr 20, 2018 at 15:24 johnny 5 21.1k53 gold badges136 silver badges214 bronze badges asked Aug 6, 2017 at 5:42 user7951676user7951676 3772 silver badges12 bronze badges 1
  • iOS safari mobile – user7951676 Commented Aug 6, 2017 at 6:09
Add a ment  | 

2 Answers 2

Reset to default 13

Your audioCtx assignment should be moved outside of drum(), as it will get called every time, eventually throwing an exception since you can't create more than 6 audio contexts in a document.

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')
      })
  }
}

本文标签: javascriptaudiocontext Samplerate returning null after being read 8 timesStack Overflow