资源描述
在VOIP音频算法中,回音解决已经成为一种关系通话质量重要问题。
回声产生在IP网络重要有两种:
1.声学回声
2.电路回声
声学回声重要又提成如下几种:
a ) 直接回声:由扬声器产生声音未经任何反射直接进入麦克风
b ) 间接回声:由扬声器发出声音通过多次反射后,再进入Mic
对于第二种回声,拥有多途径,时变性特点.是比较难解决.
由于IP网络下传播延迟较大,而普通状况下,对于人耳,如果声音延迟达到了10ms以上话,那么回声就会越来越明显.
普通来讲,VOIP中声音延迟重要来自于几种方面:
1. 编码延迟:普通状况下编码算法在声音压缩时都会产生延迟,就咱们采用Speex来讲,延迟大概在20ms左右
2. 解决延迟,封装时延,缓冲时延等
3. 在IP网络中数据传播过程也会照成延时.这由当前网络状况决定.
回声消除模型:
a) 建立远端声音模型,进行回声预计,从采集值中减去预计值
b) 声学模型
Speex是一套专门用于压缩声音库,由于其专门针对声音,因此压缩声音性能非常高.Speex由于其压缩性能,及0.80版后跨平台性能,因此在网络声音传播中有很大价值.但是需要注意是speex只能对声音进行压缩,不支持音乐压缩,如果你需要音乐压缩你或许需要用vorbis库.
但是speex资料像其他大都数专用库同样,并没有大多中文资料.因此在这里我决定将里面最核心编程技术翻译出来.一来是练习练习自己翻译资料能力,二来是以便某些英语水平较差朋友.由于本人能力有限,有些感觉有出入或难理解地方可以去speex官方网站.org找到英文原版阐明.
1,speex简介(略)
2特性描述
这个章节展示了speex重要特性,以衣某些关于对话(speech)编码一种概念,以便协助咱们更好理解下一章节.
取样率(Sampling rate)
Speex重要是设计了三种不同取样率:8kHz,16kHz,32kHz.这些分别代表了窄宽(narrowband),多频率,超声.
质量
Speex编码大都数时间是被一种范畴为0到10质量参数来控制 .在一种比特率为常量(CBR)操作中,质量参数是一种整数,而对于变动比特率(VBR)参数是一种float;
复杂性(变量)
用speex,你可以将编码设立成容许复杂度.这由一种范畴为1到10整数来控制完毕,就像你用选项-1到-9来控制gzip和bzip2压缩质量.在普通运用中,噪声级别复杂度1是在1到2dB之间,比复杂度10要高,但是CPU需要复杂度10大概5倍高行复杂度1.在实践中,最佳是设立在2到4之间,尽管更高设定普通有用,当编码一种非对话声音(non-speech sounds)像DTMF语调(tones).
变波特率(VBR
Variable bit-rate (VBR) allows a codec to change its bit-rate dynamically to adapt to
变波特率(VBR)容许编码动态地变化它波特率以适应声音编码”难度”.在speex举例来说,
像元音(vowel)和瞬间高音(high-enenrg transients)需要个高比特率来获得一种不错质量,而摩擦音(fricative)可以被充分地用相对较少字节来进行编码.由于上面这个因素,VBR可以调节到一种低比特率却达到一种同样质量,或者用某个比特率达到更好质量.尽管有上面这些长处,但是VBR也有两个重要缺陷.一方面,仅仅靠指定质量值,这里没有一种关于最后平均比特率保证.(译者注:作者大概是想说没有什么明确办法懂得质量值)此外,对某些即时通信,像IP电话(VoIP)这种包括着最大比特率,必要把比特率设为足够低以适应传播通道.
平均比特率(ABR)
平均比特率通过动态地调节VBR质量去得到一种拟定目的比特率,从而解决了VBR中一种问题..由于质量/比特率被即时调节了,整体质量将会稍稍低于由VBR对一种
设立得和目的平均比特率非常接近质量数编码得到成果.
声音生动性检测(VAD)
声音生动性检测将会发现音频正在被编码成对话,静音,或背景噪音.VAD总在用VBR进行编码时暗中起作用,因而选项仅仅对一种不是VBR操作起作用.对于不是VBR操作来说,speex察觉出一种不属于对话周期,然后对它用足够字节重新生成为背景噪音.不这叫做舒服噪音生成(CNG).
不持续传播(DTX)
不持续传播是VAD/VBR操作一种额外选项,当背景噪音一定期,它可以完整地传播.由于在基于文献操作中,咱们不能停止对文献进行写入,因此只有5字节被这种帧所运用.(给250bps通信)
Algorithmic delay
迟时算法
每一种声音编码导致了在传播上延时.对于speex,这种延时等于frame大小加上某些数量需要对每一帧进行前瞻(”look-adhead”).在窄宽操作中(8kHz),迟时是30ms,而对于多频率(2-44Hz),迟时是34ms.这些值不涉及CPU编码,解码帧时间.
4.1 Encoding
4.1压缩
为了用Speex压缩对话,你一方面需要引用头文献:
#include <speex.h>
然后你需要定义一种Speex位采集(bit-packing)构造
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_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而不会导致溢出最大数.nbBytes是一种实际写入btye_ptr数,即编码实际大小在调用speex_bits_write前,也许你需要调用speex_bits_nbytes(&bits)得到需要写入(write)字节大小.
在你已经编码后,释放所有资源.
speex_bits_destroy(&bits);
speex_encoder_destroy(enc_state);
That’s about it for the encoder.
这就是关于编码方面.
Speex manul中文版三
附源代码翻译:
B Sample code
B 例程源代码
这个章节演示了一段用speex编码,解码对话(speech)源代码.
可以如下用api命令来编码并解码一种文献:
译者注:这里说api命令是指unix用”|”进行管道写入读出.在windows下这样并不能实现.
% sampleenc in_file.sw | sampledec out_file.sw
这里这两段代码都没有引用其他头文献,并以16 比特率(bits)进行编码
natural endianness).
B.1 sampleenc.c
Sameleenc 用一种未加工16比特率(bits)文章,给它编码并产生一种speex 流(steam)给原则输出.注意已压缩和speexenc/speexdec不和谐!
#include <speex.h>
#include <stdio.h>
#define FRAME_SIZE 160
int main(int argc,char **argv)
{
char *inFile;
FILE *fin;
short in[FRAME_SIZE];
float input[FRAME_SIZE];
char cbits[200];
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_QUALITY,&tmp);
inFile = argv[1];
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;i<FRAME_SIZE;i++)
input[i]=in[i];
//清空这个构造体里所有字节,以便咱们可以编码一种新帧
speex_bits_reset(&bits);
//对帧进行编码
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);
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,而大小为160
filter_length,最佳是房间内反射时间1/3
如:一种房间反射时延为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,也可以通过preprocessor 来控制
问题核心是 解决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这个参数设立为噪音参数.
我相信在大多数状况下,都是由于声音捕获和声音播放之间同步问题没有解决好,导致音频质量下降。
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(数字信号)时采样频率,也就是单位时间内采样多少点。一种采样点数据有8(甚至更多)个比特。
采样率越高音质也就越高,文献就越大。
比特率
比特率是指每秒钟传送比特数,在语音信号编码时,表达语音数据每秒钟需要多少个比特表达,单位为bps(比特/秒)或kbps(千比特/秒)。注意区别kbps和kBps(千字节/秒)。
质量(可变)
Speex是一种有损编解码库,这意味着它文档压缩方面会导致语音输入信号失真,和某些语音编解码库不同是,它尽量去控制质量和比特率之间平衡。大多数时候,是用一种0到10范畴内质量参数来控制Speex编码,比特率为常量操作,质量参数是整数,如果是变比特率(VBR),则为浮点数(Float)
复杂度(可变)
在Speex中,编码器可调节复杂度。用1到10整数来控制如何执行搜索,就像用-1到-9来设立压缩工具gzip或bzip2(博主注:设计压缩块长度,为100k~900k)。正常状况下,复杂度为1时噪声级会比复杂度为10时高1~2 dB(分贝),而复杂度为10CPU需求是复杂度为15倍。实践证明,最佳将复杂度设立在2~4,设立较高则对非语音编码如双音多频(DTMF)音质较为有用。
变比特率(VBR)
变比牲率(VBR)容许编解码器动态调节比特率以适应音频解码“难度”,拿Speex来说,像元音和瞬间高音则需较高比特率(Bit-rate)来达到最佳效果,而摩擦音则用较少比特(bits)即可完毕编码。基于这种因素,变比特率(VBR)可以用较低比特率(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),比特率越高,传送数据越大。声音中比特率是指将数字声音由模仿格式转化成数字格式采样率,采样率越高,还原后音质就越好。 视频中比特率(码率)原理与声音中相似,都是指由模仿信号转换为数字信号采样率。
展开阅读全文