G.711编码原理及代码

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

1.介绍:

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)这一过程被减小。

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);
}  

参考:

lhttp://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-G.711-198811-I!!PDF-E&type=items

lITU-TG.711 pdf

lhttp://en.wikipedia.org/wiki/G.711

lWikipedia: G.711 & A-law

lhttp://en.wikipedia.org/wiki/Mu-law

lWikipedia: Mu-law

lhttp://72.14.235.104/search?q=cache:CIgTx4nuxeQJ:telecom.tbi.net/pcm1.html+mu-law+Comparison+with+A-law&hl=zh-TW&ct=clnk&cd=5&gl=tw

详细PPT下载(分享自网络):

http://download.csdn.net/detail/guo8113/8587203

时间: 2024-11-08 23:55:42

G.711编码原理及代码的相关文章

G.711是一种由国际电信联盟(ITU-T)制定的音频编码方式

http://zh.wikipedia.org/zh-cn/G.711 ITU-T G.711 page ITU-T G.191 software tools for speech and audio coding, including G.711 C code Code Project C# implementation of G.711 with source code G.711是一种由国际电信联盟(ITU-T)制定的音频编码方式,又称为ITU-T G.711. 基本信息编辑 它是国际电信

BASE64编码原理与Golang代码调用

一.概念简介 Base64是一种基于64个可打印字符来表示二进制数据的表示方法.由于2^6=64,所以每6个比特为一个单元,对应某个可打印字符.3个字节有24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示.它可用来作为电子邮件的传输编码.在Base64中的可打印字符包括字母A-Z.a-z.数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同. Base64常用于在通常处理文本数据的场合,表示.传输.存储一些二进制数据 二.代码调用 在Golang中提供了

Base64加密解密原理以及代码实现(VC++)

Base64加密解密原理以及代码实现 转自:http://blog.csdn.net/jacky_dai/article/details/4698461 1. Base64使用A--Z,a--z,0--9,+,/ 这64个字符.    2. 编码原理:将3个字节转换成4个字节( (3 X 8) = 24 = (4 X 6) )先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了.    3. 解码原理:将4个字节转换成3个字节.先读入4个6位(用或运算),每次左移6位

Java Base64加密、解密原理Java代码

Java Base64加密.解密原理Java代码 转自:http://blog.csdn.net/songylwq/article/details/7578905 Base64是什么: Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045-RFC2049,上面有MIME的详细规范.Base64编码可用于在HTTP环境下传递较长的标识信息.例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为

BASE64编码原理分析脚本实现及逆向案例

BASE64编码原理分析脚本实现及逆向案例 0x01 简单介绍 数据传送时并不支持所有的字符,很多时候只支持可见字符的传送.但是数据传送不可能只传送可见字符为解决这个问题就诞生了base64编码.base64编码将所有待编码字符转换成64个可见字符表中的字符. 0x02 编码原理 被Base64编码之后所得到的所有字符都是在以下这个表当中的. 上表中总共有64个字符,2^6=64所以只需要6个bit位就足够描述所有的表中字符了.计算机中1个字节8个bit,一个ASCII码占1个字节.因此多出来的

一篇文章彻底弄懂Base64编码原理

在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理又了解多少?今天这篇博文带领大家了解一下Base64的底层实现. Base64的由来 目前Base64已经成为网络上常见的传输8Bit字节代码的编码方式之一.在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后再进行签名或加密,之后再进行(或再次Base64)传输.那么,Base64到底起到什么作用呢? 在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会出现

知识扩展——(转)一篇文章彻底弄懂Base64编码原理

在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理又了解多少?今天这篇博文带领大家了解一下Base64的底层实现. 一.Base64的由来 目前Base64已经成为网络上常见的传输8Bit字节代码的编码方式之一.在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后再进行签名或加密,之后再进行(或再次Base64)传输.那么,Base64到底起到什么作用呢? 在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会

Atitit.Base64编码原理与实现设计

Atitit.Base64编码原理与实现设计 1. Base64编码1 1.1. 为什么要用自己的base64编码方案1 2. Base64编码由来1 3. Base64编码原理1 3.1. 具体来说,转换方式可以分为四步:2 3.2. 注意2 3.3. Padding3 4. URL安全的Base64编码3 1. Base64编码 1.1. 为什么要用自己的base64编码方案 防止apache codec  jdk的jar冲突. 2. Base64编码由来 Base64最早是用来解决电子邮件

flume原理及代码实现

转载标明出处:http://www.cnblogs.com/adealjason/p/6240122.html 最近想玩一下流计算,先看了flume的实现原理及源码 源码可以去apache 官网下载 下面整理下flume的原理及代码实现: flume是一个实时数据收集工具,hadoop的生态圈之一,主要用来在分布式环境下各服务器节点做数据收集,然后汇总到统一的数据存储平台,flume支持多种部署架构模式,单点agent部署,分层架构模式部署,如通过一个负载均衡agent将收集的数据分发到各个子a