线程上的Python Sounddevice.play()
我在线程上播放sounddevice时遇到一些问题。我在开始时将sounddevice作为sd导入。然后在运行期间,我想使用ASIO声卡在线程上播放音调。我需要在线程上执行的所有配置都运行良好。但是,当我想播放该音调时,出现以下错误: sounddevice.PortAudioError:打开OutputStream时出错:意外的主机API 2错误0:u“加载ASIO驱动程序失败” 如果每次需要时都在线程处初始化导入,它就会工作。但我当然不想那样做。有什么办法解决这个问题吗 谢谢 下面是一个简单的代码示例:线程上的Python Sounddevice.play(),python,multithreading,python-sounddevice,Python,Multithreading,Python Sounddevice,我在线程上播放sounddevice时遇到一些问题。我在开始时将sounddevice作为sd导入。然后在运行期间,我想使用ASIO声卡在线程上播放音调。我需要在线程上执行的所有配置都运行良好。但是,当我想播放该音调时,出现以下错误: sounddevice.PortAudioError:打开OutputStream时出错:意外的主机API 2错误0:u“加载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()
这似乎是一个特定于平台的问题。我刚刚在ALSA/Linux上试用过,效果很好。使用ASIO,您可能必须在稍后用于创建流的同一线程中进行库初始化(在
import
期间发生)(这是play()
为您做的)
如果每次需要时都在线程处初始化导入,它就会工作。但我当然不想那样做
你为什么不想那样做?您知道Python中的import
的使用是自动缓存的吗?第二次使用import
时,只执行dict
查找,而不执行其他操作
但是你是对的,重复的导入
看起来仍然有点奇怪。
您是否在测试中仅尝试了一次导入?您还可以在那里执行所有的sd.default
操作
如果在初始化过程中仍然存在问题(或者如果坚持将所有导入都放在顶部),可以尝试使用未记录的\u initialize()
和\u terminate()
函数,请参阅
如果要使用多个线程
实例,则play()
函数将出现问题,该函数用于单线程使用。但无论如何,只有一个Python线程进行音频I/O可能更有意义
顺便说一句,您不需要(…).astype(np.float32)
,这个转换是自动为您完成的
当我在做这件事时,如果默认的输入和输出设备不同,您的线路sd.query\u devices(sd.default.device)['name']
将中断。这似乎是一个特定于平台的问题。我刚刚在ALSA/Linux上试用过,效果很好。使用ASIO,您可能必须在稍后用于创建流的同一线程中进行库初始化(在import
期间发生)(这是play()
为您做的)
如果每次需要时都在线程处初始化导入,它就会工作。但我当然不想那样做
你为什么不想那样做?您知道Python中的import
的使用是自动缓存的吗?第二次使用import
时,只执行dict
查找,而不执行其他操作
但是你是对的,重复的导入
看起来仍然有点奇怪。
您是否在测试中仅尝试了一次导入?您还可以在那里执行所有的sd.default
操作
如果在初始化过程中仍然存在问题(或者如果坚持将所有导入都放在顶部),可以尝试使用未记录的\u initialize()
和\u terminate()
函数,请参阅
如果要使用多个线程
实例,则play()
函数将出现问题,该函数用于单线程使用。但无论如何,只有一个Python线程进行音频I/O可能更有意义
顺便说一句,您不需要(…).astype(np.float32)
,这个转换是自动为您完成的
当我使用时,如果默认的输入和输出设备不同,您的线路sd.query\u devices(sd.default.device)['name']
将中断。请提供一个示例。@Matthias我出于好奇添加了示例代码,您使用多线程的用例是什么?请提供一个。@Matthias我添加的示例代码只是出于好奇,您使用多线程的用例是什么?