[音频系列]第五章 差分编码,ADPCM与G726

[复制链接]
2450|17
手机看帖
扫描二维码
随时随地手机跟帖
zhanzr21|  楼主 | 2017-6-20 21:43 | 显示全部楼层
本帖最后由 zhanzr21 于 2017-6-20 21:48 编辑

前言
本章介绍另外一个广泛使用的ITU音频算法标准G726.与同G711一样, G726也是由数字电话中的应用而发展而来的语音压缩算法.数字电话应用中,G726经常与G711同时使用以提高带宽利用率.
几个容易混淆的专业名词
DM(DeltaModulation,也写作Δ-modulation): 讲的是一种调制编码思路,即增量调制.比如如下数据:
[1, 2, 3, 100, 0, 2000, 0, 60000]
如果以16 bit的PCM编码传输,需要8x2=16Bytes.如果以DM方式传输,最低只需要1byte: 二进制(11110101).即仅仅传输每个sample与上次的变化趋势.
DPCM(Differential pulse-codemodulation):DM基本同义,但是强调DM在音频,信号处理方面的应用.DPCM在音频编码上的应用是1950年由Bell实验室的C. Chapin Cutler发明的,当然这个专利也早就过期了.


图 当年的专利申请书中的DPCM算法说明
LDM(LinearDelta-Modulation): 讲的是最简单的DM,也就是上述DM例子中的种类.可以说是DM的子集,如果仅仅提到DM,一般指的是LDM.

图 清晰一点的
DM编码与解码算法说明
CVSD/CVSDM(Continuouslyvariable slope delta modulation):LDM的一种发展,LDM的增量描述的步长固定,CVSD的步长可变.CVSD在军用通信中应用较为广泛,因为它能提供可靠的通信质量,但是对计算要求不那么高,很适合在恶劣的环境提供稳定的输出.

ADPCM(Adaptive differential pulse-code modulation): 是CVSD进一步发展,自适应地计算步长.是本文的主角算法.

IMA
(The Interactive MultimediaAssociation): 一个音频处理的行业组织,1998年就停止活动了.IMA的最为人称道的成就就是优化与规范了ADPCM算法的实现标准.目前江湖上的ADPCM也被称为IMAADPCM,但是事实上除了IMAADPCM,也没有其他的广泛实现的ADPCM规范.IMA的规范对于ITU的标准的最大改进就是将对数与浮点运算都优化成了查表与定点版本.这样一来对硬件的要求就大大降低了.

G726
:ITUADPCM的标准,主要从数学角度对算法上进行定义.G726整合了G721G723两个旧标准的内容.G721覆盖的内容为32kbpsADPCM版本.G723覆盖的是24kbps40kbpsADPCM版本.G726在整合G721与G723的基础上又增加了一个16kbps的版本.其中以32kbps的版本使用的最广泛,本文也主要介绍这个版本.看完G711**的读者应该有映像,G711的两种版本都是将13bit/14bit采样的音频压缩到8bit.因为数字电话一般都是8KHz的采样率,所以G711的带宽需求为8K*8bit=64kbps.G726的16kbps,24kbps,32kbps40kbps分别将8bit的采样(一般就是G711的输出,也可以直接是16bit的原始sample)再压缩成2bit,3bit,4bit与5bit.为了不绕口,本文若不另加说明后面讲的都是32kbps也就是4bit一个sample的版本.G727G726内容基本一致,只是讲的ADPCM在另外一种环境下的应用.

为了行文方便,下文如果不另外说明,G726与ADPCM可互相替换.



使用特权

评论回复
zhanzr21|  楼主 | 2017-6-20 21:50 | 显示全部楼层
本帖最后由 21ic小喇叭 于 2017-8-10 10:50 编辑

算法数学公式与实验
为了更好说明ADPCM,也顺便提一下LDM与CVSD.因为这三种算法是逐步发展的概念,且都有很广泛的应用.只是在实际应用中,尤其是民用的音频应用领域,ADPCM是最具知名度的.
LDM
LDM的原理很容易理解,即是把原来每个sample(比如G711的输出:8bit,或者直接是16bit的PCM数据)以一个bit的增量来表示.比如考虑到以下的简单递增8bitPCM序列:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}
如果直接传输或者存储该序列,则需要Lengh*sample_depth的数据量,这个特例中:
DataEntropy = 128 * 8bit = 128 byte
也就是要传输128 byte.但是仔细观察了这个序列就可以得知,每个序列之间的变化只有一个LSB.所以可以将初始值设定为1/2的满幅值,之后每次传输sample之间的增量:1.这样立即得到了8:1的压缩比.
只需传输以下数据序列(byte流表示,第一个sample为初始值):
{ 00, 00, 00, 00, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF}
在解码的时候,遇到bit=0则减,遇到bit=1则增加即可基本完全还原原始数据.


使用特权

评论回复
zhanzr21|  楼主 | 2017-6-20 21:51 | 显示全部楼层

使用特权

评论回复
巧克力娃娃| | 2017-6-23 14:35 | 显示全部楼层

使用特权

评论回复
巧克力娃娃| | 2017-6-23 14:36 | 显示全部楼层
学起来~

使用特权

评论回复
WAMCNCN| | 2017-6-24 16:16 | 显示全部楼层
也就是要传输128 byte.但是仔细观察了这个序列就可以得知,每个序列之间的变化只有一个LSB.所以可以将初始值设定为1/2的满幅值,之后每次传输sample之间的增量:1.这样立即得到了8:1的压缩比.
只需传输以下数据序列(以byte流表示,第一个sample为初始值):

这句怎么理解

使用特权

评论回复
zhanzr21|  楼主 | 2017-6-24 23:41 | 显示全部楼层
WAMCNCN 发表于 2017-6-24 16:16
也就是要传输128 byte.但是仔细观察了这个序列就可以得知,每个序列之间的变化只有一个LSB.所以可以将初始值 ...

哪句 这整段吗
既是说每个sample之间的差值可以用1bit表示 这样就8:1压缩了

使用特权

评论回复
WAMCNCN| | 2017-6-25 19:31 | 显示全部楼层
zhanzr21 发表于 2017-6-24 23:41
哪句 这整段吗
既是说每个sample之间的差值可以用1bit表示 这样就8:1压缩了

8:1压缩可以理解,那个128序列怎么变成 16个序列的

使用特权

评论回复
zhanzr21|  楼主 | 2017-6-25 20:28 | 显示全部楼层
WAMCNCN 发表于 2017-6-25 19:31
8:1压缩可以理解,那个128序列怎么变成 16个序列的

128个byte的序列变成了128个bit,为了书写/存储/传输方便, 故此写成16个byte,写的0xff其实是
11111111
写的0x00就是
00000000
但内容是一样子的,具体操作的时候,每编码8个原始sample存一个byte

使用特权

评论回复
WAMCNCN| | 2017-6-26 09:23 | 显示全部楼层
zhanzr21 发表于 2017-6-25 20:28
128个byte的序列变成了128个bit,为了书写/存储/传输方便, 故此写成16个byte,写的0xff其实是
11111111
写 ...

我知道一个采样用1bit表示,我的问题是序列1中的样品编码成1bit时,什么时候用1或0表示。增量调制时,后面比前面大用1表示。序列1是128个采样,序列2是16个字节即16*8==128bit.这128bit对应着序列1。序列1编码成序列2有点不明白。下面这句话:每个序列之间的变化只有一个LSB.所以可以将初始值设定为1/2的满幅值,之后每次传输sample之间的增量:1。这个1/2满幅值是多少?序列1要跟这个值比增量编码成序列2吗?

使用特权

评论回复
zhanzr21|  楼主 | 2017-6-26 12:05 | 显示全部楼层
WAMCNCN 发表于 2017-6-26 09:23
我知道一个采样用1bit表示,我的问题是序列1中的样品编码成1bit时,什么时候用1或0表示。增量调制时,后 ...

对 你理解是对的 你可以看看我共享文件夹中的LDM测试的源代码

所谓1/2满幅度在这里就是最大幅度与最小幅度的中点, 如果是有符号的输出, 那么这个中点当然为0, 但是我那实验中为0-127的变化范围, 则中点为(0+127)/2=63(取整). 这个中点当做初始的预测值, 去跟第一个序列中的每个sample进行比较, 比较的结果要么是0要么是1就是要输出的结果bit流, 同时也要更新预测值.

你看那个图就知道, 因为这个预测值因为刚开始是63, 但是实际情况是0开始的, 这样开头有一段预测不准的. 刚开始取值怎样都不重要,取1/2满幅度是最合理的猜测, 因为实际音频数据对于算法来说是随机的, 只是这个特例中如果刚开始将预测值初始化为0就能得到最佳结果, 但不属于算法之内考虑的因素.

使用特权

评论回复
WAMCNCN| | 2017-6-27 12:49 | 显示全部楼层
zhanzr21 发表于 2017-6-26 12:05
对 你理解是对的 你可以看看我共享文件夹中的LDM测试的源代码

所谓1/2满幅度在这里就是最大幅度与最小幅 ...

如果序列1采样跟63比的话,是不是编码成序列2的前一半都是00。序列2为{00,00,00,00,00,00,00,00,FF,FF,FF,FF,FF,FF,FF,FF}
和文中不符,这是我迷惑的地方。

使用特权

评论回复
WAMCNCN| | 2017-6-27 12:49 | 显示全部楼层
zhanzr21 发表于 2017-6-26 12:05
对 你理解是对的 你可以看看我共享文件夹中的LDM测试的源代码

所谓1/2满幅度在这里就是最大幅度与最小幅 ...

如果序列1采样跟63比的话,是不是编码成序列2的前一半都是00。序列2为{00,00,00,00,00,00,00,00,FF,FF,FF,FF,FF,FF,FF,FF}
和文中不符,这是我迷惑的地方。

使用特权

评论回复
WAMCNCN| | 2017-6-27 12:49 | 显示全部楼层
zhanzr21 发表于 2017-6-26 12:05
对 你理解是对的 你可以看看我共享文件夹中的LDM测试的源代码

所谓1/2满幅度在这里就是最大幅度与最小幅 ...

如果序列1采样跟63比的话,是不是编码成序列2的前一半都是00。序列2为{00,00,00,00,00,00,00,00,FF,FF,FF,FF,FF,FF,FF,FF}
和文中不符,这是我迷惑的地方。

使用特权

评论回复
zhanzr21|  楼主 | 2017-6-27 16:08 | 显示全部楼层
预测值63一路减下来都是0, 32那个位置与实际值相交了, 实际上预测值减小到比原始信号小一个LSB, 后面的信号因为原始信号一直递增, 预测值也一直跟随所以都是1

因为只有1个bit表示增加还是减小, 所以有的地方是 >就是1, <=就是0, 也有的地方前面是>=, 后面是<, 但影响甚小

这个看后文的直流实验就可看出, 对直流信号就只能小幅度震荡来跟随了

使用特权

评论回复
zhanzr21|  楼主 | 2017-6-27 16:09 | 显示全部楼层
网站这几天抽风, 容易多发重复贴子

使用特权

评论回复
jeson81| | 2017-7-4 10:45 | 显示全部楼层
WAMCNCN 发表于 2017-6-24 16:16
也就是要传输128 byte.但是仔细观察了这个序列就可以得知,每个序列之间的变化只有一个LSB.所以可以将初始值 ...

都是大神,膜拜!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:每天都進步

91

主题

1005

帖子

34

粉丝