当我用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()
,问题仍然存在。所以问题不在于它试图重播同一个文件的事实
答案 0 :(得分:1)
原因如下:
即使我们将音频缓冲区降低到声卡支持的最小值(1024或512个样本而不是pygame
的默认值4096),差异仍然存在,使得不确定应该是什么a"节拍器击败"。
我会在找到工作解决方案后立即更新。 (我在这方面有一些想法)。
答案 1 :(得分:1)
正如您在自己的回答中所写,时间问题的原因很可能是音频回调与应用程序的其余部分分离。
音频后端通常具有某种时钟,可以从回调函数内部及其外部访问。 我看到两种可能的解决方案:
使用一个允许您自己实现回调函数的库,计算回调函数内声音的开始时间,将这些时间与"音频时钟"的当前时间进行比较。并将声音写入输出缓冲区中适当位置的输出。
使用一个库,您可以指定何时开始播放声音的确切时间(根据"音频时钟")。该库将为您执行上一步的步骤。
对于第一个选项,您可以使用sounddevice模块。回调函数(您必须实现)将获得名为time
的参数,该参数具有属性time.outputBufferDacTime
,这是一个浮点值,指定时间(以秒为单位)将播放输出缓冲区的第一个样本。
完全披露:我是sounddevice
模块的作者,所以我的建议很偏颇。
最近,我开始研究rtmixer模块,可用于第二种选择。
请注意,这处于非常早期的开发状态,因此请谨慎使用。
使用此模块,您不必编写回调函数,您可以使用函数rtmixer.Mixer.play_buffer()
在指定时间(以秒为单位)播放音频缓冲区。作为参考,您可以从rtmixer.Mixer.time
获取当前时间。