网络音频内存泄漏 api 振荡器

Memory leak with web audio api oscillator

http://codepen.io/superuntitled/pen/EjZOjw/?editors=001

我有一个小的网络工具(见上面的 link)有内存泄漏,我不确定如何插入它。

将鼠标悬停在元素上时会调用以下函数(有几百个这样的元素)。

function tone(id, freq, tonelength) {

  gainNodes.id = audioCtx.createGain();
  osc.id = audioCtx.createOscillator();
  osc.id.connect(gainNodes.id);
  // set frequency and gain
  osc.id.frequency.value = freq;
  osc.id.start(0);

  gainNodes.id.connect(audioCtx.destination);

  gainNodes.id.gain.linearRampToValueAtTime(.1, audioCtx.currentTime);

  gainNodes.id.gain.linearRampToValueAtTime(0, audioCtx.currentTime + parseFloat(tonelength));

}

我认为正在创建重复的振荡器,但我不确定如何检查是否是这种情况,或者如何避免这种情况。

我觉得我应该检查一下振荡器是否已经存在,并且只是 运行 增益,但我不确定该怎么做。

我试图在振荡器持续时间后停止它,但这似乎并没有阻止泄漏:http://codepen.io/superuntitled/pen/rVmqYX?editors=001

osc.id.stop(audioCtx.currentTime + parseFloat(tonelength));

关于如何做到这一点有什么想法吗?

osc.id 有点奇怪,因为您将 id 设置为 属性 名称而不是 osc[ id ] – 但将那部分放在一边,您希望将其添加到 tone() 函数的底部:

var current = osc.id;

current.stop( audioCtx.currentTime + 2 );

current.onended = function() {
  current.disconnect();
};

基本上就是说 "Stop playing after 2 seconds, and when you're done, disconnect yourself from the AudioContext"。

如果 id 被动态分配给 osc(例如 osc[ id ]),那么您可能还需要 delete osc[ id ] – 但这似乎只是每次 tone() 以您现在的方式调用时都会被覆盖 - 因此旧振荡器应该有资格进行垃圾收集。

current 变量的原因是,到 onended 触发时,osc.id 可能已被重新分配 - 因此您需要对原始振荡器的引用。

希望对您有所帮助。