WebRTC 音频模块单独编译 --【转载】

原文地址:http://billhoo.blog.51cto.com/2337751/1213801html

【2015年2月15日】java

    Bill 这段时间没有再关注 WebRTC 以及音频处理的相关信息,且我我的早已再也不推荐单独编译 WebRTC 中的各个模块出来使用。实际上本文的参考价值已经很小了,甚至可能会产生误导。不删这篇文章的缘由在于文后有不少读者的讨论,其中的一些仍具有必定的价值,请你们务必以批判和审慎的态度阅读文章。android

 

【2014年5月14日】git

   昨天有幸在 Google 论坛里询问到 AECM 模块的延迟计算一事,Project member 说捣腾这个延迟实际上对 AECM的效果没有帮助,这个延迟值仅在 AECM 启动时加快内置延迟估算器的收敛,若是更新的延迟有误,甚至会使AECM 内置的延迟估算器出现错误的偏移,他建议我使用一个理论上的定值,Chrome 中他们用了 100ms。我以前也在 AECM 里看到了它对内置的 delay_estimator 二进制延迟估算器有很大的依赖,近端与远端数据匹配与否,几乎所有仰仗这个延迟估算器的结果。所以,对于 AECM 的使用,是否还须要花时间去计算这个系统延迟,bill 再也不置评,个中效果你们本身实践和把握。web

   其次,AECM 产生的唧唧声 Project member 澄清这不是 bug,而是 AECM 算法原本就有此表现,属正常现象。算法

   在这里仅但愿你们知道此事,以避免被我一家之言误导。windows

 

   【2014年5月8日】app

   本文已有一年之久,随着本身在学习过程当中认识的加深,以及期间和各位在文后的讨论,担忧后来者照着这一年前的文章走弯路,bill 以为有必要对文章作一个更新,点出本身走的弯路,以避免误导后来者。dom

   1. 本身最开始是把 AECM、NS、VAD、AGC 各个模块单独提取出来使用,如今看来实属麻烦,且效果也不甚理想。若是你们的项目没有特殊的要求,大可将整个语音引擎 VoiceEngine 编译出来使用。就我我的而言,目前的解决方案是独立编译使用音频处理单元 AudioProcessingModule,由于 APM 是一个纯净的音频处理单元,其接口仅与音频处理有关,APM编译请见此文。APM的使用加上上层代码的优化,能够保证基本的通话效果(离完美还很远),回声基本是没有的。主要会存在两个问题,一是AECM出来的效果会有唧唧声,这个声音能够经过对延迟计算的不断优化而获得改善,最终能够作到说几句话以后有1~2次唧唧声。二是通话过程当中声音会忽大忽小,目前我是怀疑由AECM的double talk处理引发的,具体的还要本身去倒腾。eclipse

   2. 关于回声消除滤波器延迟的计算,以前本身一直认为只要这个延迟计算准确,就能获得理想的回声消除效果,如今发现这个想法太幼稚,一是AECM算法自己有必定局限性,二是Android上的采集延迟没有系统API支持,很难计算准确,而播放端的API又不能保证其准确性。目前个人能力只能作到尽可能优化上层的延迟计算,尽可能减小由Android音频API对延迟形成的影响。

   3. 在 Android 上层优化计算系统音频延迟的代码达到必定瓶颈后,能够将优化目标转向 1)AECM 算法。 2)优化AEC(PC)(使其能在手机上正常运行,目前AECPC默认滤波器长度为12块,每块64个点,即AECPC仅能处理48ms的单声道16kHz延迟的数据,而Android的音频系统延迟大多在100ms以上,所以既要增长AECPC滤波器长度又要保证其运行效率是优化的重点) 3)其余模块的优化(好比抖动缓冲区等)。

   4. 文后的源码列表已通过时,因为我目前再也不支持单独编译这些模块,恕我再也不更新该列表,如确有独立编译需求的,可自行在WebRTC项目对应目录中找到须要的文件。

 

附言

   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 动态库拷贝出来以备后续使用。

 

Step 4 - 加载编译好的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

相关文章
相关标签/搜索