pygame 是延迟的原因吗?
可能不是。
Pygame 只是 SDL 的一个包装器。在某些领域——比如这个——它是一个非常薄的包装纸。
但SDL_mixer
SDL——或者更确切地说——很容易成为问题所在。
因此,您可能需要了解一些有关 SDL 的知识,才能pygame
用于超出通常游戏风格需求的音频。带有 SDL 的音频是一个很好的概述,尽管它似乎有点过时了。
首先要考虑的是您使用的音频驱动程序。例如,在许多 linux 系统上,ALSA 不能做低延迟的声音,这意味着你写的任何最终与 ALSA 对话的东西也不能做。如果您的系统设置为使用esd
或其他声音守护程序(如果可能)并在必要时回退,您显然不希望在此处使用。所以,如果这样的事情是你的问题,你将不得不配置SDL_mixer
使用不同的驱动程序。
pygame.mixer
假设驱动程序可以处理它,那么绝对可以使用/发出低延迟的声音SDL_mixer
。但它可能无法开箱即用。
您要做的第一件事是选择比默认值更小的缓冲区大小。
另请注意,SDL_mixer
如果它们不在相同的采样率/等下,它将自动在您的背后重新编码您的声音。作为目标,这不仅为 CPU 工作增加了一点延迟,还意味着实际缓冲区大小与您认为正在使用的缓冲区无关......</p>
另一种方法是绕过pygame.mixer
/ SDL_mixer
,自己进行混合,然后直接进入pygame.sound
/ SDL_sound
。这仍然会有相同的驱动程序问题,但任何由SDL_mixer
(如重新编码)引起的问题都会消失。
如果你不能让 pygame/SDL 做你想做的事(例如,因为它在你的系统上支持的唯一驱动程序都很糟糕),你将不得不使用不同的库。wiki 上的PythonInMusic有数百个链接,你也可以搜索 PyPI。但是,您可能想从另一边开始——找到一个您想要使用的 C 音频库,然后搜索它的 Python 绑定。例如,pyAudio 是 PortAudio 的一个相对较薄的包装器,因此如果 PortAudio 的可移植性、可配置性和性能要求满足您的需求并且它的 API 适合您的设计,它就会很糟糕,否则它就很糟糕。
另一个可能出错的地方是你的代码。
这显然不是你的问题,因为你所做的只是给出pygame.mixer
一个预制的声音。但是,如果您决定需要将声音预转换并将缓冲区输入pygame.sound
.
“慢”是指微秒级。每 20 毫秒缓冲区循环一次不是问题。每个样本可能循环一次。如果您正在进行任何处理,您应该考虑使用 NumPy 或专用音频库来完成繁重的工作,而不是纯 Python。