2012-08-08 41 views
2


我正在該服務器上編寫客戶端/服務器應用程序,發送捕獲從某些外部設備(例如話筒)捕獲的音頻樣本並將其發送給客戶端的實時音頻數據。然後客戶想要播放這些樣本。我的應用程序將運行在本地網絡,所以我沒有帶寬問題(我的聲音是8K,8位立體聲,而我的網卡1000Mb)。在客戶端,我緩衝數據一段時間,然後開始播放。並且當數據從服務器到達時,我將它們發送到聲卡。這似乎工作正常,但有一個問題:
當我在客戶端的緩衝區完成後,我會體驗播放聲音的差距。
我認爲這是因爲服務器和客戶端的採樣時間不同,這意味着服務器上的8K與客戶端上的8K不一樣。
我可以通過暫停客戶端的播放和緩衝來解決這個問題,但是我的老闆不接受它,因爲我有適當的帶寬,我應該能夠播放聲音,沒有間隙或暫停。
所以我決定動態地改變客戶端的播放速度,但我不知道如何。
現場網絡音頻樣本的流暢播放

我在Windows中編程(本機),我目前使用waveOutXXX來播放聲音。我可以使用任何其他本地庫(DirectX/DirectSound,Jack或...),但它們應該在客戶端提供流暢的播放。

我與waveOutXXX多次編程,沒有任何問題,我知道它好,但我解決不了我的動態重採樣

+0

另外,網絡數據緩衝也可能會產生影響,使得網絡堆棧首先嚐試預緩衝數據(以便更有效地以更大的塊形式發送),從而導致罕見地發送小塊數據和間隙在接收方。 – 2012-08-08 14:53:56

+0

這是一個很好的說明,但由於我有一個連續的數據(每秒16K)是否真的影響網絡的緩衝?並且我緩衝了1秒鐘的數據,所以指定的問題不應該是可以在我的回放系統中產生空隙的東西 – BigBoss 2012-08-09 20:23:57

+0

我認爲最好的做法是做一個測試,看看發生了什麼。 – 2012-08-09 20:27:29

回答

1

我建議你的問題不太可能是由於錯誤的採樣率,但與你的緩衝有關。你應該不斷地將數據轉儲到聲卡上,並不斷填充緩衝區。使用合理的緩衝區大小......對於大多數應用程序來說,300ms就足夠了。

現在,在很長一段時間內,記錄端的時鐘和播放端的時鐘可能會漂移得足夠遠,以至於300ms的緩衝區已經不夠用了。我會建議,不要重新採樣這樣一個可能會引入僞像的小差異,只需在編碼端添加樣本即可。你仍然可以以8kHz記錄,但你可能會每秒鐘增加一個或兩個樣本,以達到8.001kHz左右。簡單地將現有樣本中的一個樣本加倍(甚至是一個樣本與下一個樣本之間的簡單平均值)將不會被聽到。根據您的應用需要進行調整。

+0

感謝Brad對你的迴應。但我使用了一個不是300毫秒的1秒緩衝區,而且我仍然有問題。我說我已經播放了很多波形文件,沒有任何問題,所以我知道我應該在哪裏添加緩衝區,但是在播放的一面添加一個或多個樣本的想法看起來很有道理。如果玩邊比錄音邊快,我該怎麼辦?以及爲什麼我有這麼大的緩衝區(1秒)的錯誤 – BigBoss 2012-08-09 20:17:04

+0

@BigBoss,我認爲這個問題不是專門緩衝,而是在你的代碼或方法中有錯誤。您需要生成穩定的數據流才能發送到聲卡,就好像您正在播放一個長WAV文件一樣。您不能發送一個緩衝區,然後再發送另一個緩衝區,然後發送另一個您需要編程連接這些緩衝區並穩定地將它們發送到聲卡的緩衝區。添加樣本可以修復播放端比錄製端更快的問題。如果你添加了太多的樣本,你可以做相反的事情。遠程緩衝區上的遙測將很有用。 – Brad 2012-08-09 20:22:56

+0

讓我解釋一下我的程序。我從我的服務器接收數據。我會將它分成固定的聲音塊並緩衝它們長達1秒,然後開始播放,將所有準備好的波形標題寫入聲卡,然後在從服務器接收到數據時,數據的大小與我的一樣多固定長度,我添加一個新的緩衝區聲卡(如果我有一個返回的波頭)或我下次緩衝數據窗口通知我的WOM_DONE。 – BigBoss 2012-08-09 20:32:22

1

我在我的工作中的應用程序也有類似的問題的問題。它不涉及網絡,但它確實涉及以某個固定採樣率實時捕獲源數據,進行大量信號處理,最終以固定速率輸出到聲卡。和你一樣,我在緩衝區邊界處的回放中存在間隙。

在我看來,問題是處理正在完成導致音頻數據以非常生澀的方式進入聲卡。也就是說,它會得到一個大塊,然後它會有很長一段時間纔得到另一塊。整體吞吐量是正確的,但是這種延遲導致聲卡經常被餓死以獲取數據。我想你可能與你的系統中的網絡部分有相同的情況。

我解決這個問題的方法是先讓音頻緩衝區變長。然後,每當收到一個新的音頻塊時,我檢查了緩衝區是多麼充分。如果它還不到20%,我會寫一些沉默,使其達到60%左右。

您可能認爲這樣做有損減少播放差距,因爲它實際上增加了間隙,但實際上它有幫助。我遇到的問題是,即使我有一個非常大的音頻緩衝區,我總是處於空閒的邊緣。由於系統中存在其他延遲,這導致幾乎每個緩衝區都存在播放間隙。

當緩衝區開始變空時,但在實際執行之前寫入靜音,以確保緩衝區總是有一些數據可用,以便處理稍後。而且,與許多週期性間隙相比,播放中的單個小間隙很難被注意到。

我不知道這是否適用於您,但它應該很容易實施並嘗試。

+0

正如你所說,易於實施和測試,我會明天檢查它並讓你知道結果 – BigBoss 2012-08-09 20:26:40