网络音频 api 计时是不是比 setTimeout 更精确

Posted

技术标签:

【中文标题】网络音频 api 计时是不是比 setTimeout 更精确【英文标题】:Is the web audio api timing more precise than setTimeout网络音频 api 计时是否比 setTimeout 更精确 【发布时间】:2016-12-23 19:35:17 【问题描述】:

在网络音频 api 中推送声音时,您可以设置声音以source.start(startTime); 开头的时间。但是我想知道这有多精确。我知道setTimeout() 只是将要执行的代码放在事件队列中。我认为这也是 Web 音频 api 所做的,但这只是一个猜测。因此,两者之间没有区别。

我尝试在播放声音之前运行一些长时间运行的进程,并且声音确实延迟了。

  //...
  source.start(startTime + 0.2);
  //....
 let i = 0;
 while( i < 100000)
   console.log("p" + i);
   i++;
 

网络音频 api 在底层使用 setTimeout 也是如此。如果是这样,我可以通过使用网络工作者使事情变得更加敏感吗?我知道网络工作者可以访问 setTimeout,但我不确定它是否可以访问网络音频 api。

来自文档:

音频工作者提供直接脚本音频处理的能力 在 web worker 上下文中完成,并由几个定义 接口(自 2014 年 8 月 29 日起新增。)这些未在 还没有任何浏览器

这只是解决音频处理的问题,我不确定这是否包括播放音频。

【问题讨论】:

【参考方案1】:

网络音频 api 计时是否比 setTimeout 更精确?

是的,到目前为止!音频计时器implementation 旨在减少(累积)延迟,并将实时和精确计时功能降低到采样级别。它使用音频事件的精确调度程序。

来自MDN:

以高精度和低延迟控制时间,允许 开发人员编写能够准确响应事件的代码,并且 即使在高采样率下也能够针对特定样本。所以 鼓机和音序器等应用程序都在 到达。

来自the W3C Editor's Draft 20 December 2016:

[...] 特别是,实现者可以不使用消息队列,而是使用 线程之间共享的内存,只要内存 操作不会重新排序。

setTimeout() 的工作方式对于一般的音频处理来说不够准确,甚至可以限制其下限时间值(例如,将其设置为 1ms 可能会被浏览器更改为 4ms)。它可能会或可能不会在目标时间触发,具体取决于事件队列以及其他因素。

要记住的另一件事是,Web Audio API 中的所有预定时间都与AudioContextcurrentTime 的值相关(同上)。

那么网络音频 api 在底层使用 setTimeout 吗?

有点已经回答了,但是没有,绝对没有:)

Audio Worker 节点将用于处理音频数据(如当前但已弃用的ScriptProcessorNode),但在单独的线程上而不是播放音频本身。所有音频播放都通过主音频线程进行。在Audio Workers Nodes here 上查看更多信息。

【讨论】:

感谢您的详尽回答,这对您很有帮助。我不确定我是否看到音频工作者的使用,或者也许我确实看到了。例如,当我想用​​release effect(声音逐渐变低)停止声音时,我使用setTimeout。如果我有一个音频网络工作者,我想我可以在音频网络工作者而不是主线程中做到这一点,并且更精确。这没什么大不了的,因为它是进步的,但我会很高兴。我希望它会尽快实施。再次感谢。

以上是关于网络音频 api 计时是不是比 setTimeout 更精确的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 计时

直接调用音频单元而不是回调 iOS

网页音频API 第二章

当我需要自定义音频效果时,我是不是需要处理音频单元,或者我可以依赖音频队列服务?

如何使用来自网络套接字的网络音频 API 流式传输音频块?

在连接到网络音频 api 的音频元素上设置播放速率