【问题标题】:Do Web Audio API events run in a separate thread?Web 音频 API 事件是否在单独的线程中运行?
【发布时间】:2016-08-05 03:44:02
【问题描述】:

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

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

有没有办法测试这个?

【问题讨论】:

  • 您是否还使用网络套接字流式传输音频?你是怎么上去的? ...在侧节点上从 Web Worker 线程中启动 Web Audio 会很好!

标签: javascript html web-audio-api


【解决方案1】:

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

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

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

myScriptProcessorNode.onaudioprocess = myWebWorker.postMessage;

【讨论】:

  • 我以前用过网络工作者。如果 onaudioprocess 正在主线程中执行,那么我想我不需要锁环缓冲区,只需要一个简单的同步缓冲区,对吧?我稍微改一下我的问题。
  • 是的,使用 JavaScript,您永远不需要锁定 - 一次只执行一个任务。
【解决方案2】:

使用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 的引用,以便将处理后的数据复制回最终由用户播放。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    相关资源
    最近更新 更多