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

G711(G711a+g711u)编码原理及代码相关推荐

  1. Base64 编码原理及代码实现

    Base64 编码原理及代码实现 所谓 base64 编码就是从 ASCII 码表中选取64个可打印字符(A-Za-z0-9+/)作为基本字符集对其它字符进行编码转换.加上作为填充的 "=& ...

  2. DPCM编码原理及代码实现

    目录 一.DPCM编码 二.DPCM编码原理 三.DPCM编码器 四.DPCM解码器 五.DPCM代码实现 六.代码结果 一.DPCM编码 DPCM编码,英文名称Differential pulse- ...

  3. G711编码原理及代码

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

  4. Quoted-Printable编码原理及代码实现

    这篇文章是我之前在RYTong内部分享的一篇文章,摘取了有用的部分.当时帮助某项目邮件系统解决问题,期间了解到Quoted-Printable编码,在此与大家分享下该编码的原理和个人版本的代码实现. ...

  5. 移植mp4v2开源库,h264+g711a/g711u编码mp4

    1.mp4v2移植 step1.下载:https://launchpad.net/ubuntu/+source/mp4v2 step2.编译 简单配置参数: ./configure --host=ar ...

  6. 哈夫曼编码原理与Python实现代码(附手动推导过程原稿真迹)

    哈夫曼编码依据字符出现概率来构造异字头(任何一个字符的编码都不是其他字符的前缀)的平均长度最短的码字,通过构造二叉树来实现,出现频次越多的字符编码越短,出现频次越少的字符编码越长.为了演示哈夫曼编码原 ...

  7. JPEG编码原理及文件格式及代码分析

    一 JPEG编码原理 首先我们先来看一下JPEG的编码原理图 如上图所示,下面进行逐步的分析: 1 RGB->YUV 首先为了降低互相的关联性,将RGB转换为YUV,这样就可以对亮度信号和色度信 ...

  8. HTML首字下沉的编码,CSS_有关首行首字下沉的实现原理及代码,下面是两个个小技巧,一个是 - phpStudy...

    有关首行首字下沉的实现原理及代码 下面是两个个小技巧,一个是很多报刊中的首字下沉,其实很简单,原理就是在样式中添加后缀即可.还有一个是对第一行文字进行单独样式.给这段标签添加后缀即可.这两个小技巧分别 ...

  9. c++之PCM G711A G711U源码实现

    系列音视频指南 文章目录 系列音视频指南 前言 一.PCM是什么? 二.G711是什么? G711 A-LAW G711 U-LAW 三.源码分析 1.PCM->G711A 2.G711A-&g ...

最新文章

  1. 分享一下我的初中生活
  2. linux中通过命令生成hex值
  3. 第二百二十六天 how can I 坚持
  4. AI+混合云模式,如何最大化挖掘数据价值?
  5. 前 1 号店 CTO 黄哲铿揭秘:微服务架构在超大场景下的应用
  6. 数据结构的时间复杂度与空间复杂度、及相关证明
  7. 学完Linux之后学什么语言,学习C语言一段时间后我们能做什么?
  8. 使用ActivityGroup类显示多个Activity
  9. 网站扫码登录时怎么一回事?
  10. 基于PaddleOCR史上最全车牌号识别实现(二)
  11. 使用webpack搭建vue项目;webpack+vue
  12. 【渝粤教育】电大中专药理学基础作业 题库
  13. 初试hive-创建内表(最简单的表),load加载方式简介
  14. 《平衡掌控者》笔记(结)
  15. Kurento应用开发指南(以Kurento 5.0为模板) 之四:示例教程 一对一视频呼叫
  16. PX4使用FPV DShot电调
  17. 使用 __breakpoint 实现软件中断
  18. VC 编译选项的使用点滴 warring lnk4908
  19. 第四范式上市更进一步:再募资7亿美元,AI独角兽们陷亏损泥潭
  20. HCIP-IoT——华为云物联网端到端开发

热门文章

  1. 获取iOS设备UDID的方法
  2. js视频封面(截帧)
  3. 16083001(古墓丽影GPA)
  4. 网站HTPPS加密有什么作用
  5. Matlab画天球坐标图,知道方位角和高度角
  6. 由夏时令引起的java世界时间不一致问题
  7. Human Pose Estimation姿态估计调研
  8. spo0lsv病毒分析
  9. 《软件工程之美》打卡第六周,春招我借这份PDF的复习思路
  10. win10添加打印机失败,无法正常使用打印机的解决办法