我正在研究制作一些软件,使键盘的功能像钢琴一样(例如,用户按下“W”键,扬声器会播放 D 音符)。我可能会使用 OpenAL。我了解数字音频的基础知识,但播放实时音频以响应按键会带来一些我无法解决的问题。
问题是:假设我有 10 个音频缓冲区,每个缓冲区保存一秒钟的音频数据。如果我必须在通过扬声器播放缓冲区之前填充缓冲区,那么我会在播放缓冲区前一两秒填充缓冲区。这意味着每当用户尝试弹奏音符时,在按下键和弹奏音符之间会有一到两秒的延迟。
你是如何解决这个问题的?您是否只是让缓冲区尽可能小,并尽可能晚地填充它们?有没有我遗漏的技巧?
最佳答案
大多数软件合成器根本不使用多个缓冲区。
他们只使用一个不断播放的小型环形缓冲区。
高优先级线程将尽可能频繁地检查当前播放位置并用声音数据填充环形缓冲区的空闲部分(例如自上次线程运行以来播放的部分)。
这会给你一个恒定的延迟,它只受环形缓冲区大小和声卡输出延迟的限制(通常不会那么多)。
您可以进一步降低延迟:
如果要播放新音符(例如,用户刚刚按下一个键),您会检查环形缓冲区中的当前播放位置,为安全添加一些样本,然后使用应用了新的声音设置。
如果您运行基于时间的效果(延迟线、混响等),这会变得很棘手,但这是可行的。只需每毫秒左右跟踪一次基于时间的效果的最后 10 个状态。这将使及时返回 10 毫秒成为可能。
关于audio - 使用软件合成器制作实时音频应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1392725/