我正在尝试在Raspberry Pi上制作一个非常简单的节拍器,该Raspberry Pi会按设定的时间间隔播放.wav文件,但是时间上听上不准确。 我真的不知道为什么,python的时间模块不准确吗?
我认为处理音频的代码不是瓶颈,因为如果我将其放入没有计时器的循环中,它将始终发出嘎嘎声。 使用下面的简单代码,声音将在节拍上播放几次,然后一遍一遍地随机关闭一个节拍。
import pygame
from time import sleep
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.mixer.init()
pygame.init()
BPM = 160
sound = pygame.mixer.Sound('sounds/hihat1.wav')
while True:
sound.play()
sleep(60/BPM)
我希望使声音每X毫秒重复一次,精度至少为+/- 10ms左右。那不现实吗?如果是这样,请提出一个替代方案。
答案 0 :(得分:3)
事实证明,问题是使用了太大的块,这可能导致pygame延迟播放声音,因为之前的块已经排队。我的第一个建议是,我希望OP的代码会随着时间的推移而缓慢漂移,这表明这样的做法会更好:
import pygame
from time import time, sleep
import gc
pygame.mixer.pre_init(44100, -16, 2, 256)
pygame.mixer.init()
pygame.init()
BPM = 160
DELTA = 60/BPM
sound = pygame.mixer.Sound('sounds/hihat1.wav')
goal = time()
while True:
print(time() - goal)
sound.play()
goal += DELTA
gc.collect()
sleep(goal - time())
即跟踪“当前时间”,并根据经过的时间调整sleep
。我会在每次睡觉之前明确执行“垃圾收集”(即gc.collect()
),以使事情更具确定性。
答案 1 :(得分:1)
当我在本地计算机上测试您的代码时,睡眠似乎并不在乎pygame线程,因此您的声音会相互重叠。
此外,我认为您应该使用pygames自己的计时器来延迟动作。
您可以在py上尝试以下代码吗?
import pygame
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.mixer.init()
pygame.init()
BPM = 160
sound = pygame.mixer.Sound('sounds/hihat1.wav')
while True:
sound.play()
pygame.time.delay(int(sound.get_length()*1000))
pygame.time.delay(int(60/BPM*1000))