Speex之一-介紹Speex
介紹Speex
Speex編解碼器(www.speex.org)存在是因為有這麼一個需求,即是開源同時專利版權也是免費的。這應該也是各開源軟體的必要條件。本質上講,Speex是針對語音的,vorbis是針對語音/音樂的。不像很多基它編碼,Speex不是為移動手機設計的,而是為網絡和VOIP應用設計的。文件壓縮當然也技持。Speex設計得很靈活,支持很寬範圍的語音質量和比特率。支持非常好的語音也意味著Speex能夠編碼窄帶語音(電話質量,8kHz采樣率)也能編碼寬帶語音(16kHz采樣率)。代替移動手機,為VOIP設計意味著Speex對丟包是魯棒的,而不是損壞的。這是基於假設在網絡環境下,包可能到達了也或者根本沒到達。因為Speex定位是廣泛的設備,所以它是複雜度可調和占內存小的。這全部的設計目標使之選擇了CELP作為編碼技術。一個主要的原因是是CELP已經被證明其可靠性,並且能夠很好的擴展到低比特率(如DOD CELP 4.8kbps)和高比特率(如G.728 16 kbps)。
Speex之二-编码描述及相关概念
编码描述
这一章节将描述Speex更为详细特征
2.1. 概念
在介绍全部Speex特征之前,这里有一些语音编码的概念以帮助更好地理解本手册。虽然有一些是语音/音频处理的概念,其它是特殊于Speex的(译得怪怪的)
采样率
采样率使用赫茲(hz)表示,是每一秒钟信号采样的个数。以采样率Fs kHz为例,其最高频率等于Fs/2 kHz(Fs/2 被称为Nyquist频率)。这是信号处理的基本属性,也通过采样定理被描述。Speex 主要被设计为三个不同的采样率:8kHz,16kHz,32kHz。这些分别称为窄带、宽带、超宽带。
质量(可变的)
Speex是一种有损编解码器,这意味着它压缩开支在输入语音信号的保真度。不像其它语音编解码器,Speex是可以权衡质量与比特率的。很多时候通过一个从0到10的质量参数来控制Speex编码器。在固定比特率(CBR)操作,质量参数是一个整形,而可变比特率(VBR)其质量参数为浮点型。
复杂度(可变的)
Speex编码器复杂度是可变的。这是用一个从1到10的整形来完成对它的控制,这类似于使用-1到-9设置gzip和bzip2压缩工具。复杂度1的噪声水平在1到2分贝之间要高于复杂度10,但复杂度10的CPU要求大约是复杂度1的5倍。在实践中,最好的折衷是在复杂度2到4,尽管当非讲话声音如DTMF,更高的设置经常是有用的。
可变比特率(VBR)
可变比特率允许一个编解码器根据不同的语音动态自适应地变化比特率。以Speex为例,声音像元音和高能量瞬时要求一个更高的比特率去达到好的质量,而编码摩擦音(如 s,f发音)会适当较少比特。因此VBR能达到在相同的质量下更低的比特率,或者在相同的比特率下更好的质量。尽管有以上的优点,但VBR有两个主要的缺点:一个是只能指定质量,但不能保证最终平均比特率。另一个是在一些实时应用中像VOIP,最大比特率必须满足通讯通道。
平均比特率(ABR)
平均比特率解决了VBR其中的一个问题,为了满足一个明确的目标比特率,用它来动态调节VBR质量。因为质量/比特率是实时调节的,所以全局质量将会稍微低于设置满足于目标平均比特率的VBR质量。
语音活动性检测(VAD)
当使能语音活动性检测功能,将检测被编码的语音是讲话或静音/背景噪声。当编码为VBR时VAD总是暗中活动,所以设置只在非VBR有效。在这种情况,Speex在检测非讲话周期和足够的比特率下重建背景噪声,这称为舒适噪声生成(GNG)
间断传输(DTX)
间断传输是除了VAD/VBR的一个操作,它允许当只有固定背景噪声时完全停止传输。在文本模式操作,由于我们不能停止写文件,所以每帧只能使用5比特(相当于250bps)
感知加强
感知加强是解码器的一部分,开启该功能时试图通过编码/解码处理降低噪声的感知。在很多情况下,感知加强从客观上会使声音与源声音相关更大(只从信噪比角度考虑),但最终声音从主观上会更好。
延迟与算法延迟
第一个语音编解码都会介绍传输的时延。Speex的时延等于一帧时间加上处理每一帧向前看需要的时间。窄带(8kHz)的时延是30ms,而宽带(16kHz)是34ms。这些值不计编码或解码所花费CPU的时间。
2.2. 预处理器
这部分参考预处理模型介绍1.1.x分支。预处理器的设计是运行于编码器之前的。预处理器提供了三个主要的功能:
(1)噪声抑制(NS)
(2)自动增益控制(AGC)
(3)活动性检测(VAD)
插图1 回音消除模型
噪声抑制(NS)
噪声抑制器能被用于在发送之前降低输入信号的背景噪声的数量。提供更高质量的语音是否噪声抑制信号或者是根本。无论怎样使用降噪信号是有益的。一般语音编解码(包括Speex)对噪声输入的处理是不足的,会趋向于放大噪声。噪声抑制器很大地降低了这一影响。
自动增益控制(AGC)
自动增益控制是处理面对录音因为大量不同设置而导致音量变化。AGC提供了一种方式去调整参考音量。这在VOIP中是很有用的,因为不需再手动调节麦克风的增益。还有另外一个优点是麦克风增益在一个比较保守的水平,它更容易避免削波、失真。
语音活动性检测(VAD)
通过预处理提供的语音活动性检测(VAD)会比直接由编解码器提供的更为高级。
2.3 自适应抖动缓冲
当使用UDP或RTP传输语音时,包可能会有丢包、不同时延甚至错序。抖动缓冲的目的就是重排包和缓冲,它们是足够长的(但又不能超过所需),所以他们被发送去解码。
2.4. 语音回音消除器
在任何一个免提通讯系统中(插图1),远端的语音被本地场声播放,传播到整个房间并且被麦克风所采集。如果抓取麦克风的语音直接发送给麦克风,那么远端用户会听到他自己的回声。一个语音回音消除器的设计是在发送去远端之前移除回声。去理解回声消除器意味着改善远端质量是很重要的。
2.5. 重采样
有些情况,转换一个语音的采样率是很有用的。这有很多原因。比如,它能混合不合采样率的流,支持声卡不支持的采样率。这是为什么重采样是Speex工程的一部分。这个重采样能用于转换两个任意采样率(比例必须只能是有理数),而且可以通过权衡质量与复杂度去控制它。
Speex之三-编译和移植
编译和移植
通过自动配置在UNIX/Linux或其它平台支持(如Win32/cywin)编译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指令(只在 x86/浮点)
-enable-fixed-point 编译Speex为无浮点单位(FPU)处理器
-enable-arm4-asm 启用汇编指定为ARMv4架构(只在gcc)
-enable-arm5e-asm 启用汇编指定为ARMv5E架构(只在gcc)
-enable-fixed-point-debug 只使用调试定点码(非常慢)
-enable-epic-48k 启用一个专门(不兼容)4.8kbps窄带模式(在1.1.x和1.2beta)
-enable-ti-c55x 启用支持TI C5x族
-enable-blackfin-asm 启动汇编指定为Blackfin DSP架构
-enable-vorbis-psycho 使编码器使用Vorbis心理学模型。这是非常实验性,可能在将来会被移除
3.1 平台
Speex是众所周知可在大量架构上编译和运行的,包括浮点和定点。一般只要架构能够自然地计算两个有符号16位数(32位结果)的相乘,和运行足够的时钟率,就能够运行Speex。下面是Speex知道能运行的架构(可能还可以运行于很多其它架构):
Speex也有一些方法去分配暂时数组.当使用支持C99属性的编译器(自2007年起,微软编译器不支持了,但GCC支持),最好这定义VAR_ARRAYS. 使用C99的变化长度数组时,最好定义USE_ALLOCA已致Speex能使用alloc()去分配暂时数组. 注意在很多系统, alloca()是BUG所以它可能不能工作. 如果没有定义VAR_ARRAYS和USE_ALLOCA,那Speex将回落分配一个很大的暂时空间,并让它成为自己的内部空间.这解决方案主要的缺点就是太浪费了.它需要为最坏的情况(最坏的比特率、最高的复杂度设置...)分配够的栈空间,而且默认不共享多个编码器/解码器之间的内存。如果只剩下手动分配唯一的设置,仍有一些东西能被改善的,通过重写os_support.h文件里面的speex_alloc_scratch()调用,它总是可以返回相同的内存区域。除些之外,通过重定义NB_ENC_STACK和NB_DEC_STACK(或相似宽带)可以只为已知优势的方案下分配内存。在这种情况,可以为明确的采样率,比特率和复杂度水平测量内存需要的数量。
Speex的基本描述包括一个命令行编码器和解码器. 那些工具产生和读包装在OGG容器的Speex文件.虽然它是可以封装Speex在任意容器的,但Ogg被推荐为文件的容器的.本段描述如何为Ogg的Speex文件使用命令行工具
4.1 speexenc
Speexenc单元是通过裸PCM或wave文件被使用于创建Speex文件. 可使用下面命令:
speexenc [操作] input_file output_file
值input_file和output_file分别对应stdin和stdout
有效的设置:
–narrowband(-n) 告诉Speex视输入信号为窄带(8kHz),这是默认的
–wideband (-w) 告诉Speex视输入信号为宽带(16khz)
–ultra-wideband (-u) 告诉Speex视输入信号为超宽带(32khz)
–quality n 设置编码质量(0-10),默认为8
–bitrate n 编码比特率(使用比特率小于等于n)
–vbr 开启VBR(可变比特率),默认关闭
–abr n 开启ABR(平均比特率)在n kbps,默认关闭
–vad 开启VAD(语音活动性检测),默认关闭
–dtx 开启DTX(间断性传输),默认关闭
–nframes n 打包n帧到每一个ogg包中(这节省了空间)
–comp n 设置编码速度/质量权衡.n的值越高,编码越慢(默认为3)
-V 冗长的操作,打印当前使用的比特率
–help (-h) 打印帮助
–version (-v) 打印版本信息
Speex内容:
–comment 增加被给的字符串作为额外内容.这可以会被使用多次.
–author 作者
–title 题目
裸输入设置:
–rate n 裸输入的采样率
–stereo 认为裸输为立体声的
–le 裸输入是小端的
–be 裸输入是大端的
–8bit 裸输入是8位无符号的
–16bit 裸输入是16位有符号的
4.2 speexdec
Speex解码单位被使用于解码Speex文件. 使用被使用能过调用:
speexdec [操作] speex文件 [输出文件]
当没有指定输出文件,文件将通过声卡播放.
有效设置是:
–enh 开启post-filter(默认)
–no-enh 关闭post-filter
–force-nb 强制使用窄带解码
–force-wb 强制使用宽带解码
–force-uwb 强制使用超宽带解码
–mono 强制使用单声道解码
–stereo 强制使用立体声解码
–rate n 强制使用nHz采样率解码
–packet-loss 模拟n%的随机丢包
–V 冗长的操作,打印当前使用的比特率
–help (-h) 打印帮助
–version (-v) 打印版本信息