SPEEXデコードが間違っています
質問
SPEEXを使用して、いくつかのオーディオデータをエンコードし、UDPを介して送信し、反対側でデコードしています。 SPEEXでいくつかのテストを実行しましたが、エンコードした直後にパケットをデコードすると、デコードされたデータが元のデータに近いものではないことに気付きました。バッファの開始時のバイトのほとんどは0です。したがって、UDPを介して送信されたオーディオをデコードすると、ノイズだけです。これが私がオーディオをエンコードする方法です:
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サイトからサンプルをエンコード/デコードする例に由来しています。ここで何が欠けているのかわかりません。
解決
エンコードされたデータが非常に異なっている理由を見つけました。 Paulo Scardineが言ったように、それは喪失した圧縮であり、Speexは160フレームでのみ動作するため、PortaudioからSpeexにデータを取得する場合、160フレームの「パケット」である必要があります。
他のヒント
実際に話すことは、オーディオデータに追加の遅延を導入します。
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
LookaheadはZereosで初期化されるため、最初のいくつかのサンプルが「ゼロに近い」と観察します。
タイミングを正しくするには、コーデックに供給した実際のオーディオデータを取得する前に、これらのサンプルをスキップする必要があります。なぜそうなのか、私にはわかりません。 Speexは、主にオーディオデータの保存と復元のためではなく、Speexはストリーミング用であるため、Speexの著者はこれを気にしませんでした。別の回避策(スペースを無駄にしない)は、実際のオーディオデータにフィードしてから、最初の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
簡単なエンコード/デコードをご覧ください。http://www.spex.org/docs/manual/spex-manual/node13.html#section00131000000000000000000
UDPを使用しているため、ジッターバッファーを使用してパケットなどを再注文することもできます。