关于 javascript:Web Audio API 调度以构建音序器。我不明白

Web Audio API scheduling to build a sequencer. I don't get it

我正在尝试学习如何编写一个基本程序,让我看到使用网络音频 API 安排声音事件的正确方法,以加深我对构建简单声音音序器所需模式的理解。我试图理解克里斯威尔逊关于两个时钟文章的故事,但它完全超出了我的脑海。所以基本上我希望真正理解它的人可以尝试以不同的方式解释它,希望他们中的一个人会"坚持",类似于 StackOverflow 有一个鼓励对闭包进行不同解释的线程。让我展示我到目前为止所理解的内容。

我了解如何使用 setInterval

制作一个简单的音序器

我知道您可以使用以下代码安排要播放的声音:

1
playSound.start(audioContext.currentTime+numb);

我在概念上不明白的是如何以使用网络音频 api 计时而不是 setInterval/setTimeout 的方式将视觉问题与音频播放事件挂钩。

我正在研究这个以确切了解它是如何工作的:
http://www.html5rocks.com/en/tutorials/audio/scheduling/goodmetronome.html

但与此同时,我想我会发布此线程以帮助从 SO 上的人那里并行学习更多信息。


我不确定您所说的"将视觉队列与音频播放事件挂钩"是什么意思,如果这不能解决您的问题,请详细说明。

您仍然需要使用 setInterval(或 setTimeout)在实现良好的排序器中进行调度。问题是 setInterval/setTimeout 的准确度,特别是在主线程中,可能相当低(即当你说 "setTimeout(600)" 时,你可能会在 600 毫秒后被回调;你可能会在 640 毫秒内被回调) .这是由于主线程中发生的其他事情(例如布局、渲染和 Javascript 垃圾收集)以及 Javascript 中的事件处理系统本身造成的。

为了解决这个问题,你需要第二层调度——换句话说,不是你的 setInterval 回调调用 "start(0)"(这基本上意味着 "一旦你接到这个电话就开始播放"),你说 "start( sequenceStartTime offset )" 足够早,所以它在正确的时间开始,但足够晚,所以你可以决定不调用它(即你不需要定位整首歌曲在音频事件中)。音频事件以非常高的精度分派——如果你说"在时间 t 开始这个缓冲区播放",它将在时间 t 开始——不可能是三十毫秒之后。

如果您要问"我如何做到这样,当用户敲击打击垫时,它会记住在序列中的正确时间播放它"-好吧,您记得何时开始序列在音频和系统时间:

1
2
sequenceStartTime = Date.now();
sequenceAudioStartTime = audioContext.currentTime;

并使用循环次数乘以序列长度来计算开始时间。 (这基本上就是节拍器的作用。)很高兴在聊天中实时浏览。