网络音频内存泄漏 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
可能已被重新分配 - 因此您需要对原始振荡器的引用。
希望对您有所帮助。
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
可能已被重新分配 - 因此您需要对原始振荡器的引用。
希望对您有所帮助。