2.2 编解码器
Speex的主要特性有:
1)免费软件/开源,免专利费和版税
2)利用嵌入比特流集成了窄带和宽带
3)大范围可用比特率(从2.15kbps到44kbps)
4)动态比特率转换(AMR)和可变比特率操作(VBR)
5)声音活动检测(VAD,与VBR集成)和断续传输(DTX)
6)可变复杂度
7)嵌入宽带结构(可伸缩采样率)
8)32kHz超宽带采样率
9)强度立体声编码选项
10)定点实现
2.3 预处理器
这是在1.1.x版本中已经介绍的预处理器模块。预处理器在对音频编码前对音频进行预处理,有三个主要功能:
1)噪声抑制
2)自动增益控制·(AGC)
3)声音活动检测(VAD)
解码器能减少输入信号的背景噪声。预处理能得到高质量语音,而不管降噪后的信号是否通过Speex编码。然而,先降噪再进行编解码是有好处的,因为Speex编解码器通常会对噪声输入同样进行编解码,这将会扩大噪声,而降噪能大大减少这一影响。
自动增益控制(AGC)是为了处理录音音量在不同设置里有很大差别这一问题,AGC将会调整信号音量到参考音量大小。这对网络电话时非常有用的,因为这样就不需要手工调节麦克风增益了。第二个好处是若将麦克风增益设置为较低的等级,更容易避免削波。
预处理器提供的声音活动检测(VAD)比编解码器中直接提供的VAD更先进。
2.4 自适应抖动缓冲器
当通过UDP(User Datagram Protocal,用户数据报协议)或RTP(Real Time Protocal,实时传输协议)传输声音(或其他任何内容)时,数据包可能丢失,不同延时到达,甚至乱序。抖动缓冲器的作用是对数据包进行重排序并保存在足够长的buffer(但有一定限度)里,然后将数据包发送去解码。
2.5 声学回声消除器
在任何免提式通信系统中(图2.1),远端的语音在本地扬声器播放时,经过在房间里传播后又会被麦克风录音。如果将麦克风录音直接又发送到远端,则远端的用户将会听到他自己的回声。声学回声消除器就是为了在将录音发送到远端前消除声学回声。注意回声消除器意味着提高了远端接收的语音质量。
图2.1 声学回声模型
2.6 重采样器
在一些情况下,转换音频的采样率是很有用的,原因有很多,如能混合不同采样率流,能支持声卡不支持的采样率,能转码等。这也是为什么现在重采样器也是Speex项目的一部分的原因。重采样器能在任意采样率间进行转换(采样率必须是有理数),能控制质量和复杂度的折中。
3 编译和端口
在UNIX/Linux或任何其他支持autoconf的平台(如Win32/cygwin)下编译Speex很容易,只需输入
% ./configure [options]
% make
% make install
Speex配置脚本支持的选项有:
-prefix=<path> 指定安装Speex的基本路径(如/usr)
-enable-shared/-disable-shared 是否编译共享库
-enable-static/-disable-static 是否编译静态库
-disable-wideband 禁用Speex的宽带部分(典型地为了节省空间)
-enable-valgrind 为调试启用valgrind(一款用于内存调试内存泄漏检测以及性能分析的软件开发工具)额外的匹配记录(默认不启用)
-enable-sse 启用SSE(Streaming Simd Extensions,指令集)指令(仅支持x86浮点数)
-enable-fixed-point 为没有浮点单元(FPU)的处理器编译Speex
-enable-arm4-asm 启用ARMv4结构配置特性(仅支持gcc)
-enable-arm5e-asm 启用ARMv5E结构配置特性(仅支持gcc)
-enable-fixed-poin-debug 仅调试定点代码(非常慢)
-enable-epic-48k 启用特殊(不兼容)的4.8kbps窄带模型(在1.1.x和1.2beta版本中已损坏)
-enable-ti-c55x 启用对TI C5x系列的支持
-enable-balckfin-asm 启用Blackfin DSP结构配置特性(仅支持gcc)
-enable-vorbis-psycho 使编码器使用Vorbis心理音响学模型,这处于试验阶段,将来可能取消
3.1 平台
Speex可在包括浮点单元和定点单元的许多平台下编译和工作。通常,任何能计算两个16位带符号数乘法(结果是32位)和能在充分地时钟频率下运行(依赖结构)的平台都能运行Speex。已知的Speex的工作平台有(可能还有其他):
1)x86 & x86-64 2)Power 3)SPARC 4)ARM 5)Blackfin 6)Coldfire(68k系列) 7)TI C54xx & C55xx 8)TI C6xxx 9)TriMedia(试验)已知的Speex工作的操作系统有(可能还有其他):
1)Linux 2)uClinux 3)MacOS X 4)BSD 5)其他UNIX/POSIX变体 6)Symbian
源代码目录中README.xxx文件包含在某个平台或操作系统下编译的额外信息。
3.2 端口和优化
以下是在新平台或目前已有平台下配置端口或优化Speex要考虑的一些注意事项。
3.2.1 CPU优化
最影响Speex的CPU使用的是浮点编译还是定点编译。如果你的CPU/DSP没有浮点单元FPU,则定点编译将更快。如果有FPU,则需要测试以下浮点编译和定点编译哪个快。在x86平台中,浮点编译一般更快。为了对Speex定点编译,你需要输入-fixed-point来配置脚本或为编译器定义FIXED-POINT宏。对于1.2beta3版本,现在能禁用浮点兼容的API,这意味着你的代码无需浮点仿真库即可链接,为了达到这一目的,可以通过-disable-float-api配置或定义DISABLE_FLOAT_API宏。等到VBR特性移植到定点,你将需要通过-disable-vbr配置或定义DISABLE_VBR宏。
在一些DSP平台中需要核实的一些事有:1)确定高速缓存被设置为回写式模型;2)如果芯片用SRAM代替高速缓存,确认大量代码处于SRAM而不是RAM中。
如果你要编写汇编,以下函数通常是你必须最先优化的:1)filter_mem16() 2)iir_mem16() 3)vq_nbest() 4)pitch_xcorr() 5)interp_pitch()。滤波器函数filter_mem16()和iir_mem16()应用在转置直接II型(DF2T)。然而对基于乘法累计(MAC)的平台,DF2T需要频繁重装蓄电池,这将使代码非常慢。对于这些平台(如Blackfin和Coldfire),更好的方法是应用这些函数为直接I型(DF1),这在MAC时更容易再装。然而如果这么做,需要确认DF1实现仍能得到像原始DF2T实现一样的滤波器值,这很必要,因为滤波器是时变的并且必须在任何编码器或解码器上直接计算相同的值(不算机器舍入)。
3.2.2 内存优化
内存优化主要是在一些小的嵌入式平台中需要考虑。对于PC,Speex已经足够小,无需内存优化。有几种方法的减少Speex的内存使用,包括代码大小和数据大小。对于优化代码大小,关键是移除你不需要的特性。以下是禁用一些你不需要的特性的例子:1)宽带支持(-disable-wideband);2)立体声支持(移除stereo.c);3)VBR支持(-disable-vbr或DISABLE_VBR);4)你所使用的比特率不要静态码本(*_table.c文件)
Speex也有一些配置临时数组的方法。当使用适当支持C99的编译器时(到2007年,微软编译器不支持,gcc支持),最好定义VAR_ARRAYS,以利用C99的可变大小数组这一特性。下一个最好做的是定义USE_ALLOCA以使Speex能用函数alloca()分配临时数组。注意在许多系统中,alloca()可能无效。如果没有定义VAR_ARRAYS和USE_ALLOCA,则Speex将利用它的内部分配分配一大块”可用空间”,这样的主要缺点是浪费。需要为最坏情况(最坏比特率,最高复杂度设置...)分配足够的栈,默认的,在多个编码器/解码器状态之间内存不共享。最后,如果只能“手动”分配,也有一些方法可以提高。通过复写os_support.h中的speex_alloc_scratch(),可以使所有状态总是返回同一块内存(此时必须特别注意线程)。除此之外,通过重新定义NB_ENC_STACK和NB_DEC_STACKA(宽带类似),可以为提前知道的情况分配内存,此时,需要衡量使用的采样率、比特率和复杂度级别所需的内存数量。