语音编码分成波形编码、参数编码和混合编码.波形编码就是语音信号形成的波形进行处理和加工,参数编码是以语音信号产生的数字模型为基础,求出其模型参数,然后按照这些参数还原数字模型,合成语音。混合编码是综合了波形编码和参数编码的长处,在4-16kbps的速率上进行高质量的语音合成。例如多脉冲激励线性预测编码(MPLPC),码本激励线性预测编码(CELP)都是混合编码。
人耳的听觉范围在20-20KHZ,根本抽样定律要保证声音不失真,就必须用44KHZ左右采样频率,但是人说话的范围在300-3400HZ,所以就用8KHZ主要对人声采样。
波形编码前,首先对模拟语音信号进行采样,然后对采样结果进行幅度量化,再进行二进制编码。
参数编码则是对数字模型的参数进行求值,目前常用的是无损声管离散时间模型,该模型综合了人声的最重要三个因素:声门,激励和辐射。这三个因素都可以用数学函数表达。再加上在语音信号的非均匀性和相关性,非均匀性表现在小幅度信号出现的概率较大,相关性表现在相邻的两个样本点相关和相隔基音周期之间的两个样本点也相关。线性预测就时利用了相关性从原来的语音信号计算出现在的信号。而且人在正常的交谈中有50%的时间是静音,只在听对方讲话,语音检测VAD就是用来判断是否是静音,而柔和噪声再生CNG就是用来产生一个“好听”的静音传给对方,
G.729与G.723是ITU制定的适用于IP电话语音编码,因为其高质量,低码率而得到广泛应用,下面分别做介绍:
G.729是ITU制定通过的8kbps的语音编码协议,换算成字节才1k,它采用共轭结构的算术码激励线性预测(CS-ACELP)。
G.723也是ITU制定的,不过它是双速率语音编码,它可以工作在5.3kbps和6.3kbps两个方式上,相应分别采用代数码激励线性预测(ACELP)和多脉冲最大似能量化(MP-MLQ)。
在ITU上注册一个帐号便可以下载现实的C源代码和描述文档,在VC 6下编译并运行,却发现编码效率太低,编码时间基本上是优化后5-6倍。ITU的源代码中采用的是最基本的运算,而且没有做过任何优化,所以效率极度低下。在优化之前先推荐一款调试软件DevPartner Studio Professional,它能进行错误分析和性能分析,功能强大,操作简单。
通过DevPartner对源代码进行分析发现无论是G.729还是G.723大部分运算都集中在basic_op.c的函数中,basic_op.c里面都是些基本运算,L_mac(),L_mult(),L_add()和sature()又占用basic_op.c中的绝大部分运算。所以优化也应该集中在这几个函数中。在basic_op.c有个溢出标志位overflow,很多基本函数多对其判断浪费了很多时间,其实可以直接去掉,使用时直接判断结果时候为最大值即可知道是否溢出,对basic_op.c的函数采用MMX指令优化,使用其饱和特性可以减掉很多判断溢出的操作,
下面给出一个加法的例子
Word16 add(Word16 var1,Word16 var2)
{
_asm{
movd mm0,var1;
movd mm1,var2;
paddsw mm0,mm1;
movd eax,mm0;
emms;
}
}
源代码中太多的函数调用,比如L_mac就调用了L_mult和L_add函数,如果直接把L_mult和L_add代码填入L_mac中则可以省去很多函数调用浪费的时间,ITU的代码中为了详细的描述算法有很多类似循环没有合并,将其合并也可以提高效率,并且有些在循环体内的运算也可以提到循环体外,对于用For()控制的循环次数最好使用参数,这样编译器可以将循环解开。
因为本人能力和精力有限,仅仅是在源代码的层面上对G.729和G.723进行优化,不过也取得了相当可观的效果,优化后的效率比优化前提高了一倍,如果再做更深层次的算法优化相信会有更高的提升。