取消预定的网络音频

时间:2019-10-26 19:27:16

标签: javascript web-audio-api

我已经了解A Tale of Two Clocks所能提供的知识,它描述了一种通过现场编辑(例如鼓机)为Web音频应用程序进行调度的方法,我对一个关键方面感到困惑。

该技术的主要动机是一旦安排AudioBufferSourceNodestart()一起玩,就不能取消它。

但是,如果我在预定播放之前在stop()上呼叫AudioBufferSourceNodes,它将永远不会播放,因此可以取消。那么为什么需要这种技术呢?我想念什么?

2 个答案:

答案 0 :(得分:1)

主要优点是audioBufferSourceNode.start(someTimeInTheFuture)可以精确采样。这就是为什么它优于setTimeout(() => audioBufferSourceNode.start(), someTimeInTheFuture)的原因,后者根本不准确。

由于Web Audio API的内部功能,如果可能的话,最好提前安排一些时间。每当在start()上调用AudioBufferSourceNode时,该命令必须从主线程传递到音频线程,然后在该音频线程中执行该命令。这需要一些时间,这意味着如果您想立即开始某些事情,它可能在音频线程中到达的时间太晚了。

答案 1 :(得分:1)

我认为OP正在问“为什么不提前安排所有笔记,然后如果要停止则通过(stop。)取消所有剩余的笔记?”

实际上,您可以这样做。对于小序列,这可能是一种好的方法。但是:

如果您想取消它们,则需要分别保留对每个AudioBufferSourceNode的引用-单独的第16音符hihat模式在140bpm的速度为2800音符(= AudioBufferSourceNodes),持续5分钟歌曲。对于整首歌曲,这也可能是大量的内存,可以一次分配和取消分配所有内存。对于更长的序列,可能吸引力不大。

如果要对序列播放进行实时更改,则尤其如此-例如,如果要更改速度,则需要取消所有剩余音符,然后重新安排它们。

我在ATOTC中详细介绍的技术的主要动机是在第二部分的结尾:“总之,因为您将需要灵活地更改速度或诸如频率或增益之类的参数(或完全停止调度),所以您不必不想将太多的音频事件推入队列-或更准确地说,您不希望时间过长,因为您可能希望完全更改该计划。”我确实提到取消,但这确实是事后的想法。

如果您使用的是相对较短的序列,并且您不关心使用的额外内存,那么最简单的方法就是创建一个GainNode,将其连接到目标,然后设置所有AudioBufferSourceNodes连接到该GainNode。明确地,不要保留对您的ABSN的引用,而应保留对GainNode的引用-如果要取消,只需断开GainNode并释放它即可。没有其他东西可以玩到目的地了,所有东西最终都将被释放。 (我在第二节中也提到了这一点,尽管它可能有点贬义。对于较小的应用程序来说也可以。)