前段時(shí)間在做攝像頭想關(guān)的項(xiàng)目的時(shí)候牲阁,在播放卡錄得時(shí)候,攝像頭返回來的數(shù)據(jù)的時(shí)候壤躲,發(fā)現(xiàn)返回來的音頻的格式是將pcm編碼成G711A的數(shù)據(jù)城菊。所以只能將G711A轉(zhuǎn)換為pcm,然后在進(jìn)行播放碉克。于是凌唬,就瘋狂的在網(wǎng)上找資料。
但是漏麦,并沒有找到G711A轉(zhuǎn)pcm的相關(guān)資料客税。
于是,就開始研究編碼格式.
先補(bǔ)充一下pcm和G711的編碼方式
1)pcm
PCM是一種編碼格式撕贞,pcm是裸流更耻。
所以,pcm我們直接就能夠就行播放
2)G711
在開始講G711A轉(zhuǎn)為pcm的時(shí)候捏膨,我們先了解一下pcm是怎么被轉(zhuǎn)換為G711的秧均。
以下的相互轉(zhuǎn)換,都會(huì)用到一個(gè)三方庫号涯。
1)pcm-> G711
從上面的編碼原理可以知道目胡,pcm轉(zhuǎn)G711是進(jìn)行了壓縮轉(zhuǎn)換。
起壓縮率為1:2链快, 即把16位數(shù)據(jù)壓縮成8位
NSUInteger datalength = [inputData length];
Byte *byteData = (Byte *)[inputData bytes];
short *pPcm = (short *)byteData;
int outlen = 0;
int len =(int)datalength / 2;
Byte * G711Buff = (Byte *)malloc(len);
memset(G711Buff,0,len);
int i;
for (i=0; i<len; i++) {
G711Buff[i] = linear2alaw(pPcm[i]);
}
outlen = i;
Byte *sendbuff = (Byte *)G711Buff;
NSData * sendData = [[NSData alloc]initWithBytes:sendbuff length:len];
2)G711A->pcm
因?yàn)槲覀冎纏cm轉(zhuǎn)G711是將pcm進(jìn)行了壓縮誉己,那么G711轉(zhuǎn)pcm我們就需要將G711重新編碼后,長度會(huì)增加會(huì)原來的兩倍久又。
我收到的數(shù)據(jù)是char類型的buffer數(shù)據(jù)
dataPtr:(const char *)data_ptr
遍歷收到的數(shù)據(jù)巫延,解析每個(gè)字節(jié)
short * pcmOuT = (short *)(malloc(dataLen*2));//因?yàn)檗D(zhuǎn)換后長度為原來的兩倍效五,所以申請(qǐng)一個(gè)數(shù)據(jù)長度兩倍的數(shù)組
for (int i =0; i<dataLen; i++) {
pcmOuT[i] = (int16_t)alaw2linear(data_ptr[i]);
}
這樣解析出來的數(shù)據(jù)就是pcm地消÷澹可以截止播放.
G711U轉(zhuǎn)pcm也是類似的做法