2016-10-04 181 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']將會中斷。