G711(G711a+g711u)编码原理及代码

G711编码的声音清晰度好,语音自然度高,但压缩效率低,数据量大常在32Kbps以上。常用于电话语音(推荐使用64Kbps),sampling rate为8K,压缩率为2,即把S16格式的数据压缩为8bit,分为a-law和u-law。


a-law也叫g711a,输入的是13位(其实是S16的高13位),使用在欧洲和其他地区,这种格式是经过特别设计的,便于数字设备进行快速运算。

运算过程如下:

(1)      取符号位并取反得到s,

(2)      获取强度位eee,获取方法如图所示

(3)      获取高位样本位wxyz

(4)      组合为seeewxyz,将seeewxyz逢偶数为取补数,编码完毕

示例:

输入pcm数据为3210,二进制对应为(0000 1100 1000 1010)

二进制变换下排列组合方式(0 0001 1001 0001010)

(1)      获取符号位最高位为0,取反,s=1

(2)      获取强度位0001,查表,编码制应该是eee=100

(3)      获取高位样本wxyz=1001

(4)      组合为11001001,逢偶数为取反为10011100

编码完毕。

u-law也叫g711u,使用在北美和日本,输入的是14位,编码算法就是查表,没啥复杂算法,就是基础值+平均偏移值,具体示例如下:

pcm=2345

(1)取得范围值

+4062 to +2015 in 16 intervals of 128

 

(2)得到基础值0x90,

(3)间隔数128,

(4)区间基本值4062,

(5)当前值2345和区间基本值差异4062-2345=1717,

(6)偏移值=1717/间隔数=1717/128,取整得到13,

(7)输出为0x90+13=0x9D

Code如下


 
  
  
  1. #include <stdio.h>
  2. #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
  3. #define QUANT_MASK (0xf) /* Quantization field mask. */
  4. #define NSEGS (8) /* Number of A-law segments. */
  5. #define SEG_SHIFT (4) /* Left shift for segment number. */
  6. #define SEG_MASK (0x70) /* Segment field mask. */
  7. #define BIAS (0x84) /* Bias for linear code. */
  8. #define CLIP 8159
  9. #define G711_A_LAW (0)
  10. #define G711_MU_LAW (1)
  11. #define DATA_LEN (16)
  12. static short seg_aend[ 8] = {
  13. 0x1F, 0x3F, 0x7F, 0xFF,
  14. 0x1FF, 0x3FF, 0x7FF, 0xFFF
  15. };
  16. static short seg_uend[ 8] = {
  17. 0x3F, 0x7F, 0xFF, 0x1FF,
  18. 0x3FF, 0x7FF, 0xFFF, 0x1FFF
  19. };
  20. unsigned char _u2a[ 128] = {
  21. /* u- to A-law conversions */
  22. 1, 1, 2, 2, 3, 3, 4, 4,
  23. 5, 5, 6, 6, 7, 7, 8, 8,
  24. 9, 10, 11, 12, 13, 14, 15, 16,
  25. 17, 18, 19, 20, 21, 22, 23, 24,
  26. 25, 27, 29, 31, 33, 34, 35, 36,
  27. 37, 38, 39, 40, 41, 42, 43, 44,
  28. 46, 48, 49, 50, 51, 52, 53, 54,
  29. 55, 56, 57, 58, 59, 60, 61, 62,
  30. 64, 65, 66, 67, 68, 69, 70, 71,
  31. 72, 73, 74, 75, 76, 77, 78, 79,
  32. 81, 82, 83, 84, 85, 86, 87, 88,
  33. 89, 90, 91, 92, 93, 94, 95, 96,
  34. 97, 98, 99, 100, 101, 102, 103, 104,
  35. 105, 106, 107, 108, 109, 110, 111, 112,
  36. 113, 114, 115, 116, 117, 118, 119, 120,
  37. 121, 122, 123, 124, 125, 126, 127, 128
  38. };
  39. unsigned char _a2u[ 128] = {
  40. /* A- to u-law conversions */
  41. 1, 3, 5, 7, 9, 11, 13, 15,
  42. 16, 17, 18, 19, 20, 21, 22, 23,
  43. 24, 25, 26, 27, 28, 29, 30, 31,
  44. 32, 32, 33, 33, 34, 34, 35, 35,
  45. 36, 37, 38, 39, 40, 41, 42, 43,
  46. 44, 45, 46, 47, 48, 48, 49, 49,
  47. 50, 51, 52, 53, 54, 55, 56, 57,
  48. 58, 59, 60, 61, 62, 63, 64, 64,
  49. 65, 66, 67, 68, 69, 70, 71, 72,
  50. 73, 74, 75, 76, 77, 78, 79, 79,
  51. 80, 81, 82, 83, 84, 85, 86, 87,
  52. 88, 89, 90, 91, 92, 93, 94, 95,
  53. 96, 97, 98, 99, 100, 101, 102, 103,
  54. 104, 105, 106, 107, 108, 109, 110, 111,
  55. 112, 113, 114, 115, 116, 117, 118, 119,
  56. 120, 121, 122, 123, 124, 125, 126, 127
  57. };
  58. static short search(int val, short *table, int size)
  59. {
  60. int i;
  61. for (i = 0; i < size; i++) {
  62. if (val <= *table++)
  63. return (i);
  64. }
  65. return (size);
  66. }
  67. /*
  68. * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
  69. *
  70. * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
  71. *
  72. *Linear Input CodeCompressed Code
  73. *---------------------------------------
  74. *0000000wxyza000wxyz
  75. *0000001wxyza001wxyz
  76. *000001wxyzab010wxyz
  77. *00001wxyzabc011wxyz
  78. *0001wxyzabcd100wxyz
  79. *001wxyzabcde101wxyz
  80. *01wxyzabcdef110wxyz
  81. *1wxyzabcdefg111wxyz
  82. *
  83. * For further information see John C. Bellamy's Digital Telephony, 1982,
  84. * John Wiley & Sons, pps 98-111 and 472-476.
  85. */
  86. unsigned char linear2alaw(int pcm_val)/* 2's complement (16-bit range) */
  87. {
  88. int mask;
  89. int seg;
  90. unsigned char aval;
  91. pcm_val = pcm_val >> 3;
  92. if (pcm_val >= 0) {
  93. mask = 0xD5; /* sign (7th) bit = 1 */
  94. } else {
  95. mask = 0x55; /* sign bit = 0 */
  96. pcm_val = -pcm_val - 1;
  97. }
  98. /* Convert the scaled magnitude to segment number. */
  99. seg = search(pcm_val, seg_aend, 8);
  100. /* Combine the sign, segment, and quantization bits. */
  101. if (seg >= 8) /* out of range, return maximum value. */
  102. return ( unsigned char) ( 0x7F ^ mask);
  103. else {
  104. aval = ( unsigned char) seg << SEG_SHIFT;
  105. if (seg < 2)
  106. aval |= (pcm_val >> 1) & QUANT_MASK;
  107. else
  108. aval |= (pcm_val >> seg) & QUANT_MASK;
  109. return (aval ^ mask);
  110. }
  111. }
  112. /*
  113. * alaw2linear() - Convert an A-law value to 16-bit linear PCM
  114. *
  115. */
  116. int alaw2linear(unsigned char a_val)
  117. {
  118. int t;
  119. int seg;
  120. a_val ^= 0x55;
  121. t = (a_val & QUANT_MASK) << 4;
  122. seg = (( unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
  123. switch (seg) {
  124. case 0:
  125. t += 8;
  126. break;
  127. case 1:
  128. t += 0x108;
  129. break;
  130. default:
  131. t += 0x108;
  132. t <<= seg - 1;
  133. }
  134. return ((a_val & SIGN_BIT) ? t : -t);
  135. }
  136. /*
  137. * linear2ulaw() - Convert a linear PCM value to u-law
  138. *
  139. * In order to simplify the encoding process, the original linear magnitude
  140. * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
  141. * (33 - 8191). The result can be seen in the following encoding table:
  142. *
  143. *Biased Linear Input CodeCompressed Code
  144. *---------------------------------------
  145. *00000001wxyza000wxyz
  146. *0000001wxyzab001wxyz
  147. *000001wxyzabc010wxyz
  148. *00001wxyzabcd011wxyz
  149. *0001wxyzabcde100wxyz
  150. *001wxyzabcdef101wxyz
  151. *01wxyzabcdefg110wxyz
  152. *1wxyzabcdefgh111wxyz
  153. *
  154. * Each biased linear code has a leading 1 which identifies the segment
  155. * number. The value of the segment number is equal to 7 minus the number
  156. * of leading 0's. The quantization interval is directly available as the
  157. * four bits wxyz. * The trailing bits (a - h) are ignored.
  158. *
  159. * Ordinarily the complement of the resulting code word is used for
  160. * transmission, and so the code word is complemented before it is returned.
  161. *
  162. * For further information see John C. Bellamy's Digital Telephony, 1982,
  163. * John Wiley & Sons, pps 98-111 and 472-476.
  164. */
  165. unsigned char linear2ulaw(short pcm_val)/* 2's complement (16-bit range) */
  166. {
  167. short mask;
  168. short seg;
  169. unsigned char uval;
  170. /* Get the sign and the magnitude of the value. */
  171. pcm_val = pcm_val >> 2;
  172. if (pcm_val < 0) {
  173. pcm_val = -pcm_val;
  174. mask = 0x7F;
  175. } else {
  176. mask = 0xFF;
  177. }
  178. if (pcm_val > CLIP)
  179. pcm_val = CLIP; /* clip the magnitude */
  180. pcm_val += (BIAS >> 2);
  181. /* Convert the scaled magnitude to segment number. */
  182. seg = search(pcm_val, seg_uend, 8);
  183. /*
  184. * Combine the sign, segment, quantization bits;
  185. * and complement the code word.
  186. */
  187. if (seg >= 8) /* out of range, return maximum value. */
  188. return ( unsigned char) ( 0x7F ^ mask);
  189. else {
  190. uval = ( unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
  191. return (uval ^ mask);
  192. }
  193. }
  194. /*
  195. * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
  196. *
  197. * First, a biased linear code is derived from the code word. An unbiased
  198. * output can then be obtained by subtracting 33 from the biased code.
  199. *
  200. * Note that this function expects to be passed the complement of the
  201. * original code word. This is in keeping with ISDN conventions.
  202. */
  203. short ulaw2linear(unsigned char u_val)
  204. {
  205. short t;
  206. /* Complement to obtain normal u-law value. */
  207. u_val = ~u_val;
  208. /*
  209. * Extract and bias the quantization bits. Then
  210. * shift up by the segment number and subtract out the bias.
  211. */
  212. t = ((u_val & QUANT_MASK) << 3) + BIAS;
  213. t <<= (( unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
  214. return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
  215. }
  216. /* A-law to u-law conversion */
  217. unsigned char alaw2ulaw(unsigned char aval)
  218. {
  219. aval &= 0xff;
  220. return ( unsigned char) ((aval & 0x80) ? ( 0xFF ^ _a2u[aval ^ 0xD5]) :
  221. ( 0x7F ^ _a2u[aval ^ 0x55]));
  222. }
  223. /* u-law to A-law conversion */
  224. unsigned char ulaw2alaw(unsigned char uval)
  225. {
  226. uval &= 0xff;
  227. return ( unsigned char) ((uval & 0x80) ? ( 0xD5 ^ (_u2a[ 0xFF ^ uval] - 1)) :
  228. ( unsigned char) ( 0x55 ^ (_u2a[ 0x7F ^ uval] - 1)));
  229. }
  230. int encode(char *a_psrc, char *a_pdst, int in_data_len, unsigned char type)
  231. {
  232. int i;
  233. short *psrc = ( short *)a_psrc;
  234. int out_data_len = in_data_len / sizeof( short);
  235. if (a_psrc == NULL || a_pdst == NULL) {
  236. return ( -1);
  237. }
  238. if (in_data_len <= 0) {
  239. return ( -1);
  240. }
  241. if (type == G711_A_LAW) {
  242. for (i = 0; i < out_data_len; i++) {
  243. a_pdst[i] = ( char)linear2alaw(psrc[i]);
  244. }
  245. } else {
  246. for (i = 0; i < out_data_len; i++) {
  247. a_pdst[i] = ( char)linear2ulaw(psrc[i]);
  248. }
  249. }
  250. return (i);
  251. }
  252. int decode(char *a_psrc, char *a_pdst, int in_data_len, unsigned char type)
  253. {
  254. int i;
  255. short *pdst = ( short *)a_pdst;
  256. int out_data_len = in_data_len / sizeof( char);
  257. if (a_psrc == NULL || a_pdst == NULL) {
  258. return ( -1);
  259. }
  260. if (type == G711_A_LAW) {
  261. for (i = 0; i < out_data_len; i++) {
  262. pdst[i] = ( short)alaw2linear(( unsigned char)a_psrc[i]);
  263. }
  264. } else {
  265. for (i = 0; i < out_data_len; i++) {
  266. pdst[i] = ( short)ulaw2linear(( unsigned char)a_psrc[i]);
  267. }
  268. }
  269. return (i * sizeof( short));
  270. }
  271. int main(int argc, char **argv)
  272. {
  273. int i = 0;
  274. int n = 0;
  275. unsigned short pcm_buf[DATA_LEN] = { 0}; /*store linear pcm data*/
  276. unsigned short pcm_buf2[DATA_LEN] = { 0}; /*store linear pcm data*/
  277. unsigned char g711_buf[DATA_LEN] = { 0};
  278. FILE * fp_in = fopen( "input.wav", "r");
  279. FILE * fp_out = fopen( "pcm.g711_alaw", "w");
  280. FILE * fp_out_pcm = fopen( "pcm2.wav", "w");
  281. unsigned char header[ 128] = { 0 };
  282. fread(header, 1, 0x2c, fp_in);
  283. fwrite(header, 1, 0x2c, fp_out_pcm);
  284. while (DATA_LEN * 2 == fread(pcm_buf, 1, DATA_LEN * 2, fp_in)) {
  285. printf( "encode %d was trans\n",
  286. encode(pcm_buf, g711_buf, sizeof(pcm_buf), G711_A_LAW));
  287. fwrite(g711_buf, 1, DATA_LEN, fp_out);
  288. printf( "decode %d was trans\n",
  289. decode(g711_buf, pcm_buf2, sizeof(g711_buf), G711_A_LAW));
  290. fwrite(pcm_buf2, 1, DATA_LEN* 2, fp_out_pcm);
  291. }
  292. fclose(fp_in);
  293. fclose(fp_out);
  294. fclose(fp_out_pcm);
  295. return 0;
  296. }


转自:https://blog.csdn.net/szfhy/article/details/52448906

猜你喜欢

转载自blog.csdn.net/u014470361/article/details/98503237