版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013025955/article/details/85220390
PCM原始音频数据体积较大,就算是比较小的16位采样精度,每秒采样40000次,10分钟的数据也有45MB,这样在网络传输所需要的成本很大。 考虑使用压缩方法减少需要传输的数据量,G711a律编码格式可以将16位数据压缩成8位,即将原本45MB压缩一半变成22MB左右。
目录
- 程序效果
- G711a律编码过程
程序效果
在PCM录制、播放基础上新增G711a律编解码功能。
1.原始wav文件在进行G711a律编码之后,体积变为原来的一半。 2.解码后,恢复位原始大小,但是由于为有损压缩,声音相交原始音频有明显的噪音。
G711a律编码过程
保留高位,舍弃低位
以13bit采样的PCM音频数据为例,编码成8bit的数据流。(在播放的时候再还原成13bit)
压缩前 |
压缩后 |
S 0000 001w xyz'a |
s001 wxyz |
S 0000 01wx yz'ab |
s010 wxyz |
S 0000 1wxy z'abc |
s011 wxyz |
S 0001 wxyz 'abcd |
s100 wxyz |
S 001w xyz'a bcde |
s101 wxyz |
S 01wx yz'ab cdef |
s110 wxyz |
S 1wxy z'abc defg |
s111 wxyz |
压缩方式如上,原始输入均为13位音频数据,其中S为符号位代表正、负,'符号之后的数据再压缩过程中被舍弃,仅保留wxyz位置上的数据。
压缩后的格式很像二进制科学技术法形式:
S、2的xxx次方、wxyz数据
符号位与偶数位取反
- unsigned char linear2alaw(short pcm_val) /* 2's complement (16-bit range) */
- {
- short mask;
- short seg;
- unsigned char aval;
- if (pcm_val >= 0) {
- mask = 0xD5; /* sign (7th) bit = 1 */
- } else {
- mask = 0x55; /* sign bit = 0 */
- pcm_val = -pcm_val - 8;
- }
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_end, 8);
- /* Combine the sign, segment, and quantization bits. */
- if (seg >= 8) /* out of range, return maximum value. */
- return (0x7F ^ mask);
- else {
- aval = seg << SEG_SHIFT;
- if (seg < 2)
- aval |= (pcm_val >> 4) & QUANT_MASK;
- else
- aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
- return (aval ^ mask);
- }
- }
主要通过“<<”、“>>”、“|”、“^”等位运算实现编码过程。
参考资料:
1.G.711编码原理及代码
https://www.2cto.com/kf/201504/390076.html