speexの基本符号化と復号化の流れ
10979 ワード
最近speexの符号化と復号化の流れを研究している.
以前はIMで音声クリップを使っていましたが、これは簡単で、googlecodeのgaussのコードを見つけて、セットすれば使えます.
しかしgooglecodeは閉じて、ある人は彼をgithubに導入して、住所はここにありますhttps://github.com/cczufish/OggSpeex-android
私も導入しましたが、成功していません.何の問題か分かりません.レベルが足りないかもしれません.ははははhttps://github.com/dongweiq/android-recorder
音声クリップをつなぎ合わせて合成し、UIに再生中の時間を表示する必要がある.gaussのコードを見てみると、彼のコードは復号しながら再生され、short[160]のクリップに従って一つ一つ再生されていることが分かった.
また、pacetNoが0の場合はspeexのファイルヘッダで80バイトを占め、packetNoが1の場合はパケット番号2を検索し、2の場合は160 shortでオーディオを復号し、復号後のwavを再生するパケット番号もある.
その後、ネット上で以下の内容を見つけました.http://blog.163.com/yuan_zhch/blog/static/193790046201172611527217/
speex全体の符号化と復号化の過程の総括に相当するだろう.
一:符号化プロセス
SpeexのAPI関数を使用してオーディオデータを圧縮符号化するには、次の手順に従います.
1.SpeexBits型変数bitsとSpeexエンコーダ状態変数enc_を定義するstate.
2、speex_を呼び出すbits_init(&bits)bitsを初期化します.
3、speex_を呼び出すencoder_init(&speex_nb_mode)はenc_を初期化するstate.ここでspeex_nb_modeはSpeexModeタイプの変数で、狭帯域モードを表します.そしてspeex_wb_modeはブロードバンドモード、speex_を表しますuwb_modeは超広帯域モードを表す.
4、呼び出し関数int speex_encoder_ ctl(void*state,int request,void*ptr)は、エンコーダのパラメータを設定し、パラメータstateはエンコーダの状態を表す.パラメータrequestは、SPEX_などの定義するパラメータのタイプを表します.GET_ FRAME_SIZEは設定フレームサイズを表し、SPEX_SET_QUALITYは量子化サイズを表し、これは符号化の品質を決定する.パラメータptrは、設定する値を表します.
speex_経由encoder_ctl(enc_state,SPEX_GET_FRAME_SIZE,&frame_size)とspeex_encoder_ctl(enc_state,SPEX_SET_QUALITY,&quality)でエンコーダのパラメータを設定します.
5、初期化完了後、各フレームの音声に対して以下の処理を行う:呼び出し関数speex_bits_reset(&bits)SpeexBitsを再度設定し、関数speex_を呼び出します.encode(enc_state,input_frame,&bits)は、パラメータbitsに符号化されたデータストリームを保存します.
6、符号化終了後、関数speex_を呼び出すbits_destroy (&bits), speex_encoder_destroy(enc_state)が来る
二:復号プロセス
同様に、符号化されたオーディオデータを復号するには、以下のステップが必要である.
1.SpeexBits型変数bitsとSpeex符号化状態変数enc_を定義するstate.
2、speex_を呼び出すbits_init(&bits)bitsを初期化します.
3、speex_を呼び出すdecoder_init(&speex_nb_mode)はenc_を初期化するstate.
4、呼び出し関数speex_decoder_ctl(void*state,int request,void*ptr)でエンコーダのパラメータを設定します.
5、呼び出し関数speex_decode(void*state,SpeexBits*bits,float*out)は、パラメータbitsのオーディオデータをデコーディングし、パラメータoutに復号化されたデータストリームを保存する.
6、呼び出し関数speex_bits_destroy(&bits), speex_ decoder_ destroy(void*state)は、SpeexBitsとデコーダを閉じて破棄します.
次に、インスタンスコードを示します. #include #include /*フレームのサイズはこのルーチンでは一定の値であるが、必ずしもそうではない*/ #define FRAME_SIZE 160 int main(int argc, char **argv) { char *inFile; FILE *fin; short in[FRAME_SIZE]; float input[FRAME_SIZE]; char cbits[200]; int nbBytes; /*コードの状態を保存*/ void *state; /*バイトを保存するので、speexの通常の読み書き*/ SpeexBits bits; int i, tmp; //新しい符号化状態を狭幅(narrowband)モードで state = speex_encoder_init(&speex_nb_mode); //設定品質8(15 kbps) tmp=8; speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp); inFile = argv[1]; fin = fopen(inFile, "r"); //初期化構造によりデータ を保存 speex_bits_init(&bits); while (1) { //1フレーム16 bitsの音 を読み込む fread(in, sizeof(short), FRAME_SIZE, fin); if (feof(fin)) break; //16 bitsの値をfloatに変換し、speexライブラリが で動作できるようにします. for (i=0;i input[i]=in[i]; //この構造体のすべてのバイトを空にして、新しいフレーム を符号化することができます. speex_bits_reset(&bits); //フレームを符号化 speex_encode(state, input, &bits); //bitsを書き出したchar型配列 にコピーする nbBytes = speex_bits_write(&bits, cbits, 200); //まずフレームのサイズを書き出します.これはsampledecファイルに必要な値ですが、アプリケーションでは とは異なる場合があります. fwrite(&nbBytes, sizeof(int), 1, stdout); //圧縮された配列を書く fwrite(cbits, 1, nbBytes, stdout); } //リリースエンコーダ状態量 speex_encoder_destroy(state); //リリースbit_Packing構造 speex_bits_destroy(&bits); fclose(fin); return 0; }
以前はIMで音声クリップを使っていましたが、これは簡単で、googlecodeのgaussのコードを見つけて、セットすれば使えます.
しかしgooglecodeは閉じて、ある人は彼をgithubに導入して、住所はここにありますhttps://github.com/cczufish/OggSpeex-android
私も導入しましたが、成功していません.何の問題か分かりません.レベルが足りないかもしれません.ははははhttps://github.com/dongweiq/android-recorder
音声クリップをつなぎ合わせて合成し、UIに再生中の時間を表示する必要がある.gaussのコードを見てみると、彼のコードは復号しながら再生され、short[160]のクリップに従って一つ一つ再生されていることが分かった.
1 /* decode each segment, writing output to wav */
2 for (curseg = 0; curseg < segments; curseg++) {
3
4 if (Thread.interrupted()) {
5 dis.close();
6 track.stop();
7 track.release();
8 return;
9 }
10
11 while (this.isPaused()) {
12 track.stop();
13 track.release();
14 // Thread.sleep(100);
15 }
16
17 /* get the number of bytes in the segment */
18 bodybytes = header[OGG_HEADERSIZE + curseg] & 0xFF;
19 if (bodybytes == 255) {
20 System.err.println("sorry, don't handle 255 sizes!");
21 return;
22 }
23 dis.readFully(payload, 0, bodybytes);
24 chksum = OggCrc.checksum(chksum, payload, 0, bodybytes);
25
26 /* decode the segment */
27 /* if first packet, read the Speex header */
28 if (packetNo == 0) {
29 if (readSpeexHeader(payload, 0, bodybytes, true)) {
30 packetNo++;
31 } else {
32 packetNo = 0;
33 }
34 } else if (packetNo == 1) { // Ogg Comment packet
35 packetNo++;
36 } else {
37
38 /* get the amount of decoded data */
39 short[] decoded = new short[160];
40 if ((decsize = speexDecoder.decode(payload, decoded, 160)) > 0) {
41 track.write(decoded, 0, decsize);
42 float maxVol = AudioTrack.getMaxVolume();
43 track.setStereoVolume(maxVol, maxVol);//
44 track.play();
45 }
46 packetNo++;
47 }
48 }
また、pacetNoが0の場合はspeexのファイルヘッダで80バイトを占め、packetNoが1の場合はパケット番号2を検索し、2の場合は160 shortでオーディオを復号し、復号後のwavを再生するパケット番号もある.
その後、ネット上で以下の内容を見つけました.http://blog.163.com/yuan_zhch/blog/static/193790046201172611527217/
speex全体の符号化と復号化の過程の総括に相当するだろう.
一:符号化プロセス
SpeexのAPI関数を使用してオーディオデータを圧縮符号化するには、次の手順に従います.
1.SpeexBits型変数bitsとSpeexエンコーダ状態変数enc_を定義するstate.
2、speex_を呼び出すbits_init(&bits)bitsを初期化します.
3、speex_を呼び出すencoder_init(&speex_nb_mode)はenc_を初期化するstate.ここでspeex_nb_modeはSpeexModeタイプの変数で、狭帯域モードを表します.そしてspeex_wb_modeはブロードバンドモード、speex_を表しますuwb_modeは超広帯域モードを表す.
4、呼び出し関数int speex_encoder_ ctl(void*state,int request,void*ptr)は、エンコーダのパラメータを設定し、パラメータstateはエンコーダの状態を表す.パラメータrequestは、SPEX_などの定義するパラメータのタイプを表します.GET_ FRAME_SIZEは設定フレームサイズを表し、SPEX_SET_QUALITYは量子化サイズを表し、これは符号化の品質を決定する.パラメータptrは、設定する値を表します.
speex_経由encoder_ctl(enc_state,SPEX_GET_FRAME_SIZE,&frame_size)とspeex_encoder_ctl(enc_state,SPEX_SET_QUALITY,&quality)でエンコーダのパラメータを設定します.
5、初期化完了後、各フレームの音声に対して以下の処理を行う:呼び出し関数speex_bits_reset(&bits)SpeexBitsを再度設定し、関数speex_を呼び出します.encode(enc_state,input_frame,&bits)は、パラメータbitsに符号化されたデータストリームを保存します.
6、符号化終了後、関数speex_を呼び出すbits_destroy (&bits), speex_encoder_destroy(enc_state)が来る
二:復号プロセス
同様に、符号化されたオーディオデータを復号するには、以下のステップが必要である.
1.SpeexBits型変数bitsとSpeex符号化状態変数enc_を定義するstate.
2、speex_を呼び出すbits_init(&bits)bitsを初期化します.
3、speex_を呼び出すdecoder_init(&speex_nb_mode)はenc_を初期化するstate.
4、呼び出し関数speex_decoder_ctl(void*state,int request,void*ptr)でエンコーダのパラメータを設定します.
5、呼び出し関数speex_decode(void*state,SpeexBits*bits,float*out)は、パラメータbitsのオーディオデータをデコーディングし、パラメータoutに復号化されたデータストリームを保存する.
6、呼び出し関数speex_bits_destroy(&bits), speex_ decoder_ destroy(void*state)は、SpeexBitsとデコーダを閉じて破棄します.
次に、インスタンスコードを示します.