最近看语音编码,发现网上大都只给出了G711的代码,确没有介绍原理,尽管很简单,但直接看代码也是有点摸不着。下面找到了原理进行简要的叙述,并给出了在网上找到的代码。
G.711
也称为PCM(脉冲编码调制),是国际电信联盟订定出来的一套语音压缩标准,主要用于电话。它主要用脉冲编码调制对音频采样,采样率为8k每秒。它利用一个 64Kbps 未压缩通道传输语音讯号。起压缩率为1:2,即把16位数据压缩成8位。G.711是主流的波形声音编解码器。
G.711 标准下主要有两种压缩算法。一种是µ-law algorithm (又称often u-law, ulaw, mu-law),主要运用于北美和日本;另一种是A-law algorithm,主要运用于欧洲和世界其他地区。其中,后者是特别设计用来方便计算机处理的。这两种算法都使用一个采样率为8kHz的输入来创建64Kbps的数字输出。G.711采用一种称为分组丢失隐藏(PLC)的技术来减少丢包带来的实际影响。有效的信号带宽在静默期间通过语音活动检测(VAD)这一过程被减小。
G.711编码方式将14bits(采用16bits采样与存储)的PCM信号编码成8bits的样本进行传输。
原理:取影响较为重要的位编码成8位(保留重要位),比如下面的数据,前N较具有影响力,(以下2组数据,N=5)
0000 0001 1111 1111 (511)
0000 0001 1111 0000 (496)
0001 1111 1111 1111 (8191)
0001 1111 0000 0000 (7936)
取影响最大的5位(1位为强度位,4位样本位),sign为样本的符号位,同时编码后的数据逢偶数为取补数。即^0xD5。编码表如下,s位符号位正数时s=1。
比如pcm=3210(0000 1100 1000 1010)2
1. int sign = pcm & 0x8000) >> 8;
S=1;
2. 取强度位
0 0001 10010001010
Xs = 100
3. 取高位样本
0 0001 10010001010
wxyz = 1001
4. 結合以上数字
s xxx wxyz
1 100 1001
5. 逢偶位数取补数
1 1001001
1 0011100
1.取得范围值,得到8-bit基本值
2.取得间隔数值size。如图所示:
3.取得區間基本值rb(ex2015)
4.算出與區間基本值rb的距離d d = rb - sample
5.依據間距大小size,算出平移量s = d / size
6.與8-bit基本值相加output = b + s
7903 |
8159 4319 |
4063 |
4063 2143 |
2015 |
2015 1055 |
991 |
991 511 |
479 |
479 239 |
223 |
223 103 |
95 |
95 35 |
31 |
31 3 |
0 |
1 0 |
範例 : 2345 => 0x9D
1.取得範圍值
range => 4063~2015
1-1.得到8-bit基本值
b = 0x90
2.取得間隔數值
size = 128
3.取得區間基本值
4063 |
4063 2143 |
rb = 4063
4.算出與區間基本值rb的距離d
d = rb – sample = 4063 – 2345 = 1718
5.依據間距大小size,算出平移量
s = d / size = 1718 / 128 = 13.42… => 13
6.與8-bit基本值相加
output = b + s = 0x90 + 13 = 9D