2016-10-04 180 views
0

我在线程上播放声音设备时遇到了一些问题。我在开始时将音频设备作为sd导入。然后在运行期间,我想用ASIO声卡在线程上播放音调。我需要在线程上完成的所有配置都运行良好。然而,当我想玩的语气我得到了以下错误:线程上的Python Sounddevice.play()

sounddevice.PortAudioError:错误打开的OutputStream:未预料到的主机API 2错误0:u'Failed加载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() 
+0

请提供[MCVE](http://stackoverflow.com/help/mcve)。 – Matthias

+0

@Matthias我加了,示例代码 – Laura

+0

出于好奇,你使用多线程的用例是什么? – Matthias

回答

0

这似乎是一个特定于平台的问题。我刚刚尝试过使用ALSA/Linux,它工作正常。使用ASIO,您可能必须在稍后用于创建流的相同线程中执行库初始化(发生在import时间)(您可以使用哪一个play())?

If I initialize the import at the thread everytime I need it, it work. But of course I do not want to do that.

为什么你不想那么做?你知道在Python中使用import会自动缓存吗?第二次使用import时,只有dict查找完成,没有别的。

但你说的对,import仍然看起来有点奇怪。 您是否尝试在Test.__init__()中仅使用import一次?在那里你也可以做所有的sd.default的东西。

如果您仍然有初始化过程中出现问题(或者,如果你坚持有在顶部全部进口),你可以尝试使用无证_initialize()_terminate()功能,见issue #3

如果您想使用多个Thread实例,您将遇到play()函数的问题,该函数用于单线程使用。但无论如何,只有一个执行音频I/O的Python线程可能更有意义。另请参阅PortAudio Tips – Threading

顺便说一句,你不需要(...).astype(np.float32),这个转换是为你自动完成的。

虽然我在这里,但如果默认输入和输出设备不同,您的行sd.query_devices(sd.default.device)['name']将会中断。