我目前尝试每 x 毫秒重复一次声音 - 其中 x 取决于我通过套接字收到的 UDP 数据包 - 我决定使用 pygame 来实现这一点。我用这个答案每 x 毫秒重复一次:https://stackoverflow.com/a/18954902/3475778 https://stackoverflow.com/a/18954902/3475778
但现在我遇到了问题,声音播放得很不规则,并做了一个最小工作示例,问题仍然存在:
import pygame
from pygame.locals import *
pygame.mixer.init()
sound = pygame.mixer.Sound('sound.wav')
def play_sound():
sound.stop()
sound.play()
pygame.init()
clock = pygame.time.Clock()
pygame.time.set_timer(USEREVENT+1, 200)
while True:
# clock.tick(30)
for event in pygame.event.get():
if event.type == USEREVENT+1:
play_sound()
以下是我通过 Audacity 从脚本中记录的波形:
您会看到,由于某种原因,某些样本的播放时间比其他样本长。对于我想要构建的某种节拍器来说不太好。
编辑更新:
不是pygame.time.set_timer的问题,因为这段代码没有解决问题,也不依赖pygame.time.set_timer:
import pygame
from datetime import datetime
d = datetime.now()
pygame.mixer.init()
sound = pygame.mixer.Sound('horn_short.wav')
pygame.init()
while True:
if (datetime.now() - d).total_seconds() > 0.2:
sound.play()
d = datetime.now()
有同样的问题。该问题也在 Ubuntu 16.04、Python 3.5 64bit (Anaconda) 和新安装的 pygame 下出现。
这是一种替代方法的想法。
如果目标是定期播放声音,
如果您(动态)将声音填充到所需的间隔长度,您可能会得到更好的结果,
然后简单地循环它Sound.play(loops=-1) http://pygame.org/docs/ref/mixer.html#pygame.mixer.Sound.play.
如果只有少数有效间隔,则可能最容易
存储专用声音文件并加载适当的文件。
否则,pygame.sndarray http://pygame.org/docs/ref/sndarray.html模块提供对
Anumpy http://www.numpy.org/原始声音数据的数组,这使得
动态生成所需长度的声音对象:
import pygame
import numpy
# Helper function
def getResizedSound(sound, seconds):
frequency, bits, channels = pygame.mixer.get_init()
# Determine silence value
silence = 0 if bits < 0 else (2**bits / 2) - 1
# Get raw sample array of original sound
oldArray = pygame.sndarray.array(sound)
# Create silent sample array with desired length
newSampleCount = int(seconds * frequency)
newShape = (newSampleCount,) + oldArray.shape[1:]
newArray = numpy.full(newShape, silence, dtype=oldArray.dtype)
# Copy original sound to the beginning of the
# silent array, clipping the sound if it is longer
newArray[:oldArray.shape[0]] = oldArray[:newArray.shape[0]]
return pygame.mixer.Sound(newArray)
pygame.mixer.init()
pygame.init()
sound = pygame.mixer.Sound('sound.wav')
resizedSound = getResizedSound(sound, 0.2)
resizedSound.play(loops=-1)
while True:
pass
仅使用 pygame (和 numpy),这种方法应该有很好的机会进行准确的播放。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)