本文对G.722.1的解码器作以介绍,如有表述不当之处欢迎批评指正。欢迎任何形式的转载,但请务必注明出处。
前述
上篇文章《音频编解码之G7221编码器》介绍了G.722.1的编码器部分,这篇文章介绍其解码器部分。
简介
- G.722.1是一种基于变换域编码的算法
- 采样率: 16000hz
- 比特率: 24kbit/s 32kbit/s
- 变换域: MLT(Modulated Lapped Transform)
- 帧长: 20ms
- 变换窗长: 40ms
- 有效编码带宽: 50~7000hz
解码器
解码器先对每个区域的幅度包络进行解码,然后使用与编码器同样的方式产生16种不同的编码方法,再通过分类控制比特确定编码器所选用的编码方法,最后对MLT系数解码重建。
1. 解码幅度包络
接收到码流中的前5个比特表示第0个区域幅度包络的量化索引 r m s _ i n d e x ( 0 ) rms\_index(0) rms_index(0),通过查表的方式解码出
d i f f _ r m s _ i n d e x ( r ) , 1 ≤ r < 14 diff\_rms\_index(r), 1\leq{r}<14 diff_rms_index(r),1≤r<14
并通过以下方式得到其他区域幅度包络的量化索引
r m s _ i n d e x ( r ) = r m s _ i n d e x ( r − 1 ) + d i f f _ r m s _ i n d e x ( r ) , 1 ≤ r < 14 , 1 ≤ r < 14 rms\_index(r) = rms\_index(r-1) + diff\_rms\_index(r), 1\leq{r}<14, 1\leq{r}<14 rms_index(r)=rms_index(r−1)+diff_rms_index(r),1≤r<14,1≤r<14
然后通过 r m s _ i n d e x ( r ) rms\_index(r) rms_index(r)得到区域的幅度包络 r m s ( r ) rms(r) rms(r)。
2. 确定编码类型
使用与编码器中相同的方法,生成16种不同的编码方法,并通过分类控制比特确定编码器所使用的编码方法。
3. 解码MLT系数
通过查表解码得到 v e c t o r _ i n d e x ( v ) vector\_index(v) vector_index(v),并通过下式得到MLT系数的量化索引
k ( j ) = ⌊ v e c t o r _ i n d e x ( v ) ( k m a x + 1 ) l ⌋ M O D ( k m a x + 1 ) k(j)=\lfloor\frac{vector\_index(v)}{(kmax+1)^{l}}\rfloor MOD(kmax+1) k(j)=⌊(kmax+1)lvector_index(v)⌋MOD(kmax+1)
其中 M O D MOD MOD为取余操作
j = ( v + 1 ) v d − l − 1 j=(v+1)\bm{vd}-l-1 j=(v+1)vd−l−1 0 ≤ l ≤ v d − 1 0\leq{l}\leq{\bm{vd}-1} 0≤l≤vd−1 0 ≤ v ≤ v p r − 1 0\leq{v}\leq{\bm{vpr}-1} 0≤v≤vpr−1
上面式子中所用到的变量可在编码器一文中找到对应的定义。为什么对 v e c t o r _ i n d e x vector\_index vector_index经过上面式子的运算就能得到 k k k哪,先回顾一下编码器一文中的式子
v e c t o r _ i n d e x ( v ) = ∑ l = 0 v d − 1 k ( v ∗ v d + l ) ( k m a x + 1 ) v d − ( l + 1 ) vector\_index(v)=\sum_{l=0}^{\bm{vd}-1}{k(v*\bm{vd}+l)(kmax+1)^{\bm{vd}-(l+1)}} vector_index(v)=l=0∑vd−1k(v∗vd+l)(kmax+1)vd−(l+1)
这个式子是由 k k k得到 v e c t o r _ i n d e x vector\_index vector_index, 正好与前一个式子相反。下面举个例子详细说明一下这两个互为“逆”的式子。
假设给区域0分配的类别值是0,那么由编码器一文可知,该区域在编码阶段将包含10个矢量,每个矢量包含2个标量,以第2个矢量 [ k ( 2 ) , k ( 3 ) ] [k(2), k(3)] [k(2),k(3)]为例, 可知 v = 1 v=1 v=1, v d = 2 \bm{vd}=2 vd=2, k m a x = 13 kmax=13 kmax=13, 带入上式可得
v e c t o r _ i n d e x ( 1 ) = k ( 1 ∗ 2 + 0 ) ∗ ( 13 + 1 ) 2 − ( 0 + 1 ) + k ( 1 ∗ 2 + 1 ) ∗ ( 13 + 1 ) 2 − ( 1 + 1 ) vector\_index(1)=k(1*2+0)*(13+1)^{2-(0+1)}+k(1*2+1)*(13+1)^{2-(1+1)} vector_index(1)=k(1∗2+0)∗(13+1)2−(0+1)+k(1∗2+1)∗(13+1)2−(1+1)
化简之后可得
v e c t o r _ i n d e x ( 1 ) = k ( 2 ) ∗ 14 + k ( 3 ) vector\_index(1)=k(2)*14+k(3) vector_index(1)=k(2)∗14+k(3)
现在知道了如何由 k ( 2 ) k(2) k(2)和 k ( 3 ) k(3) k(3)得到 v e c t o r _ i n d e x ( 1 ) vector\_index(1) vector_index(1),那么再通过之前的那个式子看如何由 v e c t o r _ i n d e x ( 1 ) vector\_index(1) vector_index(1)得到 k ( 2 ) k(2) k(2)和 k ( 3 ) k(3) k(3),
l = 0 ⇒ ⌊ v e c t o r _ i n d e x ( 1 ) ( 13 + 1 ) 0 ⌋ M O D ( 13 + 1 ) = k ( 3 ) l=0 \rArr \lfloor\frac{vector\_index(1)}{(13+1)^{0}}\rfloor MOD(13+1)=k(3) l=0⇒⌊(13+1)0vector_index(1)⌋MOD(13+1)=k(3)
l = 1 ⇒ ⌊ v e c t o r _ i n d e x ( 1 ) ( 13 + 1 ) 1 ⌋ M O D ( 13 + 1 ) = k ( 2 ) l=1 \rArr \lfloor\frac{vector\_index(1)}{(13+1)^{1}}\rfloor MOD(13+1)=k(2) l=1⇒⌊(13+1)1vector_index(1)⌋MOD(13+1)=k(2)
通过这个式子相信大家明白了 k k k和 v e c t o r _ i n d e x vector\_index vector_index之间是如何互相计算得到的。计算出MLT系数的量化索引 k ( j ) k(j) k(j)之后,将 k ( j ) k(j) k(j)映射到表1所对应的值,然后将该值与解码得到的幅度包络 r m s ( r ) rms(r) rms(r)相乘得到MLT系数幅度,并按照符号比特设置非零系数的符号。
4. 噪声填充
没有对类别为7 的区域的MLT系数幅度进行编码,解码时将其用噪声代替。在编码类别为5和6的区域时,由于量化步长较大,因此也有许多系数被量化为了0,解码时同样将其用噪声代替。这些噪声由于符号随机、幅度与 r m s ( r ) rms(r) rms(r)成比例的系数值代替。表2规定了比例常数。
5. 欠缺的比特
编码时,可能编码器在完成最后一个非类别7区域的编码之前比特已经不够用了。这种情况下,解码器将该区域以及剩余的所有区域当成类别7作处理。
6. 丢帧补偿
解码器若获知当前帧丢失,则使用前一帧已解码的MLT系数。若前一帧也丢失,解码器将当前帧的MLT系数全部置为0。
7.逆MLT 变换
将MLT系数转换到时域,这儿不具体介绍公式。
8.总结
磕磕绊绊花了一天多的时间终于写完了,这其实是笔者1年前的工作了, 有好多细节得重新回忆,可能还有好多地方理解地不对。笔者在刚开始学习G.722.1编解码器的时候有好多细节不懂,至今也是。比如生成16种编码方法的具体做法,以及为什么要那样做,其次就是G.722.1中有大量的表格,那些值是怎么得到的,其中某些值的含义又是什么。如果读者了解其中详情或是发现文章中有理解错误的地方,还请多多赐教!