单独编译和使用webrtc音频回声消除模块(附完整源码+测试音频文件)
单独编译和使用webrtc音频降噪模块(附完整源码+测试音频文件)
单独编译和使用webrtc音频增益模块(附完整源码+测试音频文件)
说实话很不想写这篇文章,因为这和我一贯推崇的最好全部编译并使用webrtc音频处理模块相悖。可是不知不觉已经把降噪和增益写出来,回声消除如果用户可以得到完美利用也不失为一个很好的方法。但是还是那句话,最好还是全部编译和使用webrtc的整个音频处理模块。另外这篇文章已经不单单的回声消除模块了,其中包括了降噪,增益,静音检测,如果有需要可以选择其中的一部分单独提取调试。
相对而言回声消除比起其他模块要复杂很多,不光光是计算量大(之前在一部380MHz的摄像头中测试过,其消耗的时间为降噪的三倍以上,如果音频延迟更大甚至根本跑不起来),而且其中也涉及到一个delay的计算,delay计算是否精确完全影响回声消除的效果。
至于delay的计算,网上有很多说明,有复杂也有简单的。在这里我还是简单的提一下:

这张图很多东西可以无视,我们重点看T0,T1,T2三项。
T0代表着声音从扬声器传到麦克风的时间,这个时间可以忽略,因为一般来说话筒和扬声器之间距离不会太远,考虑到声音340米每秒的速度,这个时间都不会超过1毫秒。
T1代表远处传到你这来的声音,这个声音被传递到回声消除远端接口(WebRtcAec_BufferFarend)的到播放出来的时间。一般来说接收到的音频数据传入这个接口的时候也就是上层传入扬声器的时刻,所以可以理解成该声音防到播放队列中开始计时,到播放出来的时间。
T2代表一段声音被扬声器采集到,然后到被送到近端处理函数(WebRtcAec_Process)的时刻,由于声音被采集到马上会做回声消除处理,所以这个时间可以理解成麦克风采集到声音开始计时,然后到你的代码拿到音频PCM数据所用的时间。
好了,delay=T0+T1+T2,其实也就是T1+T2。
一般来说,一个设备如果能找到合适的delay,那么这个设备再做回声消除处理就和降噪增益一样几乎没什么难度了。从网上看iPhone的固定delay是60ms,不过不确定,MacBook挂了,在等四季度新MacBook上市,所以暂时没办法做验证。
因为回声消除过程,可以理解成已经把蓝黑两种颜色的墨水完全混合,然后分离出来所需要的蓝色或者黑色颜色。事实上完全混在一起的音频数据是无法彻底分开的,但是我们可以把混在一起的声音理解成两段声音,其中有一段声音可以找到一段几乎相近的对比原声,然后在混音中找到和原声近似的数据,这样就可以分离了。delay的意义显而易见就是要把原声和混在一起的声音数据作对比时,校正时刻所用,这个时刻越是精确,那么回声消除的效果越好。不过从实际效果来看这个delay也并不需要特别精确,在这段测试音频数据里面范围可以接近100毫秒。

从两段音频波形起始位置看delay的时间应该超过100毫秒,那么可以用一段代码做测试,测试代码和音频文件来自于网上:
int WebRtcAecTest()
{
#define NN 160
short far_frame[NN];
short near_frame[NN];
short out_frame[NN]; void *aecmInst = NULL;
FILE *fp_far = fopen("speaker.pcm", "rb");
FILE *fp_near = fopen("micin.pcm", "rb");
FILE *fp_out = fopen("out.pcm", "wb"); do
{
if(!fp_far || !fp_near || !fp_out)
{
printf("WebRtcAecTest open file err \n");
break;
} WebRtcAec_Create(&aecmInst);
WebRtcAec_Init(aecmInst, , ); AecConfig config;
config.nlpMode = kAecNlpConservative;
WebRtcAec_set_config(aecmInst, config); while()
{
if (NN == fread(far_frame, sizeof(short), NN, fp_far))
{
fread(near_frame, sizeof(short), NN, fp_near);
WebRtcAec_BufferFarend(aecmInst, far_frame, NN);//对参考声音(回声)的处理 WebRtcAec_Process(aecmInst, near_frame, NULL, out_frame, NULL, NN,1,);//回声消除
fwrite(out_frame, sizeof(short), NN, fp_out);
}
else
{
break;
}
}
} while (); fclose(fp_far);
fclose(fp_near);
fclose(fp_out);
WebRtcAec_Free(aecmInst);
return ;
}
源码下载(VS2010编译版本,也可以移植到其他平台无缝编译):WebRtcAudioAllTest.rar
单独编译和使用webrtc音频回声消除模块(附完整源码+测试音频文件)的更多相关文章
- 单独编译和使用webrtc音频降噪模块(附完整源码+测试音频文件)
单独编译和使用webrtc音频增益模块(附完整源码+测试音频文件) 单独编译和使用webrtc音频回声消除模块(附完整源码+测试音频文件) webrtc的音频处理模块分为降噪ns,回音消除aec,回声 ...
- 单独编译和使用webrtc音频增益模块(附完整源码+测试音频文件)
webrtc的音频处理模块分为降噪ns和nsx,回音消除aec,回声控制acem,音频增益agc,静音检测部分.另外webrtc已经封装好了一套音频处理模块APM,如果不是有特殊必要,使用者如果要用到 ...
- webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错:
webRTC中回声消除(AEC)模块编译时aec_rdft.c文件报错. 原因是: 局部变量ip跟全局变量冲突的问题,可以将局部变量重新命名一下,就可以通过编译了. aec_rdft.c修改以后文件代 ...
- 编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码
转自:编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码 JDK:java version “1.8.0_31”Java(TM) SE Runtime Environment ( ...
- Speex Acoustic Echo Cancellation (AEC) 回声消除模块的使用
背景:回声与啸叫的产生 http://blog.csdn.net/u011202336/article/details/9238397 参考资料: http://www.speex.org/doc ...
- VS2010版的Speex音频处理模块(附源码+测试demo)
开源的Speex代码内部包含了VS2003,05,08工程,但是直接编译总有一些要设置的地方,虽说也不是很复杂,但是对于不是很了解VS的同学来说还是要折腾一阵,所以我弄了一个可以直接使用的版本,当然是 ...
- 简洁明了的插值音频重采样算法例子 (附完整C代码)
近一段时间在图像算法以及音频算法之间来回游走. 经常有一些需求,需要将音频进行采样转码处理. 现有的知名开源库,诸如: webrtc , sox等, 代码阅读起来实在闹心. 而音频重采样其实也就是插值 ...
- 一种简单高效的音频降噪算法示例(附完整C代码)
近期比较忙, 抽空出来5.1开源献礼. 但凡学习音频降噪算法的朋友,肯定看过一个算法. <<语音增强-理论与实践>> 中提及到基于对数的最小均方误差的降噪算法,也就是LogMM ...
- HTML5音频(自定义mp3播放器源码)
audio对象 src兼容.ogg .wav .mp3 <audio controls src='data/imooc.wav'></audio> width autoplay ...
随机推荐
- ES6(阮一峰)对象的扩展
1.属性的简洁表示法 允许直接写入变量和函数,作为对象的属性和方法. const foo = 'bar'; const baz = {foo};//等同于 const baz = {foo : &qu ...
- jq 手机键盘消失出现白色延迟
input 输入框失去焦点 $("#input").blur() 接口调用setTimeout 让输入框消失后再出现loading和调用接口 ios手机loading覆盖不完全 自 ...
- zabbix 发送邮件到企业微信
#!/usr/bin/python2.7#_*_coding:utf-8 _*_#auther:拿来用用import requests,sys,jsonimport urllib3urllib3.di ...
- “二维数组”?
首先说明C中是不存在所谓的"多维数组"的. int array[a][b]:声明的是一个有a个元素的数组,每个数组元素是一个含b个元素的数组. 上述声明正确的说法是,数组的数组. ...
- CF 1076E Vasya and a Tree(线段树+树剖)
传送门 解题思路 首先按照每个修改时\(x\)的深度\(+d\)从大到小排序,然后按照深度分层,一层一层的修改,修改的时候就直接暴力修改子树,然后每做完一层把答案都取下来,因为以后的所有修改的深度都小 ...
- hdu2089数位DP
旁听途说这个名字很久了,了解了一下. 改题目的意思是给你若干区间,让你找寻区间内不含62或4的数. 首先暴力必然T...那么实际上就是说,想办法做一种预处理,在每次输入的时候取值运算就可以了. 既然是 ...
- 深入理解PHP原理之Opcodes(PHP执行代码会经过的4个步骤是什么)
深入理解PHP原理之Opcodes(PHP执行代码会经过的4个步骤是什么) 一.总结 一句话总结: 1.Scanning(Lexing) ,将PHP代码转换为语言片段(Tokens) 2.Parsin ...
- EF 关键字
https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/query-keywords 子句 说明 from ...
- (转载)前端构建工具gulpjs的使用介绍及技巧
本文转载自:https://www.cnblogs.com/2050/p/4198792.html gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API ...
- 剑指offer——66翻转字符串
题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,“student ...