这里大致介绍解码的过程
本文先暂时跳过静音压缩与舒适背景噪声,以及丢包处理等
基本上掌握了编码原理,理解解码过程是非常快的,很多函数
都在编码时分析过了
Line_Unpk 按itu定义这个是解网络数据包
Lsp_Inq 这个是反量化lsp系数,在编码的时候,我们分析过了(^_^)
Lsp_Int 这个是lsp插值,在编码的时候,我们分析过了(^_^)
到此为止,得到了4组lpc系数,综合滤波器就得到了,差的就是激励了
下面这一步也是必须的,用于下一帧lsp插值
/* Copy the LSP vector for the next frame */ //lsc 更新历史值,用于下一次反量化插值
for ( i = 0 ; i < LpcOrder ; i ++ )
DecStat.PrevLsp[i] = LspVect[i] ;
然后是一个循环,根据传过来的参数,解出每个子帧的激励,由两部分构成,
自适应激励,低速率时的固定码本激励,高速率时的多脉冲激励
先取出自适应激励的初始码本(解由前一帧数据时保存下来的)
/*
* Generate the excitation for the frame
*/
for ( i = 0 ; i < PitchMax ; i ++ )
Temp[i] = DecStat.PrevExc[i] ;
Dpnt = &Temp[PitchMax] ;//lsc temp保存的历史的145个激励,因为自适应码本需要这么多历史激励
接下来解出激励,
固定码本激励解码/多脉冲激励解码,基本上是解一个bit流,经常做网络协议的朋友很容易读懂相应的代码,
不多分析了
/* Generate the fixed codebook excitation for a
subframe. (Text: Section 3.5) */
Fcbk_Unpk( Dpnt, Line.Sfs[i], Line.Olp[i>>1], (Word16) i ) ;//lsc 解出固定码本激励或者多脉冲激励
解码自适应激励,这个在编码时分析过了(^_^)
/* Generate the adaptive codebook excitation for a
subframe. (Text: Section 3.4) */
Decod_Acbk( AcbkCont, &Temp[SubFrLen*i], Line.Olp[i>>1],
Line.Sfs[i].AcLg, Line.Sfs[i].AcGn ) ;//lsc 解出自适应激励
两个激励成份相加,类似的代码我们在编码时也看到过了
/* Add the adaptive and fixed codebook contributions to
generate the total excitation. */
for ( j = 0 ; j < SubFrLen ; j ++ ) {
Dpnt[j] = shl( Dpnt[j], (Word16) 1 ) ;
Dpnt[j] = add( Dpnt[j], AcbkCont[j] ) ;//lsc 激励依次存放到temp
}
接下来跳过一大段后置滤波的代码片段,留待下一节与静音压缩等一块儿分析
有了lpc系数,以及激励,做个滤波算法,就可以收工了
滤波器的系统函数是我们非常熟悉的,在itu文档中,它就是公式2
/* Compute the synthesized speech signal for a subframe.
* (Text: Section 3.7)
*/
Synt( Dpnt, &QntLpc[i*LpcOrder] ) ;
分析完毕
注:笔者在这一系列的文章中多次提到的itu文档 T-REC-G.723.1-200605-I!!SOFT-ZST-C.zip
这个可以在itu的主面上下载到,g系列,g723就是了,熟悉723的朋友对这些资料的下载不会陌生(^_^)
林绍川
2011.10.11 于杭州