本文对 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 中有大量的表格,那些值是怎么得到的,其中某些值的含义又是什么。如果读者了解其中详情或是发现文章中有理解错误的地方,还请多多赐教!