2013-01-12 73 views
0

WaveOut API是否對當前播放的緩衝區有一定的內部限制?我的意思是,如果我提供一個非常小的緩衝區,會不會影響揚聲器播放的聲音。當我生成並播放小緩衝區的竇性波時,我正在經歷非常奇怪的噪音。就像一個高峯,或「BUMP」。什麼是最小的音頻緩衝區,用於在沒有WaveOUT API的情況下產生音調聲音

完整的故事:

我做了一個程序,可以實時生成正弦聲音信號。 可變參數是頻率和音量。項目要求的最大延遲爲50毫秒。因此,該程序必須能夠實時產生手動調節音頻信號頻率的正弦信號。

我用Windows WaveOut API,C#和P/invoke來訪問API。

當聲音緩衝區大於1000毫秒時,一切正常。如果我根據延遲要求將緩衝區最小化到50毫秒,那麼對於某些頻率,我在每個緩衝區結束時都會遇到噪聲或「BUMP」。我不明白所產生的聲音是否格式錯誤(我檢查過,沒有),或者音頻芯片發生了什麼,或者初始化和播放有些延遲。

當我將製作的音頻保存爲.wav文件時,所有內容都是完美的。

這意味着必須是我的代碼中的一些錯誤,或者音頻子系統對發送給它的緩衝塊有限制。

對於那些不知道WaveOut必須在第一時間初始化,然後必須準備與每個緩衝區的音頻標題包含需要播放的字節數和指向包含需要成爲播放器的音頻。

UPDATE

噪聲發生與下列組合44100 SamplingRate,16個比特,2個通道,50毫秒緩衝液和產生的竇201Hz,202Hz,203Hz,204Hz,205Hz的音頻信號... 219Hz, 220Hz,240赫茲,是好的

爲什麼這個差異20,我不知道。

回答

2

有幾件事情要記住,當你需要輸出的音頻順利:

  • waveOutXxxx API是低級別的API之上的傳統/兼容層,因此它具有較大的開銷,是當您達到最小延遲時不推薦使用。請注意,這不太可能是您的主要問題,但這是有助於理解
  • 的常識,因爲Windows不是實時操作系統,其音頻子系統不是實時的,或者您無法控制涉及的隨機延遲你排隊音頻數據輸出和數據真正回放,關鍵是保持一定水平的緩衝區豐滿,它可以保護您從播放下溢,並提供流暢的播放
  • waveOutXxxx你不僅限於有單緩衝區,你可以分配多個可重複使用的緩衝區並回收它們

總而言之,waveOutXxxx,DirectSound,DirectShow APIs可以工作延遲時間爲50毫秒及以上。有了WASAPI專有模式流,你可以get 5 ms latencies and even lower

編輯:我似乎已經說過了大約20毫秒的延遲。爲了彌補這一點,這裏有一個簡單的工具LowLatencyWaveOutPlayWin32,x64)來估計你可以實現的延遲。有足夠的緩衝播放是平穩的,否則你會聽到口吃。

我的理解是,緩衝區可能會返回較晚,最小延遲方面的優化設計在於具有更小的緩衝區,以便儘早將它們返回。例如,10個緩衝區3 ms /緩衝區而不是3個緩衝區10 ms /緩衝區。

D:\>LowLatencyWaveOutPlay.exe 48000 10 3 
Format: 48000 Hz, 1 channels, 16 bits per sample 
Buffer Count: 10 
Buffer Length: 3 ms (288 bytes) 
Signal Frequency: 1000 Hz 
^C 
+0

謝謝羅馬。我不能更好地解釋,但我已經有兩個緩衝區,他們完美的工作。我的軟件有三個主線。一個是生產者,消費者和玩家線程。你所說的一切都是正確的,但我最終的目標是在Windows CE上運行實時操作系統的程序(至少可以這樣說)。我在Windows CE上使用.NET Compact Framework 3.5。首先,我想在Windows 7上創建一個工作解決方案,然後將其移植到Window CE 6.0 R3。爲了實現這一點,我需要使用像WaveOut API這樣的庫。 – Patrik

+0

另外。我有一個由生產者在一個線程中填充的緩衝區。消費者創建的第二個緩衝區,供玩家線程使用。玩家只不過是WaveOut API的包裝。 WaveOut包裝器在一個線程中工作,並從列表中逐個取出較小的緩衝區。所以在那個級別上永遠不會發生緩衝區耗盡。當我將緩衝區保存到wav文件時,這個波形是完美的。所以我認爲這個問題更深層次。 – Patrik

+0

順便說一下。我試過NAudio,我看到它也在使用WaveOut。我嘗試用小緩衝區來初始化它,結果更糟糕。 (當我說一個小緩衝區時,它實際上是小緩衝區x塊數) – Patrik

相關問題