【2018-02-19】【转】 G711编码原理及代码

发布时间:2026/7/18 5:35:13
【2018-02-19】【转】 G711编码原理及代码 [历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2018-02-19 标题【转】 G711编码原理及代码分类编程 标签g711如何编码G.711a-lawu-law实例代码本文转自【 http://blog.csdn.net/szfhy/article/details/52448906 】G711编码的声音清晰度好语音自然度高但压缩效率低数据量大常在32Kbps以上。常用于电话语音(推荐使用64Kbps)sampling rate为8K压缩率为2即把S16格式的数据压缩为8bit分为a-law和u-law。a-lawa-law也叫g711a,输入的是13位其实是S16的高13位使用在欧洲和其他地区这种格式是经过特别设计的便于数字设备进行快速运算。运算过程如下1 取符号位并取反得到s2 获取强度位eee获取方法如图所示3 获取高位样本位wxyz4 组合为seeewxyz将seeewxyz逢偶数为取补数编码完毕示例输入pcm数据为3210二进制对应为0000 1100 1000 10101 获取符号位最高位为0取反s12 获取强度位0001查表编码制应该是eee1003 获取高位样本wxyz10014 组合为11001001逢偶数为取反为10011100编码完毕。u-lawu-law也叫g711u,使用在北美和日本输入的是14位编码算法就是查表没啥复杂算法就是基础值平均偏移值具体示例如下pcm23451取得范围值4062 to 2015 in 16 intervals of 1282得到基础值0x903间隔数1284区间基本值40625当前值2345和区间基本值差异4062-234517176偏移值1717/间隔数1717/128取整得到137输出为0x90130x9D实例代码#includestdio.h#defineSIGN_BIT(0x80)/* Sign bit for a A-law byte. */#defineQUANT_MASK(0xf)/* Quantization field mask. */#defineNSEGS(8)/* Number of A-law segments. */#defineSEG_SHIFT(4)/* Left shift for segment number. */#defineSEG_MASK(0x70)/* Segment field mask. */#defineBIAS(0x84)/* Bias for linear code. */#defineCLIP8159#defineG711_A_LAW(0)#defineG711_MU_LAW(1)#defineDATA_LEN(16)staticshortseg_aend[8]{0x1F,0x3F,0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF};staticshortseg_uend[8]{0x3F,0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF,0x1FFF};unsignedchar_u2a[128]{/* u- to A-law conversions */1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,40,41,42,43,44,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128};unsignedchar_a2u[128]{/* A- to u-law conversions */1,3,5,7,9,11,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,32,33,33,34,34,35,35,36,37,38,39,40,41,42,43,44,45,46,47,48,48,49,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127};staticshortsearch(intval,short*table,intsize){inti;for(i0;isize;i){if(val*table)return(i);}return(size);}/* * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law * * linear2alaw() accepts an 16-bit integer and encodes it as A-law data. * *Linear Input CodeCompressed Code *--------------------------------------- *0000000wxyza000wxyz *0000001wxyza001wxyz *000001wxyzab010wxyz *00001wxyzabc011wxyz *0001wxyzabcd100wxyz *001wxyzabcde101wxyz *01wxyzabcdef110wxyz *1wxyzabcdefg111wxyz * * For further information see John C. Bellamys Digital Telephony, 1982, * John Wiley Sons, pps 98-111 and 472-476. */unsignedcharlinear2alaw(intpcm_val)/* 2s complement (16-bit range) */{intmask;intseg;unsignedcharaval;pcm_valpcm_val3;if(pcm_val0){mask0xD5;/* sign (7th) bit 1 */}else{mask0x55;/* sign bit 0 */pcm_val-pcm_val-1;}/* Convert the scaled magnitude to segment number. */segsearch(pcm_val,seg_aend,8);/* Combine the sign, segment, and quantization bits. */if(seg8)/* out of range, return maximum value. */return(unsignedchar)(0x7F^mask);else{aval(unsignedchar)segSEG_SHIFT;if(seg2)aval|(pcm_val1)QUANT_MASK;elseaval|(pcm_valseg)QUANT_MASK;return(aval^mask);}}/* * alaw2linear() - Convert an A-law value to 16-bit linear PCM * */intalaw2linear(unsignedchara_val){intt;intseg;a_val^0x55;t(a_valQUANT_MASK)4;seg((unsigned)a_valSEG_MASK)SEG_SHIFT;switch(seg){case0:t8;break;case1:t0x108;break;default:t0x108;tseg-1;}return((a_valSIGN_BIT)?t:-t);}/* * linear2ulaw() - Convert a linear PCM value to u-law * * In order to simplify the encoding process, the original linear magnitude * is biased by adding 33 which shifts the encoding range from (0 - 8158) to * (33 - 8191). The result can be seen in the following encoding table: * *Biased Linear Input CodeCompressed Code *--------------------------------------- *00000001wxyza000wxyz *0000001wxyzab001wxyz *000001wxyzabc010wxyz *00001wxyzabcd011wxyz *0001wxyzabcde100wxyz *001wxyzabcdef101wxyz *01wxyzabcdefg110wxyz *1wxyzabcdefgh111wxyz * * Each biased linear code has a leading 1 which identifies the segment * number. The value of the segment number is equal to 7 minus the number * of leading 0s. The quantization interval is directly available as the * four bits wxyz. * The trailing bits (a - h) are ignored. * * Ordinarily the complement of the resulting code word is used for * transmission, and so the code word is complemented before it is returned. * * For further information see John C. Bellamys Digital Telephony, 1982, * John Wiley Sons, pps 98-111 and 472-476. */unsignedcharlinear2ulaw(shortpcm_val)/* 2s complement (16-bit range) */{shortmask;shortseg;unsignedcharuval;/* Get the sign and the magnitude of the value. */pcm_valpcm_val2;if(pcm_val0){pcm_val-pcm_val;mask0x7F;}else{mask0xFF;}if(pcm_valCLIP)pcm_valCLIP;/* clip the magnitude */pcm_val(BIAS2);/* Convert the scaled magnitude to segment number. */segsearch(pcm_val,seg_uend,8);/* * Combine the sign, segment, quantization bits; * and complement the code word. */if(seg8)/* out of range, return maximum value. */return(unsignedchar)(0x7F^mask);else{uval(unsignedchar)(seg4)|((pcm_val(seg1))0xF);return(uval^mask);}}/* * ulaw2linear() - Convert a u-law value to 16-bit linear PCM * * First, a biased linear code is derived from the code word. An unbiased * output can then be obtained by subtracting 33 from the biased code. * * Note that this function expects to be passed the complement of the * original code word. This is in keeping with ISDN conventions. */shortulaw2linear(unsignedcharu_val){shortt;/* Complement to obtain normal u-law value. */u_val~u_val;/* * Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias. */t((u_valQUANT_MASK)3)BIAS;t((unsigned)u_valSEG_MASK)SEG_SHIFT;return((u_valSIGN_BIT)?(BIAS-t):(t-BIAS));}/* A-law to u-law conversion */unsignedcharalaw2ulaw(unsignedcharaval){aval0xff;return(unsignedchar)((aval0x80)?(0xFF^_a2u):(0x7F^_a2u));}/* u-law to A-law conversion */unsignedcharulaw2alaw(unsignedcharuval){uval0xff;return(unsignedchar)((uval0x80)?(0xD5^(_u2a[0xFF^uval]-1)):(unsignedchar)(0x55^(_u2a[0x7F^uval]-1)));}intencode(char*a_psrc,char*a_pdst,intin_data_len,unsignedchartype){inti;short*psrc(short*)a_psrc;intout_data_lenin_data_len/sizeof(short);if(a_psrcNULL||a_pdstNULL){return(-1);}if(in_data_len0){return(-1);}if(typeG711_A_LAW){for(i0;iout_data_len;i){a_pdst(char)linear2alaw(psrc);}}else{for(i0;iout_data_len;i){a_pdst(char)linear2ulaw(psrc);}}return(i);}intdecode(char*a_psrc,char*a_pdst,intin_data_len,unsignedchartype){inti;short*pdst(short*)a_pdst;intout_data_lenin_data_len/sizeof(char);if(a_psrcNULL||a_pdstNULL){return(-1);}if(typeG711_A_LAW){for(i0;iout_data_len;i){pdst(short)alaw2linear((unsignedchar)a_psrc);}}else{for(i0;iout_data_len;i){pdst(short)ulaw2linear((unsignedchar)a_psrc);}}return(i*sizeof(short));}intmain(intargc,char**argv){inti0;intn0;unsignedshortpcm_buf[DATA_LEN]{0};/*store linear pcm data*/unsignedshortpcm_buf2[DATA_LEN]{0};/*store linear pcm data*/unsignedcharg711_buf[DATA_LEN]{0};FILE*fp_infopen(input.wav,r);FILE*fp_outfopen(pcm.g711_alaw,w);FILE*fp_out_pcmfopen(pcm2.wav,w);unsignedcharheader[128]{0};fread(header,1,0x2c,fp_in);fwrite(header,1,0x2c,fp_out_pcm);while(DATA_LEN*2fread(pcm_buf,1,DATA_LEN*2,fp_in)){printf(encode%d was trans ,encode(pcm_buf,g711_buf,sizeof(pcm_buf),G711_A_LAW));fwrite(g711_buf,1,DATA_LEN,fp_out);printf(decode%d was trans ,decode(g711_buf,pcm_buf2,sizeof(g711_buf),G711_A_LAW));fwrite(pcm_buf2,1,DATA_LEN*2,fp_out_pcm);}fclose(fp_in);fclose(fp_out);fclose(fp_out_pcm);return0;}