轉載自:http://www.rosoo.net/a/201010/10363.html
Speex是近年來開發出的一套功能強大的語音引擎,能夠實現高質量和低比特率的編碼。它不僅提供了基于碼激勵線性預測(CELP)算法的編/解碼模塊, 而且在其最新發布的版本中還提供了聲音預處理和聲學回聲消除模塊,為保障IP網絡中的語音通信質量提供了技術手段。此外,Speex還具有壓縮后的比特率 低(2~44 kbps)的特點,并支持多種比特率。這些特點使得Speex特別適合VoIP的系統。
雖然是開源的,但是使用的人還不是很多,網上的資料也很少,下面簡單給大家介紹一下如何使用speex的API。
一:編碼流程
使用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表示要定義的參數類型,如SPEEX_ GET_ FRAME_SIZE表示設置幀大小,SPEEX_ SET_QUALITY表示量化大小,這決定了編碼的質量;參數ptr表示要設定的值。
可通過speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &frame_size) 和speex_encoder_ctl(enc_state, SPEEX_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 <speex.h>
- #include <stdio.h>
-
- #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;
-
- SpeexBits bits;
- int i, tmp;
-
- state = speex_encoder_init(&speex_nb_mode);
-
- tmp=8;
- speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);
- inFile = argv[1];
-
- fin = fopen(inFile, "r");
-
- speex_bits_init(&bits);
- while (1)
- {
-
- fread(in, sizeof(short), FRAME_SIZE, fin);
- if (feof(fin))
- break;
-
- for (i=0;i<FRAME_SIZE;i++)
- input[i]=in[i];
-
-
- speex_bits_reset(&bits);
-
- speex_encode(state, input, &bits);
-
- nbBytes = speex_bits_write(&bits, cbits, 200);
-
- fwrite(&nbBytes, sizeof(int), 1, stdout);
-
- fwrite(cbits, 1, nbBytes, stdout);
- }
-
-
- speex_encoder_destroy(state);
-
- speex_bits_destroy(&bits);
- fclose(fin);
- return 0;
- }