2012-11-08 105 views
6

我在onaudioprocess的ScriptProcessorNode特別感興趣(直到最近稱爲JavaScriptNode)。它是定期爲音頻處理調用的事件監聽器。它是否在單獨的線程中運行?Web Audio API事件是否在單獨的線程中運行?

我想將數據提供給循環緩衝區並在此回調之外處理它,所以我不佔用CPU。我可以使用網絡工作者進行異步處理,但AFAIK我需要不同線程情況下的環形緩衝區的不同實現。

有沒有辦法測試這個?

+0

你是否也使用網絡套接字流音頻?你過得怎麼樣? ...在邊上的節點將很高興從Web Worker線程內啓動Web Audio! –

回答

5

所有的JavaScript都是單線程的,同步執行。任何異步的東西都是通過事件完成的,這些事件將其處理程序添加到任務隊列中 - 在當前任務完成時執行。要使用單獨的線程,您需要像WebWorkers這樣的環境 - 每個線程都有自己的執行上下文(全局範圍)和任務隊列;他們之間的溝通是通過事件完成的。

由於onaudioprocess處理程序似乎與DOM處於相同的作用域,所以它很可能不在它自己的線程中運行。如果你真的有一個計算密集的任務,使你的網頁反應遲鈍,你應該使用WebWorker到你喂音頻事件:

myScriptProcessorNode.onaudioprocess = myWebWorker.postMessage; 
+0

我以前使用過網絡工作者。如果在主線程中正在執行onaudioprocess,那麼我想我不需要鎖環緩衝區,只是一個簡單的同步緩衝區,對嗎?我會稍微改述一下我的問題。 – Davorin

+0

是的,用JavaScript你永遠不需要鎖定 - 一次只有一個執行的任務。 – Bergi

0

隨着BERGI的解決方案,你會碰到與structured clone algorithm不是問題能夠複製audioProcessingEvent中的只讀參數。你需要做的是打破了你是可複製的事件需要的部分,並通過他們交給你的工人在不同的數據結構,像這樣:

_onAudioProcess(audioProcessingEvent) { 
    const {inputBuffer, outputBuffer} = audioProcessingEvent; 
    // The output buffer contains the samples that will be modified and 
    // eventually played, so we need to keep a reference to it. 
    this._outputBuffer = outputBuffer; 
    const numChannels = inputBuffer.numberOfChannels; 

    const inputChannels = 
    Array.from({length: numChannels}, (i) => { 
     return inputBuffer.getChannelData(i); 
    }); 

    this._worker.postMessage({ 
    command: 'DO_STUFF', 
    inputChannels: inputChannels, 
    }); 
} 

你也將需要訪問在setMessageHandler中引用您的outputBuffer,以便將處理後的數據複製回來,最終由用戶播放。

相關問題