Python Sounddevice.play() в темах
У меня возникли проблемы с воспроизведением звукового устройства в потоке. Я импортирую звуковое устройство как sd в начале. Затем во время работы я хочу воспроизвести тон на нити, используя звуковую карту ASIO. Все конфигурации, которые мне нужно сделать в потоке, работают хорошо. Однако, когда я хочу воспроизвести звук, я получил следующую ошибку:
sounddevice.PortAudioError: Ошибка открытия OutputStream: непредвиденная ошибка API хоста 2: 0: "Не удалось загрузить драйвер ASIO"
Если я инициализирую импорт в потоке каждый раз, когда мне это нужно, он работает. Но, конечно, я не хочу этого делать. Любая идея горячая, чтобы решить это?
Спасибо!
Вот простой пример кода:
from threading import Thread
import numpy as np
import sounddevice as sd
class Test(Thread):
def __init__(self):
Thread.__init__(self)
#-- Configuration of the Tone to be played
self.fs = 44100 # sampling rate, in Hz, 44100 or 48000
duration = 1.05 # in seconds, may be float
f = 200.0 # sine frequency, Hz, may be float
self.tone_data = (np.sin(2*np.pi*np.arange(self.fs*duration)*f/self.fs)).astype(np.float32)
def run(self):
#-- Configuration of the ASIO sound card
#import sounddevice as sd
sd.default.channels = 2
sd.default.device = 14
print sd.query_devices(sd.default.device)['name']
#sd.default.latency = ('low','low')
#asio_out = sd.AsioSettings(channel_selectors=[1, 2])
#sd.default.extra_settings = asio_out
sd.default.samplerate = self.fs
sd.play(self.tone_data)
sd.wait()
w = Test()
w.start()
1 ответ
Кажется, это проблема для конкретной платформы. Я только что попробовал это с ALSA/Linux, и он отлично работает. С ASIO вам, вероятно, придется выполнить инициализацию библиотеки (что происходит во время import
время) в том же потоке, который вы используете позже, чтобы создать поток (который play()
делает для вас)?
Если я инициализирую импорт в потоке каждый раз, когда мне это нужно, он работает. Но, конечно, я не хочу этого делать.
Почему ты не хочешь этого делать? Знаете ли вы, что использование import
в Python кешируется автоматически? Второй раз вы используете import
только dict
поиск сделан и больше ничего.
Но ты прав, повторил import
все еще выглядит немного странно. Вы пытались сделать import
только один раз в Test.__init__()
? Там вы также можете сделать все sd.default
вещи.
Если у вас все еще есть проблемы во время инициализации (или если вы настаиваете на том, чтобы весь импорт был сверху), вы можете попробовать использовать недокументированный _initialize()
а также _terminate()
функции, см. выпуск № 3.
Если вы хотите использовать несколько Thread
случаи, вы получите проблемы с play()
функция, которая предназначена для однопоточного использования. Но в любом случае, вероятно, имеет смысл иметь только один поток Python, который выполняет аудио-ввод-вывод. Смотрите также PortAudio Tips - Threading.
Кстати, вам не нужно (...).astype(np.float32)
Это преобразование выполняется автоматически для вас.
И пока я на этом, ваша линия sd.query_devices(sd.default.device)['name']
сломается, если устройства ввода и вывода по умолчанию отличаются.