2017-05-23 43 views
0

我想編寫一個程序,該程序允許我使用計算機鍵盤播放示例聲音,而且幾乎沒有延遲。使用聲音設備模塊從命令行播放聲音樣本時的等待時間過長

我的程序:

import numpy as np 
import sounddevice as sd 
import soundfile as sf 
import msvcrt 

sd.default.latency = 'low' 

samplesarray = [] 

def load_samples(num): 
    filename='sample'+str(num)+'.wav' 
    data, fs = sf.read(filename, dtype='float32') 
    sd.default.samplerate = fs 
    samplesarray.append(data) 
    return 

numberofsamples=3 

for i in range(numberofsamples):  
    load_samples(i+1) 

def play_session(): 
    while 0==0: 
     key = int(msvcrt.getch()) 
     sd.play(samplesarray[key-1]) 
    return 

play_session() 

程序文件夾中包含一個編號命名sample1.wav,sample2.wav等「一個炮打響」短樣本,例如踢鼓或圈套。在這個例子中,爲了簡單,只有三個被加載。 我可以在終端中啓動我當前的程序,並在我的鍵上播放樣本「映射」,這正是我想要的。 唯一的問題是延遲:雖然不是很大,但它是明顯的。

對於實時播放樣本,理想的延遲應該幾乎不可察覺(數十毫秒的順序)。

我怎麼能做到這一點?

+0

你可能是指*毫秒*秒? – Matthias

回答

0

在其他幾件事情中,可能的最低延遲取決於您使用的主機API。由於您正在導入msvcrt模塊,因此我假設您使用Windows,對吧?

在那裏,您通常可以選擇多個主機API。 WASAPI,WDM/KS或ASIO通常可以達到最低的延遲。

如果您使用WASAPI,您可以嘗試exclusive mode,這可能會允許更低的延遲,但我不確定。

設置latency'low'(如你所做的)應該這樣做,但是您也可以嘗試使用blocksize的不同值。但請注意,太小的塊大小會導致緩衝區下溢,這可能會導致可聽見的點擊。最後,如果你真的想擠掉設置中的最後一個等待時間,你應該去掉sd.play()(每次調用時都會打開一個新的sd.OutputStream),而是在你自己的回調函數中實現你的回放邏輯。

+0

謝謝。我在程序開始時加入了'wasapi_exclusive = sd.WasapiSettings(exclusive = True)'和'sd.default.extra_settings = wasapi_exclusive'。如果我不調用函數'play_session()'它運行得很好,但是如果我嘗試調用它,就會得到「sounddevice.PortAudioError:打開OutputStream:不兼容的主機API特定流信息時出錯」。我試圖谷歌解決方案無濟於事。建議? – skyfish

+0

@skyfish你真的使用WASAPI設備嗎?如果是的話,你的錯誤聽起來類似於https://github.com/spatialaudio/python-sounddevice/issues/35。如果您*不使用'extra_settings',延遲如何? – Matthias