gpt4 book ai didi

javascript - WebAudio 计时如何工作?使用 setInterval 是一个糟糕的解决方案吗?

转载 作者:太空宇宙 更新时间:2023-11-04 16:00:24 27 4
gpt4 key购买 nike

我正在尝试使用 WebAudio API 制作合成器/音序器。主要是想做一些可以播放由音符和事件组成的歌曲的东西,比如 MIDI 来控制合成器的多个 channel 。但我仍然需要解决时间方面的问题。

我已阅读有关 WebAudio API 的教程,但我不太了解计时/调度/时钟的工作原理。一开始我做了一个polyphonic synthesizer为按键播放音符,这不需要考虑任何时间。然后,我使用 setInterval 使振荡器以特定时间间隔播放一组音符。然而,我注意到过去在 Google Chrome 中切换标签时,播放速度明显减慢,我认为资源占用较少 - 但其他合成库 没有这个问题。此外,我只能假设使用 setInterval 不利于流畅(缓冲正确的词?)回放,尤其是在考虑 ADSR 包络振荡器时。

根据我的阅读,WebAudio API 有一个不断增加的 currentTime 计时器变量。但是如果音符存储在一个数组中并且我想以设定的速率循环它,那么如何操作 WebAudio 计时器以按设定的速率迭代数组?我的setInterval solution (volume warning)根本不考虑 WebAudio 定时器,只是调用 voice()setInterval 来播放一个音符,覆盖最后播放的声音。

除了 setInterval 之外,是否有更好或更有效的方式来播放/循环音符序列?

只是更新澄清一下:当我写这个问题时,我正在使用 setInterval 以固定间隔播放一系列音符(例如,未安排 - 不断开始/停止振荡器)并想知道更可靠的方法来演奏音符。我发现更好的解决方案是在 osc.frequencyGainNode 上使用 setValueAtTime。对于简单的原型(prototype)合成器,这很有效,但更高级的合成器可以在 osc.startosc.stop 上使用计时器。问题是循环播放歌曲。为了循环,我需要不断安排更多音符,以便在歌曲结束时重新开始。我可以使用 setInterval 来安排整个歌曲循环,但它仍然必须与歌曲播放保持同步,并且 setInterval(甚至 Web例如,当标签不活动时, worker 的 onMessage 调用)可以放慢速度。 setInterval 的时钟甚至不可靠,所以我只是每 5 毫秒检查一次是否 (currentTime >= songTime) 并在满足条件时安排。这种方法可能不太有效。 What I have so far .

最佳答案

我几年前写过这篇文章:https://www.html5rocks.com/en/tutorials/audio/scheduling/ .它涉及网络音频计时器和 setInterval 之间的区别;简而言之,您不能在网络音频时钟中“操纵时间”,它是由声卡中的硬件时钟驱动的。不过,您可以安排事件在其时间范围内发生,使用 setInterval 作为非常紧张/较慢的周期提醒来安排新事件。

至于你的切换选项卡问题,这是一个 1Hz 的速率限制器,大多数现代浏览器必须避免使用 setInterval 作为渲染计时器的人的电力成本(例如 setInterval 间隔为 16ms 以尝试安排视频的每一帧).您可以通过两种方式避免它 - 使用 Web Workers 的 hack,我在我的节拍器演示 (https://github.com/cwilso/metronome) 中使用它,或者您可以在窗口失去焦点时 Hook (在窗口对象上触发 onblur 事件)以开始调度一次超过 1 秒的事件。唯一的问题是当窗口再次获得焦点时(onfocus 事件在 window 对象上触发),您将在 Web Audio 中安排最多一秒钟的事件 - 您无法切换回窗口并立即点击“停止”,例如

setInterval 本身并不是重复节奏的音乐计时的好解决方案,因为当主线程中有大量其他事情(包括垃圾收集)时,它会抖动(即延迟)。您会开始听到抖动,尤其是在性能较低的 CPU 上。

关于javascript - WebAudio 计时如何工作?使用 setInterval 是一个糟糕的解决方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42124448/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com