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'] сломается, если устройства ввода и вывода по умолчанию отличаются.

Другие вопросы по тегам