2010-11-25 80 views
2

我正在使用speex編碼一些音頻數據並通過UDP發送,並在另一側解碼。 我用speex進行了一些測試,發現如果我在對它進行編碼後直接對數據包進行解碼,解碼後的數據絕不會接近原始數據。緩衝區開始處的大部分字節爲0. 因此,當我解碼通過UDP發送的音頻時,我所得到的只是噪聲。 這是怎麼了編碼音頻:speex解碼出錯

bool AudioEncoder::encode(float *raw, char *encoded_bits) 
{ 
    for (size_t i = 0; i < 256; i++) 
     this->_rfdata[i] = raw[i]; 
    speex_bits_reset(&this->_bits); 
    speex_encode(this->_state, this->_rfdata, &this->_bits); 
    int bytesWritten = speex_bits_write(&this->_bits, encoded_bits, 512); 
    if (bytesWritten) 
     return true; 
    return false; 
} 

這是怎麼了解碼音頻:

float *f = new float[256]; 
// recvbuf is the buffer I pass to my recv function on the socket 
speex_bits_read_from(&this->_bits, recvbuf, 512); 
speex_decode(this->state, &this->_bits, f); 

我已經簽出文檔,以及我的大多數代碼來自例子編碼/解碼來自speex網站的樣本。 我不知道我在這裏錯過了什麼。

+0

的Speex是一個有損編解碼器,所產生的流將是從原始的不同,因爲爲了你鬆散信息來實現更好的壓縮。 – 2010-11-25 18:23:11

+1

@Paulo Scardine如果我使用正弦波值對數組進行編碼,則20〜1個浮點數(一旦解碼)全部等於0。我知道這是有損的,但是我失去了大部分數據。如果我有一些正面價值,我也會得到一些負值。 – dotminic 2010-11-25 18:33:13

+0

看起來像一個簽名/未簽名的數據類型問題。 – 2010-11-25 19:24:08

回答

1

我發現編碼數據如此不同的原因。事實上這是Paulo Scardine說的有損壓縮,而且speex只能處理160幀,所以從portaudio到speex的數據時,它需要160幀的「數據包」。

1

其實講引入了額外的延遲音頻數據,我發現通過反向enginiering:

narrow band : delay = 200 - framesize + lookahead = 200 - 160 + 40 = 80 samples 

wide band : delay = 400 - framesize + lookahead = 400 - 320 + 143 = 223 samples 

uwide band : delay = 800 - framesize + lookahead = 800 - 640 + 349 = 509 samples 

由於先行與zereos初始化,您觀察到的前幾個樣品是「接近零」 。

爲了獲得正確的時間,您必須先跳過這些樣本,然後才能獲得您已編入編解碼器的實際音頻數據。爲什麼是這樣,我不知道。 Propelby的作者從來不關心這個問題,因爲speex是用於流式傳輸,主要不是用於存儲和恢復音頻數據。 另一個解決方法(不浪費空間)是,在饋送實際音頻數據之前,您將(幀大小延遲)零進入編解碼器,然後丟棄整個第一個speex幀。

我希望這能夠澄清一切。如果熟悉斯佩克斯的人閱讀此文,請隨時糾正我,如果我錯了。

編輯:其實,解碼器和編碼器都有前瞻時間。延遲的實際計算公式爲:

narrow band : delay = decoder_lh + encoder_lh = 40 + 40 = 80 samples 

wide band : delay = decoder_lh + encoder_lh = 80 + 143 = 223 samples 

uwide band : delay = decoder_lh + encoder_lh = 160 + 349 = 509 samples