1、在VOIP音频算法中,回音解决已经成为一种关系通话质量重要问题。回声产生在IP网络重要有两种:1.声学回声2.电路回声声学回声重要又提成如下几种:a ) 直接回声:由扬声器产生声音未经任何反射直接进入麦克风b ) 间接回声:由扬声器发出声音通过多次反射后,再进入Mic对于第二种回声,拥有多途径,时变性特点.是比较难解决.由于IP网络下传播延迟较大,而普通状况下,对于人耳,如果声音延迟达到了10ms以上话,那么回声就会越来越明显.普通来讲,VOIP中声音延迟重要来自于几种方面:1. 编码延迟:普通状况下编码算法在声音压缩时都会产生延迟,就咱们采用Speex来讲,延迟大概在20ms左右2. 解决延
2、迟,封装时延,缓冲时延等3. 在IP网络中数据传播过程也会照成延时.这由当前网络状况决定.回声消除模型:a) 建立远端声音模型,进行回声预计,从采集值中减去预计值b) 声学模型Speex是一套专门用于压缩声音库,由于其专门针对声音,因此压缩声音性能非常高.Speex由于其压缩性能,及0.80版后跨平台性能,因此在网络声音传播中有很大价值.但是需要注意是speex只能对声音进行压缩,不支持音乐压缩,如果你需要音乐压缩你或许需要用vorbis库.但是speex资料像其他大都数专用库同样,并没有大多中文资料.因此在这里我决定将里面最核心编程技术翻译出来.一来是练习练习自己翻译资料能力,二来是以便某些
3、英语水平较差朋友.由于本人能力有限,有些感觉有出入或难理解地方可以去speex官方网站.org找到英文原版阐明.1,speex简介(略)2特性描述这个章节展示了speex重要特性,以衣某些关于对话(speech)编码一种概念,以便协助咱们更好理解下一章节.取样率(Sampling rate)Speex重要是设计了三种不同取样率:8kHz,16kHz,32kHz.这些分别代表了窄宽(narrowband),多频率,超声.质量Speex编码大都数时间是被一种范畴为0到10质量参数来控制.在一种比特率为常量(CBR)操作中,质量参数是一种整数,而对于变动比特率(VBR)参数是一种float;复杂性(
4、变量)用speex,你可以将编码设立成容许复杂度.这由一种范畴为1到10整数来控制完毕,就像你用选项-1到-9来控制gzip和bzip2压缩质量.在普通运用中,噪声级别复杂度1是在1到2dB之间,比复杂度10要高,但是CPU需要复杂度10大概5倍高行复杂度1.在实践中,最佳是设立在2到4之间,尽管更高设定普通有用,当编码一种非对话声音(non-speech sounds)像DTMF语调(tones).变波特率(VBRVariable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to变波特率(
5、VBR)容许编码动态地变化它波特率以适应声音编码”难度”.在speex举例来说,像元音(vowel)和瞬间高音(high-enenrg transients)需要个高比特率来获得一种不错质量,而摩擦音(fricative)可以被充分地用相对较少字节来进行编码.由于上面这个因素,VBR可以调节到一种低比特率却达到一种同样质量,或者用某个比特率达到更好质量.尽管有上面这些长处,但是VBR也有两个重要缺陷.一方面,仅仅靠指定质量值,这里没有一种关于最后平均比特率保证.(译者注:作者大概是想说没有什么明确办法懂得质量值)此外,对某些即时通信,像IP电话(VoIP)这种包括着最大比特率,必要把比特率设为
6、足够低以适应传播通道.平均比特率(ABR)平均比特率通过动态地调节VBR质量去得到一种拟定目的比特率,从而解决了VBR中一种问题.由于质量/比特率被即时调节了,整体质量将会稍稍低于由VBR对一种设立得和目的平均比特率非常接近质量数编码得到成果.声音生动性检测(VAD)声音生动性检测将会发现音频正在被编码成对话,静音,或背景噪音.VAD总在用VBR进行编码时暗中起作用,因而选项仅仅对一种不是VBR操作起作用.对于不是VBR操作来说,speex察觉出一种不属于对话周期,然后对它用足够字节重新生成为背景噪音.不这叫做舒服噪音生成(CNG).不持续传播(DTX)不持续传播是VAD/VBR操作一种额外选
7、项,当背景噪音一定期,它可以完整地传播.由于在基于文献操作中,咱们不能停止对文献进行写入,因此只有5字节被这种帧所运用.(给250bps通信)Algorithmic delay迟时算法每一种声音编码导致了在传播上延时.对于speex,这种延时等于frame大小加上某些数量需要对每一帧进行前瞻(”look-adhead”).在窄宽操作中(8kHz),迟时是30ms,而对于多频率(2-44Hz),迟时是34ms.这些值不涉及CPU编码,解码帧时间.4.1 Encoding4.1压缩为了用Speex压缩对话,你一方面需要引用头文献:#include 然后你需要定义一种Speex位采集(bit-pac
8、king)构造SpeexBits bits;and a Speex encoder state以及定义一种speex编码器状态量void *enc_state;上面定义这样被初始化:The two are initialized by:speex_bits_init(&bits);enc_state = speex_encoder_init(&speex_nb_mode);为了支持多频率压缩,speex_nb_mode将被sppex_wb_mode取代.在大都数状况下,你需要懂得你用模式(mode)帧(frame)大小,你可以得到在frame_size变量里得到这值:speex_encoder
9、_ctl(enc_state,SPEEX_GET_FRAME_SIZE,&frame_size);一但初始化完毕,对于每一种输入帧:speex_bits_reset(&bits);speex_encode(enc_state,input_frame,&bits);nbBytes = speex_bits_write(&bits,byte_ptr,MAX_NB_BYTES);上面input_frame是一种指向对话(speech)帧(frame)float指针(pointing);byte_ptr是指向编码帧开始写地方char指针,MAX_NB_BYTES是能写进byte_ptr而不会导致溢出最
10、大数.nbBytes是一种实际写入btye_ptr数,即编码实际大小在调用speex_bits_write前,也许你需要调用speex_bits_nbytes(&bits)得到需要写入(write)字节大小.在你已经编码后,释放所有资源.speex_bits_destroy(&bits);speex_encoder_destroy(enc_state);Thats about it for the encoder.这就是关于编码方面.Speex manul中文版三附源代码翻译:B Sample codeB例程源代码这个章节演示了一段用speex编码,解码对话(speech)源代码.可以如下用a
11、pi命令来编码并解码一种文献:译者注:这里说api命令是指unix用”|”进行管道写入读出.在windows下这样并不能实现.% sampleenc in_file.sw | sampledec out_file.sw这里这两段代码都没有引用其他头文献,并以16比特率(bits)进行编码natural endianness).B.1 sampleenc.cSameleenc用一种未加工16比特率(bits)文章,给它编码并产生一种speex流(steam)给原则输出.注意已压缩和speexenc/speexdec不和谐!#include #include #define FRAME_SIZE
12、160 int main(int argc,char *argv) char *inFile; FILE *fin; short inFRAME_SIZE; float inputFRAME_SIZE; char cbits200; int nbBytes; void *state; SpeexBits bits; int i,tmp; /新建一种新编码状态在窄宽(narrowband)模式下 state = speex_encoder_init(&speex_nb_mode); /设立质量为8(15kbps) tmp=8; speex_encoder_ctl(state,SPEEX_SET_
13、QUALITY,&tmp); inFile = argv1; fin = fopen(inFile,r); /初始化构造使她们保存数据 speex_bits_init(&bits); while (1) /读入一帧16bits声音 fread(in,sizeof(short),FRAME_SIZE,fin); if (feof(fin) break; /把16bits值转化为float,以便speex库可以在上面工作 for (i=0;iFRAME_SIZE;i+)inputi=ini;/清空这个构造体里所有字节,以便咱们可以编码一种新帧speex_bits_reset(&bits);/对帧进
14、行编码speex_encode(state,input,&bits);/把bits拷贝到一种运用写出char型数组nbBytes = speex_bits_write(&bits,cbits,200);/一方面写出帧大小,这是sampledec文献需要一种值,但是你应用程序中也许不同样fwrite(&nbBytes,sizeof(int),1,stdout);/写出压缩后数组fwrite(cbits,1,nbBytes,stdout);/释放编码器状态量speex_encoder_destroy(state);/释放bit_packing构造speex_bits_destroy(&bits);
15、fclose(fin);return 0;如何使用Speex中AEC模块,提高声音质量?在Speex(.org)最新版本中,开始集成了回音消除模块,而回音消除始终是Voip之中亟待解决重要问题。诸多朋友和我说speexaec模块效能并不好,咱们先来看一下speexaecapi调用方式。SpeexEchoState *echo_state = speex_echo_state_init(frame_size,filter_length);frame_size 取值最佳是一种编码frame大小, 在低带宽条件下,普通延迟20ms,而大小为160filter_length,最佳是房间内反射时间1/3
16、如:一种房间反射时延为300ms 那么这个filter_length就最佳是100ms(这个长度又被称为tail length).而其中filter_length设定是一种核心。speex_echo_cancel(echo_state,input_frame,echo_frame,output_frame,residue);其中:input_frame:就是被声卡捕获到声音echo_frame:是由扬声器播放出声音,这个声音是需要从 input_frame中抵消声音.output_frame 是解决完后来输出声音residue是一种可选参数,如果不使用可以将之设立为NULL,也可以通过prep
17、rocessor 来控制问题核心是 解决input和echo 之间关系,也就是说在捕获到信号和播放信号之间延迟必要足够小,才可以提高效率.writetosndcard(echo_frame,frame_size)readfromsndcard(input_frame,frame_size)speex_echo_cancel(echo_state,input_frame,echo_frame,output_frame,residue)如果你想要尽量减小信号中回音,那么可以将residue这个参数设立为噪音参数.我相信在大多数状况下,都是由于声音捕获和声音播放之间同步问题没有解决好,导致音频质量下
18、降。speex_echo_state_destroy(echo_state);speex_echo_state_reset(echo_state);不再复述了!阐明:据说在Speex最新1.2beta版本上,Speex提供了可选取,简化API,来提高echo执行过程中同步问题。2.1概念采样率采样率是指从持续信号中每秒钟采集到采样数量。用Fs kHz来表达,最高频率可表达为Fs/2 kHz(见奈奎斯特Nyquist频率)。Speex重要设计了三种不同采样率:8kHz,16kHz和32kHz。分别表达了窄带、宽带和超宽带。采样率是指将声音(模仿信号)转换成mp3(数字信号)时采样频率,也就是单位
19、时间内采样多少点。一种采样点数据有8(甚至更多)个比特。采样率越高音质也就越高,文献就越大。比特率比特率是指每秒钟传送比特数,在语音信号编码时,表达语音数据每秒钟需要多少个比特表达,单位为bps(比特/秒)或kbps(千比特/秒)。注意区别kbps和kBps(千字节/秒)。质量(可变)Speex是一种有损编解码库,这意味着它文档压缩方面会导致语音输入信号失真,和某些语音编解码库不同是,它尽量去控制质量和比特率之间平衡。大多数时候,是用一种0到10范畴内质量参数来控制Speex编码,比特率为常量操作,质量参数是整数,如果是变比特率(VBR),则为浮点数(Float)复杂度(可变)在Speex中,
20、编码器可调节复杂度。用1到10整数来控制如何执行搜索,就像用-1到-9来设立压缩工具gzip或bzip2(博主注:设计压缩块长度,为100k900k)。正常状况下,复杂度为1时噪声级会比复杂度为10时高12 dB(分贝),而复杂度为10CPU需求是复杂度为15倍。实践证明,最佳将复杂度设立在24,设立较高则对非语音编码如双音多频(DTMF)音质较为有用。变比特率(VBR)变比牲率(VBR)容许编解码器动态调节比特率以适应音频解码“难度”,拿Speex来说,像元音和瞬间高音则需较高比特率(Bit-rate)来达到最佳效果,而摩擦音则用较少比特(bits)即可完毕编码。基于这种因素,变比特率(VB
21、R)可以用较低比特率(bit-rate)达到相似效果或使用某比特率(bit-rate)质量会更好。尽管它有这些优势,但VBR也有两个重要缺陷:一方面,它只是针对质量,却没办法保证最后平均比特率(ABR);另一方面,在某些实时应用如VOIP电话中,尽管拥有高比特率(bit-rate),为适应通信信道还是需要恰当减少。平均比特率(ABR)平均比特率(ABR)通过动态调节变比特率(VBR)质量来获得一种特定目的比特率,解决了VBR中存在问题之一。由于平均比特率(ABR)是实时(开环)调节质量/比特率(bit-rate),整体质量会略低于通过变比特率(VBR)设立接近于目的平均比特率进行编码获得质量。静音检测(VAD)静音检测(VAD)将检测被编码音频数据是语音还是静音或背景噪声。这个特性在用变比特率(VBR)进行编码是总是启动,因此选项设立只对非变比特率(VBR)起作用。在这种状况下,Speex检测非语音周期并对用足够比特数重新生成背景噪声进行编码。这个叫“舒服噪声生成(CNG)”。比特率是指每秒传送比特(bit)数。单位为 bps(Bit Per Second),比特率越高,传送数据越大。声音中比特率是指将数字声音由模仿格式转化成数字格式采样率,采样率越高,还原后音质就越好。 视频中比特率(码率)原理与声音中相似,都是指由模仿信号转换为数字信号采样率。