我正在尝试使用 WebAudio API 制作合成器/音序器。主要是尝试制作可以播放由音符和事件组成的歌曲的东西,例如 MIDI,以控制合成器的多个通道。但我仍然需要解决时间方面的问题。
我已阅读有关 WebAudio API 的教程,但我不太了解计时/调度/时钟的工作原理。起初我做了一个复音合成器,它可以为按键播放音符,这不需要任何时间考虑。然后我使振荡器在特定时间间隔播放一组音符,使用setInterval
. 但是我过去注意到在谷歌浏览器中切换标签时,播放速度显着减慢,我认为资源密集型较少 - 但其他合成库没有这个问题。此外,我只能假设使用setInterval
对于平滑(缓冲正确的词?)播放不是很好,尤其是在考虑 ADSR 包络振荡器时。
从我正在阅读的内容来看,WebAudio API 有一个不断增加的currentTime
计时器变量。但是,如果笔记存储在一个数组中并且我想以设定的速率循环它,那么如何操纵 WebAudio 计时器以按照设定的速率迭代数组?我的setInterval 解决方案(音量警告)根本不考虑 WebAudio 计时器,只是调用voice()
withsetInterval
来播放音符,覆盖最后播放的声音。
是否有更好或更有效的方法来播放/循环除 之外的一系列音符setInterval
?
只是更新澄清一下:当我写这个问题时,我setInterval
习惯于以固定的间隔播放一系列音符(例如,不定期的 - 不断启动/停止振荡器)并且想知道更可靠的方式来播放音符。我发现更好的解决方案是使用setValueAtTime
onosc.frequency
和GainNode
. 对于一个简单的原型合成器,这很好用,但更高级的合成器可以使用定时器 onosc.start
和osc.stop
。问题是循环播放歌曲。为了循环,我需要不断地安排更多的音符,以便在歌曲结束时重新开始。我可以用它setInterval
来安排整个歌曲循环,但它仍然必须保持播放歌曲的时间,并且setInterval
(甚至是 Web Workers'onmessage
例如,当标签不活动时,可以放慢速度)。setInterval 的时钟甚至不可靠,所以我只需每 5 毫秒检查一次是否(currentTime >= songTime)
满足条件,并安排时间。这种方法可能效率不高。我到目前为止所拥有的。