单独编译使用WebRTC的音频处理模块 - android
单独编译使用WebRTC的音频处理模块 - android
转载自: http://billhoo.blog.51cto.com/2337751/1213801附言
WebRTC是时下比较热门的新技术,由于bill接触时间尚短,对该项目的理解和认知定存在不足甚或偏差,文中有描述不当之处还望各位悉心指出,感激不尽。
前言
最近一直在捣腾如何在android和iOS上使用Google的WebRTC——一个无疑大力推动了互联网即时通信以及VoIP发展的开源项目。
虽然WebRTC主要目标是为互联网提供高质量的富媒体即时通信,但其源码为C/C++所写,且其开发版中也包含对android和iOS等移动设备的支持,因此对于如今飞速发展的移动互联网,WebRTC也能推波助澜大显神通。
WebRTC提供一套音频处理引擎VOE(本文不涉及视频处理引擎VIE),但VOE在android和iOS上的整体编译一直是一个比较繁琐且恼火的问题,于是单独提取了VOE中的NS(Noise Suppression噪声抑制)、VAD(Voice Activity Detection静音检测)、AECM(Acoustic Echo Canceller for Mobile声学回声消除)以及AGC(Auto Gain Control自动增益控制)等模块进行编译并捣鼓其使用方法。
经过自己两月有余的捣腾和测试,终于在android和iOS上成功编译出各模块并在项目中使用了NS/VAD/AECM三大模块,效果比较不错。
回过头来看看,这几大模块的编译其实非常简单,不过两月前的自己也着实为这个花了一番力气。
正文
由于几大模块的编译方式相同,故本文仅以NS模块为例,其余模块请读者自行摸索和实验。
Step 1 - 下载google WebRTC源码
WebRTC目前的开发版主线版本已经到了r4152 - 3.32,但这几大模块并未有大的修改,故本文依旧按bill当时的版本3.31进行讲解,请自行使用SVN同步以下目录(至于同步的方法,请自行google):
http://webrtc.googlecode.com/svn/branches/3.31/
Step 2- 提取WebRTC - NS模块代码
同步源码后,进入目录\webrtc\modules\audio_processing\ns,将NS模块的源码拷贝出来,下面是单独编译NS时的参考源码列表(部分头文件在WebRTC项目其他目录下,请自行搜索提取):
defines.h
signal_procession_library.h
spl_inl.h
typdefs.h
windows_private.h
fft4g.h / fft4g.c
noise_suppression.h / noise_suppression/c
ns_core.h / ns_core.c
除了上述WebRTC源码外,如果要在android的Java代码中使用,还需自行编写JNI包装文件:
ns_jni_wrapper.c(此为自定义的jni包装文件,详情请见此文)
ADDED(billhoo - 2013-6-14)鉴于有朋友询问JNI Wrapper的编写,下面提供NS模块create以及initialize函数(这两个函数足以说明问题)的wrapper源码及注释,希望对大家有所帮助。更详细的编写步骤请参考 Oracle官方文档 或此文或此文。
WebRtcNs_Create包装函数及注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /*** * Summary * types: * NSinst_t : the type of noise suppression instance structure. * NsHandle : actually the same type of NSinst_t, defined in * "noise_suppression.h" as a empty struct type named * "NsHandleT". * * Note: * 1.You have no need to pass env and jclazz to these functions, * cus' JVM will does it for you. * 2.We only support 10ms frames, that means you can only input 320 * Bytes a time. **/ /** * This function wraps the "WebRtcNs_Create" function in "noise_suppression.c". * Input: * none. * Output: * the handler of created noise suppression instance. * Return value: * -1 : error occurs. * other value : available handler of created NS instance. * * @author billhoo * @version 1.0 2013-1-29 */ JNIEXPORT jint JNICALL Java_你的类限定名_createNSInstance(JNIEnv *env, jclass jclazz) { NsHandle *hNS = NULL; //create a pointer to NsHandle on native stack. if (WebRtcNs_Create(&hNS) == -1) { //allocate dynamic memory on native heap for NS instance pointed by hNS. return -1; //error occurs } else { return (( int ) (NSinst_t *) hNS); //returns the address of NS instance on native heap. } } |
WebRtcNs_Initiate包装函数及注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /** * This function wraps the "WebRtcNs_Init" function in * "noise_suppression.c". * Initializes a NS instance and has to be called before any other * processing is made. * * Input: * - nsHandler - Handler of NS instance that should be * initialized. * - sf - sampling frequency, only 8000, 16000, 32000 * are available. * Output: * nsHandler - the handler of initialized instance. * Return value: * 0 - OK * -1 - Error * * @author billhoo * @version 1.0 2013-1-29 */ JNIEXPORT jint JNICALL Java_你的类限定名_initiateNSInstance(JNIEnv *env, jclass jclazz, jint nsHandler, jlong sf) { NsHandle *hNS = (NsHandle*) nsHandler; return WebRtcNs_Init(hNS, sf); } |
[END OF ADDED]
Step 3- 编译WebRTC - NS模块
此步请参照bill之前的文章将刚才提取的NS代码添加进eclipse工程进行编译即可。以下为NS模块的Android.mk文件:
1 2 3 4 5 6 7 8 9 | LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := webrtc_ns LOCAL_SRC_FILES := \ noise_suppression.c \ ns_core.c \ fft4g.c \ ns_jni_wrapper.c include $(BUILD_SHARED_LIBRARY) |
编译完成后,将项目中的webrtc_ns.so动态库拷贝出来以备后续使用。
Step4- 加载编译好的NS模块动态库
接下来只需要按照此文的描述在android的JAVA代码中使用刚才编译好的webrtc_ns.so动态库便大功告成。
Step 5- 几大模块的使用及注意事项
前四步已经完成了几大音频处理模块在android上的单独编译过程,并分别生成了webrtc_ns.so、webrtc_vad.so、webrtc_aecm.so以及webrtc_agc.so四个动态库,下面bill简要介绍对NS、VAD以及AECM三个库的函数使用方法及注意事项:
5.1 -NS库函数的使用及注意事项
这个很简单,参照noise_suppression.h头文件中对各API的描述即可,首先使用WebRtcNs_Create创建NS实体,然后WebRtcNs_Init初始化该实体,WebRtcNs_set_policy设置噪声抑制的级别(bill使用的是最高级别 2,效果比较理想),设置完成后便可调用WebRtcNs_Process循环对10ms(8000Hz、16000Hz)音频帧进行NS处理,注意最后别忘了调用WebRtcNs_Free将NS实体销毁。
5.2 -VAD库函数的使用及注意事项
VAD的使用和NS区别不大,唯一需要注意的是VAD仅仅只是检测,返回结果1表示VAD检测此帧为活动帧,0表示此帧为静音帧,至于判断为静音后该进行何种处理,就和你自己的项目相关了。
5.3 -AECM库函数的使用及注意事项
AECM实体的创建、初始化和销毁工作与上述相同,之后需要在远端和近端分别调用WebRtcAecm_BufferFarend以及WebRtcAecm_Process,对于AECM的使用,需要注意的重点在于Process函数的参数msInSndCardBuf,该参数在audio_procession.h头文件中以名为delay的变量呈现,该延迟的计算确为一难点(对于单独使用AECM模块来说),不过只要严格按照delay的描述进行操作即可。
附:
其他几大模块单独编译时需要的源文件列表(所有依赖头文件略,请自行根据报错添加):
WebRTC - VAD模块源文件列表
注意:VAD的编译需要宏WEBRTC_POSIX的支持,而该宏是否有实现,由WEBRTC_ANDROID等宏是否被定义决定,若你在编译时提示once函数未定义等错误, 请自行添加对WEBRTC_ANDROID宏的定义。
webrtc_vad.c
vad_core.c
vad_filterbank.c
vad_gmm.c
vad_sp.c
real_fft.c
division_operations.c
complex_bit_reverse.c
cross_correlation.c
complex_fft.c
downsample_fast.c
vector_scaling_operations.c
get_scaling_square.c
energy.c
min_max_operations.c
spl_init.c
WebRTC - AECM模块源文件列表
randomization_functions.c
spl_sqrt_floor.c
division_operations.c
min_max_operations.c
ring_buffer.c
delay_estimator.c
delay_estimator_wrapper.c
complex_bit_reverse.c
complex_fft.c
aecm_core.c
echo_control_mobile.c
WebRTC - AGC模块源文件列表
spl_sqrt.c
copy_set_operations.c
division_operations.c
dot_product_with_scale.c
resample_by_2.c
analog_agc.c
digital_agc.c
本文出自 “Bill_Hoo专栏” 博客,请务必保留此出处http://billhoo.blog.51cto.com/2337751/1213801
更多相关文章
- C语言函数的递归(上)
- Android(安卓)kotlin之对象和类(2)
- Android(安卓)Scroll 详解
- Android环境建立之编译Android内核源码笔记---2
- android全格式多媒体播放器(一:ffmpeg移植) 收藏
- Android基于LLVM的Native层代码混淆
- Android(安卓)Linker 与 SO 加壳技术
- Android(安卓)VNDK简介
- Android_Build_System