【问题标题】:Using AudioWorkletProcessor for low-latency audio scheduling?使用 AudioWorkletProcessor 进行低延迟音频调度?
【发布时间】:2020-10-11 18:33:39
【问题描述】:

我有一个使用以下设置的交互式音乐排序应用程序:

  1. 用户在 UI 中进行更改以操作音频节点图。
  2. 一个简单的 WebWorker 负责保持时间。它会定期向主线程发送一条“tick”消息。
  3. 主线程中的侦听器接收消息并执行歌曲中的下一步(使用 AudioBufferSourceNode.start 播放样本、调整音量参数等)。

在 WebWorker 中使用计时器比仅使用 setInterval 更可靠,但在主线程处理消息之前仍可能存在延迟,从而导致音频故障。

似乎理想的解决方案是在 WebWorker 中执行第 3 步,但 AudioContext is not supported in workers。这样一来,AudioWorklet 就成为了唯一的低延迟网络音频 API。但它是图中的一个节点,而我正在寻找一种方法来管理整个事情。除了重写整个系统以在 AudioWorkletProcessor 中运行(大量工作)之外,有没有办法使用处理器进行精确调度,但保留现有的图形结构?

【问题讨论】:

    标签: javascript html5-audio web-audio-api audiocontext audio-worklet


    【解决方案1】:

    AudioContext 有自己的时钟,使用它。

    node1.start( ctx.currentTime + 1 ); // in one second
    node2.start( ctx.currentTime + 2 ); // in two seconds
    node3.start( ctx.currentTime + 3 ); // in three seconds
    
    • 如果您想对前一个缓冲区源的结尾做出反应,请使用其onended 事件监听器:
    node.onended = (evt) => startANewNode();
    
    • 如果您想要一个并行计时器,请使用一个 setTimeout 循环来纠正可能的漂移:
    const duration = 1000;
    let expected = ctx.currentTime + duration;
    function loop() {
      const drift = expected - ctx.currentTime;
      startANewNode();
      setTimeout( loop, duration - drift );
    }
    setTimeout( loop, duration );
    
    

    当然,您甚至可以将所有这些点结合在一起,完全基于 AudioContext 的时钟创建您自己的计时器。

    【讨论】:

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