将音乐同步到基于帧的时间

Sync music to frame-based time

我正在制作一款游戏,其中有一系列事件(例如,在 60fps 设置下每 30 帧发生一次)我想与音乐同步(120 bpm)。在通常情况下,例如节奏游戏,将事件与音乐同步更容易,因为人类似乎感知音乐中的间隙比视频中的间隙小得多。但是,就我而言,游戏在很大程度上取决于基于帧的时间,如果我更改系列事件的时间表,很多事情都会中断。

经过大量实验,在我看来几乎不可能在不干扰人耳的情况下调整音乐:~1ms 的跳跃是明显的,视频和音频之间~10ms 的差异是明显的,0.5% 的变化在球场上是显而易见的。而且我没有方便的工具来在不改变音高的情况下加快音频速度。

在这种情况下最简单的出路是什么?我可以参考关于这个主题的任何参考资料吗?任何建议表示赞赏!

我成功使用的方法 I(在 Java 中)是通过允许 PCM 帧计数的路径路由播放信号(音频帧 运行,速率为 44100 fps,而不是 运行 以 60 fps 的速率更新屏幕)。我不知道其他语言,但是使用 Java,这可以通过使用 SourceDataLine class. As the audio frame count is incremented, it can be compared to the next item (pending item) on a collection of events that require triggers to other systems or threads. Java has an excellent class for handling the collection of events: ConcurrentSkipListSet 输出来完成。它是异步的,并通过 Comparator 设置为所需的 PCM 帧数自动对元素进行排序。

如果您在页面上搜索短语“在这里,对音频数据做一些有用的事情”,可以在使用 Files and Format Converters 的教程中看到一些显示帧计数的示例代码。他们计算的是字节数,而不是 PCM 帧,但是这个例子确实给出了基本的想法。

为什么计数PCM有效?我认为这与以下事实有关:这段代码(在 Java 中)是我们最接近将音频数据馈送到控制声音系统的本机代码的点,并且这段代码采用了阻塞队列.因此,写入操作仅在音频系统准备好接收和播放更多声音数据时发生,并且音频系统必须非常准确地保持其处理速率。这里发生的时间变化量(特别是如果线程被赋予高优先级)小于 JVM 在处理多个线程和进程时做出的选择所引起的时间变化。