6

我对ScriptProcessorNodeonaudioprocess(直到最近称为JavaScriptNode)特别感兴趣。它是一个事件侦听器,定期调用以进行音频处理。它是否在单独的线程中运行?

我想将数据提供给循环缓冲区并在此回调之外处理它,这样我就不会占用 CPU。我可以使用网络工作者进行异步处理,但是在不同线程的情况下,我需要一个不同的环形缓冲区实现。

有没有办法测试这个?

4

2 回答 2

5

所有的 JavaScript 都是单线程的,同步执行的。任何异步操作都是通过事件完成的,这些事件将它们的处理程序添加到任务队列中——在当前任务完成时执行。

要使用单独的线程,您需要一个像 WebWorkers 这样的环境——每个线程都有自己的执行上下文(全局范围)和任务队列;它们之间的通信是通过事件完成的。

由于onaudioprocess处理程序似乎与 DOM 位于同一范围内,因此它不太可能在自己的线程中运行。如果您确实有一个计算密集型任务导致您的页面无响应,您应该使用一个 WebWorker 来提供音频事件:

myScriptProcessorNode.onaudioprocess = myWebWorker.postMessage;
于 2012-11-09T00:13:08.620 回答
1

使用 Bergi 的解决方案,您将遇到结构化克隆算法无法复制 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 的引用,以便将处理后的数据复制回最终由用户播放。

于 2016-08-04T19:44:02.840 回答