2017-03-03 77 views
0

当我播放声音每0.5秒与pygame的时机不好。播放音频文件时pygame的

这就好比0.2秒暂停0.7秒再0.2秒,这是非常不规则的。


注:

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

  • 测试上a RaspberryPi

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

+1

”0.2秒的停顿时间超过0.7秒,然后再0.2秒,这是非常不规则的。“这听起来对我来说听起来很不规律,听起来很循环。声音持续多久?特别是因为'0.7 ==(sleep_time + 0.2)' – roganjosh

+0

@roganjosh为什么会有这样一个循环? 's.play()'是非阻塞的并且应该继续代码 – Basj

+0

@roganjosh我修改了代码以利用通道,因此每个播放的声音都不应该干扰另一个声音。问题仍然存在... – Basj

回答

1

这里的原因是:

enter image description here

即使我们降低音频缓冲区所支持的最小声卡(1024或512个样本,而不是pygame的默认4096个),差异仍然存在,使得应该成为“节拍器节拍”的应该是不合适的。

我会尽快找到一个适合您的工作解决方案。 (我在这个方向有几个想法)。

1

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

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

  1. 使用库,可以让你实现回调函数自己,计算回调函数内部声音的开始时间,这些时间用“音频的当前时间比较时钟“,并将声音写入输出缓冲区中适当位置的输出。

  2. 使用一个库,允许您指定何时开始播放声音的准确时间(按照“音频时钟”)。这个图书馆会为你做前面的步骤。

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

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

不久之前,我已开始研究rtmixer模块,该模块可用于第二个选项。 请注意,这是在非常早期的发展状态,所以谨慎使用它。 使用此模块,您不必编写回调函数,可以使用功能rtmixer.Mixer.play_buffer()在指定的时间(以秒为单位)播放音频缓冲区。作为参考,您可以从rtmixer.Mixer.time获得当前时间。 “

+0

非常好的答案!谢谢!我接近了同样的想法:从“播放声音事件”循环线程发送时间戳,音频回调将在“混音线程”中使用,并具有适当的位置。我一定会使用'sounddevice',我已经用于我的项目http://www.samplerbox.org!谢谢 – Basj

+0

很酷的东西,我印象深刻! – Matthias

+0

Re @Matthias,'rtmixer'在C或Cython(不是cpython,而是cython)中进行实际的混音/求和来加速它?这是我如何做SamplerBox混合([见这里](https://github.com/josephernest/SamplerBox/blob/master/samplerbox_audio.pyx)),我想知道你是否也注意到混合数学部分一种编译语言也大大提高了你的性能。 – Basj