2010-11-25 12 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のWebサイトから取得します。 私はここで何が欠けているのか分かりません。

+0

speexは非可逆コーデックです。より良い圧縮を実現するために情報が不足しているため、結果のストリームは元のものとは異なります。 –

+1

@Paulo Scardine正弦波の値を持つ配列をエンコードすると、20〜最初の浮動小数点(一度デコードされた)はすべて0になります。それは損失が多いことがわかりますが、データの大部分が失われています。私はまた、いくつかの正の価値を持っているいくつかのネガティブな価値を得る。 – dotminic

+0

は、符号付き/符号なしのデータ型の問題のようです。 –

答えて

1

コード化されたデータが非常に異なる理由が見つかりました。 Paulo Scardine氏によると、Speexは160フレームでしか動作しないため、PortaudioからSpeexにデータを取得する場合、160フレームの「パケット」である必要があります。

+1

160フレームはどういう意味ですか?フレームには、短い160バイトまたは320バイトが正しく含まれている必要がありますか? – guness

+0

Framesizeは、常にサンプルのデコードされたデータフレームサイズを指します。フレームサイズは、エンコードモードに依存します 狭帯域(8kHz):framesize = 160 samples = 320 bytes of PCM Wideband(16kHz):framesize = 320 samples = 640 bytes of PCM Ultra Wideband(32kHz):framesize = 640 samples = 1280バイトのPCM –

0

あなたは、いくつかの簡単なエンコーディング/デコーディングのためにここを見てしたいことがあります。 http://www.speex.org/docs/manual/speex-manual/node13.html#SECTION001310000000000000000

あなたはUDPを使用しているので、あなたも、パケットやものの再オーダーにジッタバッファでも動作します。

+0

私はそのリンクを見ましたが、まだ、ジッタバッファを使用していません。なぜなら、1つのパケットをエンコード/送信/デコード/再生することができないからです。私はこの上に私の髪を引っ張っている! – dotminic

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で初期化されているので、あなたが「ゼロに近い」ことを最初の数のサンプルを観察します。

タイミングを正しく取得するには、コーデックに入力した実際のオーディオデータを取得する前に、それらのサンプルをスキップする必要があります。なぜそれは、私は知らない。 Speexはストリーミング用であり、主にオーディオデータの保存と復元を目的としたものではないため、Spalexの作者Probalbyはこれを気にしませんでした。 スペースを浪費しないようにするもう1つの回避策は、実際のオーディオデータを入力して最初のspeexフレーム全体をドロップする前に、コーデックに(フレームサイズ遅延)ゼロを送ります。

これがすべてを明確にすることを願っています。 Speexに精通している人がこれを読んでくれたら、私が間違っていれば私を修正してください。

EDIT:実際には、デコーダとエンコーダの両方に先読み時間があります。遅延の実際の式は次のとおりです。

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 
関連する問題