最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - audiocontext Samplerate returning null after being read 8 times - Stack Overflow

programmeradmin9浏览0评论

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')
      })
  }
}
发布评论

评论列表(0)

  1. 暂无评论