2016-10-12 14 views
0

Несколько дней назад я установил библиотеку a sounddevice в Python 2.7.5. Я пытаюсь создать звуковой массив и добавить к нему некоторые эффекты сразу после нажатия клавиши на моем MIDI-контроллере. Но я получаю огромную задержку 0,1 до 0,2 вторых, что делает мой код бесполезен:Слишком высокая латентность при попытке манипулировать звуковыми массивами с использованием звукового оборудования в python

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() здесь (введите «input()» в Python 3.x) вместо MIDI-входов, которые можно было бы использовать с помощью библиотеки Pygame. Мой код работает, но каждый раз, когда мы нажимаем ENTER, мы слышим короткую задержку перед сигналом. Можно ли его устранить? Если нет, то есть другие библиотеки, позволяющие воспроизводить звуковой поток без каких-либо задержек?

ответ

0

Вы можете указать желаемую задержку с помощью sounddevice.default.latency. Обратите внимание, однако, что это предложил задержка, фактическая задержка может быть различной, в зависимости от аппаратного обеспечения и, вероятно, также от API-интерфейса хоста. Вы можете получить оценку фактической задержки с помощью sounddevice.Stream.latency.

По умолчанию в модуле sounddevice используется параметр задержки PostAudio высокой частоты в надежде обеспечить более надежное поведение. Вы можете переключить его на параметр PortAudio с низким, или вы можете попробовать любое числовое значение (в секундах), которое вы хотите.

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

В качестве альтернативы, вы можете, конечно, также использовать latency аргумент play() и т.д.

Если вы хотите иметь больше контроля над временем, вы можете написать свою собственную пользовательскую функцию обратного вызова. Там вы можете использовать аргумент time, а вне функции обратного вызова вы можете использовать sounddevice.Stream.time.

Вы также можете попробовать запустить поток без использования аргумента callback, а затем использовать sounddevice.Stream.write(). Я не знаю, что это будет делать с задержкой, но, возможно, стоит попробовать.

Что касается других библиотек, поскольку вы, кажется, уже используете PyGame, вы также можете использовать его для вывода звука. Это может иметь или не иметь другую задержку.

BTW, я не знаю, является ли ваш код потокобезопасным, так как вы управляете массивом, в то время как обратный вызов дает адреса памяти PortAudio. Вероятно, это не очень хорошая идея.

 Смежные вопросы

  • Нет связанных вопросов^_^