音頻編解碼-speex庫的使用方法
轉載自:http://www.rosoo.net/a/201010/10363.htmlSpeex是近年來開發出的一套功能強大的語音引擎,能夠實現高質量和低比特率的編碼。它不僅提供了基于碼激勵線性預測(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;
- /*保存字節因此他們可以被speex常規讀寫*/
- SpeexBits bits;
- int i, tmp;
- //新建一個新的編碼狀態在窄寬(narrowband)模式下
- state = speex_encoder_init(&speex_nb_mode);
- //設置質量為8(15kbps)
- tmp=8;
- speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);
- inFile = argv[1];
- fin = fopen(inFile, "r");
- //初始化結構使他們保存數據
- speex_bits_init(&bits);
- while (1)
- {
- //讀入一幀16bits的聲音
- fread(in, sizeof(short), FRAME_SIZE, fin);
- if (feof(fin))
- break;
- //把16bits的值轉化為float,以便speex庫可以在上面工作
- for (i=0;i<FRAME_SIZE;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;
- }
posted on 2012-11-22 01:27 楊粼波 閱讀(3667) 評論(0) 編輯 收藏 引用 所屬分類: 文章收藏