1

我在线程上播放声音设备时遇到了一些问题。我在开始时将声音设备导入为 sd。然后在运行期间,我想使用 ASIO 声卡在线程上播放音调。我需要在线程上进行的所有配置都运行良好。但是,当我想播放音调时,出现以下错误:

sounddevice.PortAudioError: Error opening OutputStream: Unexpected host API 2 error 0: u'Failed to load ASIO driver'

如果我每次需要时都在线程上初始化导入,它就可以工作。但我当然不想那样做。有什么想法可以解决吗?

谢谢!

这里有一个简单的代码示例:

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()
4

1 回答 1

0

这似乎是一个特定于平台的问题。我刚刚用 ALSA/Linux 试了一下,效果很好。使用 ASIO,您可能必须在import稍后用于创建流的同一线程中进行库初始化(在时间期间发生)(这play()对您有用)?

如果我每次需要时都在线程上初始化导入,它就可以工作。但我当然不想那样做。

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

但你是对的,重复的看起来import还是有点奇怪。您是否尝试过只做一次?在那里你也可以做所有的事情。importTest.__init__()sd.default

如果您在初始化过程中仍然遇到问题(或者如果您坚持将所有导入都放在顶部),您可以尝试使用未记录的_initialize()_terminate()功能,请参阅问题 #3

如果你想使用多个Thread实例,你会遇到这个play()函数的问题,它是为单线程使用而设计的。但无论如何,只有一个 Python 线程来执行音频 I/O 可能更有意义。另请参阅PortAudio 技巧 - 线程

顺便说一句,您不需要(...).astype(np.float32),此转换会自动为您完成。

当我这样做时,sd.query_devices(sd.default.device)['name']如果默认输入和输出设备不同,您的线路将会中断。

于 2016-10-14T14:21:10.113 回答