2015-06-09 119 views
-1

http://codepen.io/superuntitled/pen/EjZOjw/?editors=001Web Audio API使用振盪器

內存泄漏我有一個小的網絡工具(見上面的鏈接),有內存泄漏,而且我不確定如何插入。

當一個元素被懸停時(這裏有幾百個元素),將調用以下函數。

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

如何可以這樣做有什麼想法?

回答

1

osc.id的事情是有點怪異,因爲你設置id作爲屬性名稱,而不是osc[ id ] - 但在離開的那部分之外,你會想要將它添加到您的tone()函數的底部:

var current = osc.id; 

current.stop(audioCtx.currentTime + 2); 

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

基本上說「停止播放2秒後,當你完成,斷開你自己的AudioContext」。

如果id被動態地分配給osc(如osc[ id ]),那麼你很可能還需要delete osc[ id ] - 但似乎只是每次tone()被調用,你有現在的方式越來越重寫 - 這樣的老振盪器應該有資格進行垃圾回收。

current變量的原因是,到時間onended火災,osc.id可能已被重新分配 - 所以你需要一個參考原始振盪器。

希望有所幫助。

+0

嚴格來說,'onended'中的斷開連接是無用的。由於'OscillatorNode's不能被重用,所以當到達'stop'的時間到達時停止處理。然後它被收集並自動斷開連接,並允許您在代碼中刪除所有對它的引用。 但這是一個細節,它不會以任何方式傷害。 – padenot

+0

有道理。我不記得'AudioContext.destination'是否持有對連接到它的節點的引用。進一步思考,很明顯這將是一個可怕的想法。感謝您的澄清。 –

+0

感謝凱文的幫助,我認爲我可以接受並使用它。我感謝你的幫助。 – superUntitled