使用PyGame播放音频文件时的错误时机

时间:2017-03-03 01:16:57

标签: python audio pygame

当我用PyGame每隔0.5秒播放一次声音时:

import pygame, time

pygame.mixer.init()
s = pygame.mixer.Sound("2.wav")

for i in range(8):
  pygame.mixer.Channel(i).play(s)
  time.sleep(0.5)

它根本不正确地考虑时间。

就像暂停0.2秒而不是0.7秒然后再0.2秒,这是非常不规则的。

注意:

  • 我知道time.sleep()不是世界上最准确的,但即使使用更准确的解决方案from here,问题仍然存在

  • 在RaspberryPi上测试

  • 如果我在很大范围内播放许多不同的文件s[i].play(),问题仍然存在。所以问题不在于它试图重播同一个文件的事实

2 个答案:

答案 0 :(得分:1)

原因如下:

enter image description here

即使我们将音频缓冲区降低到声卡支持的最小值(1024或512个样本而不是pygame的默认值4096),差异仍然存在,使得不确定应该是什么a"节拍器击败"。

我会在找到工作解决方案后立即更新。 (我在这方面有一些想法)。

答案 1 :(得分:1)

正如您在自己的回答中所写,时间问题的原因很可能是音频回调与应用程序的其余部分分离。

音频后端通常具有某种时钟,可以从回调函数内部及其外部访问。 我看到两种可能的解决方案:

  1. 使用一个允许您自己实现回调函数的库,计算回调函数内声音的开始时间,将这些时间与"音频时钟"的当前时间进行比较。并将声音写入输出缓冲区中适当位置的输出。

  2. 使用一个库,您可以指定何时开始播放声音的确切时间(根据"音频时钟")。该库将为您执行上一步的步骤。

  3. 对于第一个选项,您可以使用sounddevice模块。回调函数(您必须实现)将获得名为time的参数,该参数具有属性time.outputBufferDacTime,这是一个浮点值,指定时间(以秒为单位)将播放输出缓冲区的第一个样本。

    完全披露:我是sounddevice模块的作者,所以我的建议很偏颇。

    最近,我开始研究rtmixer模块,可用于第二种选择。 请注意,这处于非常早期的开发状态,因此请谨慎使用。 使用此模块,您不必编写回调函数,您可以使用函数rtmixer.Mixer.play_buffer()在指定时间(以秒为单位)播放音频缓冲区。作为参考,您可以从rtmixer.Mixer.time获取当前时间。