0

几天前,我在 Python 2.7.5 中安装了一个 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 时,我们都会在哔声信号之前听到短暂的延迟。有没有可能消除它?如果没有,任何其他允许实时播放没有延迟的声音流的库?

4

1 回答 1

1

您可以使用sounddevice.default.latency指定所需的延迟。但是请注意,这是建议的延迟,实际延迟可能会有所不同,具体取决于硬件,也可能取决于主机 API。您可以使用sounddevice.Stream.latency估算实际延迟。

默认情况下,该sounddevice模块使用 PortAudio 的延迟设置,以期提供更强大的行为。您可以将其切换到 PortAudio 的设置,或者您可以尝试任何您想要的数值(以秒为单位)。

import sounddevice as sd
sd.default.latency = 'low'

或者,您当然也可以使用等latency参数。play()

如果您想更好地控制时间,您可能需要编写自己的自定义回调函数。在那里你可以使用time参数,在回调函数之外你可以使用sounddevice.Stream.time

您也可以尝试在不使用callback参数的情况下启动流,然后在其上使用sounddevice.Stream.write()。我不知道这会对延迟产生什么影响,但可能值得一试。

关于其他库,由于您似乎已经在使用 PyGame,您也可以将它用于音频输出。它可能有也可能没有不同的延迟。

顺便说一句,我不知道您的代码是否是线程安全的,因为您正在操作数组,而回调将内存地址提供给 PortAudio。像这样实现它可能不是一个好主意。

于 2016-10-13T22:06:21.830 回答