我正在编写同时播放数字音频(合成音乐)和 MIDI 音乐(使用 RtMidi 库)的 C++ 代码。数字化的音乐将在计算机的音频设备中播放,但 MIDI 音乐可以在外部合成器。我想播放一首同时使用数字化乐器和 MIDI 乐器的歌曲,但我不确定同步这两个音频流的最佳方式:
- 无法使用像 Sleep() 这样的函数,因为延迟时间既不均匀又太长,无法满足我的需要(大约为 1 毫秒)。如果 Sleep() 在仅请求 1ms 时定期等待 5ms,生成的歌曲速度将关闭,除非每次调用时都准确,否则速度将不均匀。
- 计算放入音频缓冲区的样本数量可为数字音频的音符之间提供超精确的时序(一个样本的最小延迟 - 48kHz 时为 0.02 毫秒),但此时序不能用于 MIDI。因为音频是缓冲的,所以音符会以突发方式合成(一次填充一个音频缓冲区,尽可能快),所以这会导致每次数字音频缓冲区需要播放一堆 MIDI 音符时,它们之间没有延迟被重新填充。
- 播放实时 MIDI 数据没有时间信息,因此一旦发送音符就会播放。因此,一个音符不能安排在以后播放,所以我需要自己在正确的时间准确地发送 MIDI 事件。
目前我正在使用 nanosleep() - 它仅适用于 Linux,而不适用于 Windows - 等待音符之间的正确时间。这允许数字音频和 MIDI 数据保持同步,但是 nanosleep() 不是很一致,因此产生的速度非常不均匀。
谁能想到一种方法来保持数字音频和 MIDI 数据的音符之间的准确时序?