码迷,mamicode.com
首页 > 其他好文 > 详细

G.711编码原理及代码

时间:2015-04-12 17:51:26      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:g711   音频编码   编码原理   g711原理   

最近看语音编码,发现网上大都只给出了G711的代码,确没有介绍原理,尽管很简单,但直接看代码也是有点摸不着。下面找到了原理进行简要的叙述,并给出了在网上找到的代码。

1.介绍:

G.711

也称为PCM(脉冲编码调制),是国际电信联盟订定出来的一套语音压缩标准,主要用于电话。它主要用脉冲编码调制对音频采样,采样率为8k每秒。它利用一个 64Kbps 未压缩通道传输语音讯号。起压缩率为12即把16位数据压缩成8位。G.711是主流的波形声音编解码器。
   G.711
标准下主要有两种压缩算法。一种是μ-law algorithm (又称often u-law, ulaw, mu-law),主要运用于北美和日本;另一种是A-law algorithm,主要运用于欧洲和世界其他地区。其中,后者是特别设计用来方便计算机处理的。这两种算法都使用一个采样率为8kHz的输入来创建64Kbps的数字输出。G.711采用一种称为分组丢失隐藏(PLC)的技术来减少丢包带来的实际影响。有效的信号带宽在静默期间通过语音活动检测(VAD)这一过程被减小。

2.原理概述:

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)

3.alaw编码规则:

取影响最大的5位(1位为强度位,4位样本位),sign为样本的符号位,同时编码后的数据逢偶数为取补数。即^0xD5。编码表如下,s位符号位正数时s=1。

技术分享

比如pcm=3210(0000 1100 1000 1010)2

1. int sign = pcm & 0x8000) >> 8;

S=1;

2. 取强度位

0001 10010001010

Xs = 100

3. 取高位样本

0  0001 10010001010

wxyz = 1001

4. 結合以上数字

s  xxx wxyz

1   100  1001

5. 逢偶位数取补数

1001001

1  0011100

4.ULaw编码规则:

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

5.代码

//编码  
int CG711Decoder::G711_EnCode(unsigned char* pCodecBits, const char* pBuffer, int nBufferSize)  
{  
    short* buffer = (short*)pBuffer;  
    for(int i=0; i<nBufferSize/2; i++)  
    {  
        pCodecBits[i] = encode(buffer[i]);  
    }  
  
    return nBufferSize/2;  
}   
  
//解码  
int CG711Decoder::G711_Decode(char* pRawData, const unsigned char* pBuffer, int nBufferSize)  
{  
    short *out_data = (short*)pRawData;  
    for(int i=0; i<nBufferSize; i++)  
    {  
        out_data[i] = decode(pBuffer[i]);  
    }  
      
    return nBufferSize*2;  
}  
  
#define MAX (32635)  
unsigned char CG711Decoder::encode(short pcm)  
{  
    int sign = (pcm & 0x8000) >> 8;  
    if (sign != 0)  
        pcm = -pcm;  	//最高位,符号位
    if (pcm > MAX) pcm = MAX;  //max=32635
    int exponent = 7;  
    int expMask;  
    for (expMask = 0x4000; (pcm & expMask) == 0  ///bit14->14-7,找到高字节中第一个不为0的位
        && exponent>0; exponent--, expMask >>= 1) { }  
    int mantissa = (pcm >> ((exponent == 0) ? 4 : (exponent + 3))) & 0x0f;  
    unsigned char alaw = (unsigned char)(sign | exponent << 4 | mantissa);  
    return (unsigned char)(alaw^0xD5);  //11010101
}  
short CG711Decoder::decode(unsigned char alaw)  
{  
    alaw ^= 0xD5;  
    int sign = alaw & 0x80;  
    int exponent = (alaw & 0x70) >> 4;  
    int data = alaw & 0x0f;  
    data <<= 4;  
    data += 8;  
    if (exponent != 0)  
        data += 0x100;  
    if (exponent > 1)  
        data <<= (exponent - 1);  
      
    return (short)(sign == 0 ? data : -data);  
}  
参考:
lITU-TG.711 pdf
lWikipedia: G.711 & A-law
lWikipedia: Mu-law

详细PPT下载(分享自网络):
http://download.csdn.net/detail/guo8113/8587203



G.711编码原理及代码

标签:g711   音频编码   编码原理   g711原理   

原文地址:http://blog.csdn.net/guo8113/article/details/45010955

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!