2010-07-15 48 views
5

我試圖爲andriod開發的應用程序,記錄48Khz幀(PCM 16bits &單聲道)並將它們發送到網絡。此外,還有一個8Khz的輸入音頻流。因此,我收到8Khz採樣幀並播放它們(我的AudioTrack對象設置爲8Khz),但播放它們時,一切正常,但延遲很大。它需要大約3秒鐘,直到你聽到什麼。從8Khz到48Khz(Java/Android)的resample/upsample聲音幀

我認爲如果我將從8Khz接收的幀上採樣到48Khz並播放它們,將不會有如此巨大的播放延遲。實際上,當我以相同的速率錄製和播放幀時,延遲非常低。壞事是我被迫這樣做:發送到48Khz並接收到8Khz。

正如之前所解釋的,我試圖將聲音幀(16位PCM)從8Khz上採樣到48Khz。有誰知道Java中的任何例程/庫/ API嗎?

我知道關於上採樣謹慎信號的基礎知識,但我認爲要設計和實現我自己的FIR濾波器並將其與音頻流進行卷積....太方便了。另外,這是我的知識。

那麼......有沒有人可以幫助我呢?有人知道我可以使用Java中的任何庫/例程嗎?任何建議或替代品?

+4

@juergen,如果你要碰到一個老問題解決在「感謝先進的」錯別字,*至少*刪除這句話完全,如它是沒有價值的,並修復其他拼寫錯誤。 – 2015-04-17 01:22:43

回答

6

一個快速和骯髒的解決方案將是線性插值。由於你總是採樣六倍這很容易做到這一點很容易做到這一點很容易做到:

它有點像這樣(C代碼,未經測試,我沒有正確處理最後一次迭代,但它顯示我認爲的想法)。

void resample (short * output, short * input, int n) 
{ 
    // output ought to be 6 times as large as input (48000/8000). 

    int i; 
    for (i=0; i<n-1; i++) 
    { 
    output[i*6+0] = input[i]*6/6 + input[i+1]*0/6; 
    output[i*6+1] = input[i]*5/6 + input[i+1]*1/6; 
    output[i*6+2] = input[i]*4/6 + input[i+1]*2/6; 
    output[i*6+3] = input[i]*3/6 + input[i+1]*3/6; 
    output[i*6+4] = input[i]*2/6 + input[i+1]*4/6; 
    output[i*6+5] = input[i]*1/6 + input[i+1]*5/6; 
    } 

線性插值不會給你很好的音質,但它便宜又快捷。如果你願意,你可以使用三次插值來改善它。

如果你想要一個快速和高質量的重採樣,我建議你使用Android-NDK編譯一個類似libresample的c resampling庫,並使用JNI從java中調用它。這會快很多。編寫JNI代碼是大多數人避開的東西,但它很容易.. NDK有很多這方面的例子。

http://www.mega-nerd.com/SRC/index.html

2

線性插補引入僞像。有高質量的重採樣的Java庫(JSSRC)(http://jssrc.khadkevich.org/)。

代碼現在可以在Github上: https://github.com/hutm/JSSRC

+1

你救了我頭痛。 該網站鏈接到您已關閉,這裏是存檔https://web.archive.org/web/20130902203226/http://jssrc.khadkevich.org ,這裏是GitHub的倉庫.. https://開頭github.com/hutm/JSSRC – 2014-10-21 21:05:27