几天前,我在Python 2.7.5中安装了a sounddevice库。我正在尝试制作一个声音数组,并在我按下MIDI控制器上的键后立即添加一些效果。但是我得到0.1到0.2秒的巨大延迟,这使我的代码无用:
import numpy as np
import sounddevice as sd
import time
import math
#we're making a sound array with a 5 seconds length noisy sound and playing it:
duration=5
framerate = 44100
array=0.02*np.random.uniform(-1, 1, framerate*duration)
sd.play(array, framerate)
t=time.time()
while(True):
signal=raw_input("push ENTER to hear a beep")
start_iter=int(framerate*(time.time()-t))
end_iter=min(start_iter+framerate/4, len(array))
#we're trying to change our data array and play a beep signal of 0.25 second after each ENTER press instantly
for i in range(start_iter, end_iter):
array[i]=0.05*math.sin(440*2*math.pi*i/44100.)
if end_iter==len(array): break #safe exit of a process after 5 seconds has passed
为了保持简单,我的声音阵列只是一个嘈杂的声音,我的效果是440Hz的哔哔声。我在这里使用了raw_input()(在Python 3.x中输入“input()”)而不是使用Pygame库可以实现的MIDI输入。我的代码有效,但每次按ENTER键,我们都会听到哔声信号前的短暂延迟。 有可能消除它吗?如果没有,任何其他图书馆允许播放没有延迟的声音流?
答案 0 :(得分:0)
您可以使用sounddevice.default.latency指定所需的延迟。但请注意,这是建议的延迟,实际延迟可能会有所不同,具体取决于硬件,也可能取决于主机API。您可以使用sounddevice.Stream.latency估算实际延迟。
默认情况下,sounddevice
模块使用PortAudio的高延迟设置,希望提供更强大的行为。您可以将其切换到PortAudio的 low 设置,或者您可以尝试所需的任何数值(以秒为单位)。
import sounddevice as sd
sd.default.latency = 'low'
或者,您当然也可以使用latency
等play()
参数。
如果您想要更多地控制时间,您可能想要编写自己的自定义回调函数。在那里你可以使用time
参数,在回调函数之外你可以使用sounddevice.Stream.time。
您也可以尝试在不使用callback
参数的情况下启动流,然后在其上使用sounddevice.Stream.write()。我不知道这会对延迟产生什么作用,但值得一试。
关于其他库,因为您似乎已经在使用PyGame,所以您也可以将它用于音频输出。它可能会或可能不会有不同的延迟。
顺便说一句,我不知道你的代码是否是线程安全的,因为你在操作数组时回调给PortAudio提供了内存地址。像这样实现它可能不是一个好主意。