使用pygame
音频播放时,我注意到高延迟(> 100 ms):
import pygame
pygame.init()
pygame.mixer.init()
sounda = pygame.mixer.Sound("test.wav")
def callback()
sounda.play()
# callback is called by another function, but I could measure a high latency (> 100ms)
pygame
导致延迟吗?更一般地说,使用Python可以低延迟音频播放吗?
应用程序示例:当MIDI信息从MIDI键盘到达时播放一些.wav文件。 (我想编写一个非常非常基本的音乐采样器)。 当然,延迟将在很大程度上取决于音频接口(ASIO或ASIO等),但我现在想分析Python是否可以实现低附加延迟,如果是这样,那么哪个模块是首选。< / p>
答案 0 :(得分:6)
pygame是延迟的原因吗?
可能不是。
Pygame只是SDL的包装。在某些领域 - 比如这个 - 它是一个非常薄的包装。
但SDL - 或者更确切地说,SDL_mixer
- 可能很容易成为问题。
因此,您可能需要了解SDL,以便将pygame
用于超出通常游戏风格需求的音频。 Audio with SDL是一个很好的概述,虽然看起来有点过时了。
首先要考虑的是你正在使用的音频驱动程序。例如,在许多Linux系统上,ALSA无法进行低延迟声音,这意味着您编写的最终与ALSA对话的任何内容都无法做到。如果您的系统设置为尽可能使用esd
或其他声音守护程序并在必要时退回,那么您显然不希望这样。因此,如果您遇到类似问题,则必须配置SDL_mixer
以使用其他驱动程序。
假设驱动程序可以处理它,肯定可以使用pygame.mixer
/ SDL_mixer
执行低延迟声音。但它可能无法开箱即用。
您要做的第一件事是选择比默认值更小的缓冲区大小。
另请注意,SDL_mixer
会自动重新编码您背后的声音,如果它们的采样率不同/等。作为目标,它不仅为CPU工作增加了一点延迟,还意味着真正的缓冲区大小与你认为正在使用的那个没有任何关系......
另一种方法是绕过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
,则可能会遇到Python循环缓慢且算术速度慢的问题。
“慢”是指微秒级。每20ms缓冲一次循环不是问题。每个样本循环一次可能是。如果您正在进行任何处理,您应该考虑使用NumPy或专用音频库来执行繁琐的工作而不是纯Python。