欢迎来到天天文库
浏览记录
ID:31433966
大小:104.00 KB
页数:4页
时间:2019-01-09
《speex在基于android的楼宇可视对讲程序中的应用》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、Speex在基于Android的楼宇可视对讲程序中的应用 摘要:本文简要介绍了在基于Android的楼宇可视对讲应用程序中声学回声消除的产生原理,并提出了通过抑制Speex来实现基于Android的回声消除。文章主要分析了Speex的源代码,讲述了以Speex为基础的jni开发。最终在Android应用层实现对Speex的合理调用,取得了良好的效果。 关键词:楼宇可视对讲回声消除AndroidSpeex 中图分类号:TP393文献标识码:A文章编号:1007-9416(2016)06-0000-0
2、0 1引言 在基于Android的楼宇对讲应用程序的开发过程中,会遇到的一个重要的难题:对话双方进行可视对讲时,一般会采用扬声器,近端的语音被麦克风采集并传送到远端,由远端的扬声器播出,播出的声音经空间反射,被远端的麦克风采集传回,这时说话人会听到自己的声音。这就是声学回声现象。为了保证软件产品的用户体验,必须实现回声消除(AEC)。由于AEC技术非常复杂,需要很大代价找专业公司解决。 2Speex简介4 Speex是一个开源免费跨平台的音频流处理方案,功能包括音频编码和解码,回声消、自动增益控
3、制、噪声抑制等。本文楼宇可视对讲系统中,室内机都是使用Android操作系统。移植Speex到Android平台,提供Android应用层调用,是实现基于Android的回声消除的最经济的方法。 3Speex的AEC模块分析 Speex移植成功后的对外函数可参看头文件“speex_echo.h”和"speex/speex_preprocess.h"。主要对外接口函数包括以下几个: SpeexEchoState*speex_echo_state_init(intframe_size,intfilte
4、r_length); 回声消除控制模块初始化,返回一个初始化过的SpeexEchoState结构指针,参数frame_size是每次处理的数据块大小,参数filter_length是speex中提到的“尾长”。 voidspeex_echo_state_destroy(SpeexEchoState*st); 释放回声消除模块,参数st就是要释放的模块的SpeexEchoState结构。 voidspeex_echo_cancellation(SpeexEchoState*st,constspx_
5、int16_t*rec,constspx_int16_t*play,spx_int16_t*out); 回声消除操作,参数rec是近端采集到的音频数据,play是远端音频数据,out是输出。 预处理操作preprocess包括回声消除预处理、噪声抑制、自动增益控制,其用法和回声消除类似。 4基于Speex的jni驱动开发 Speex模块编译成功后,就要开始着手编写jni驱动程序了。驱动程序的源文件为speex_jni.c。编译成功后会生成“libspeex.so”动态链接库。Speex的驱动对外
6、接口函数有以下几个:4 //声音处理模块初始化 voidJava_com_peric_NetPhone_Init(); //声音处理操作,参数jrecBuf就是近端音频采集数据,jechoBuf就是远端音频数据,每次输入的数据块大小可为4096字节 jbyteArrayJava_com_peric_NetPhone_AEC(JNIEnv*env,jobjectjObj,jbyteArrayjrecBuf,jbyteArrayjechoBuf) //通话完成,释放声音处理模块 voidJava
7、_com_peric_NetPhone_Release(); 5应用层实现回声消除 得了Speex的驱动程序,但有很多人却得不到理想的回声消除效果。Speex的基本原理就是以输入的远端音频数据为参照,消除麦克风采集到的近端音频中的远端音频部分。如果远端数据和近端数据之间的时间差过大,即AEC程序在做回声消除时参照的远端音频数据和近端音频数据之间有过大的错位,那么必然无法正确的消除回声。为此本文在应用层专门设置了4个队列和5个线程用于实现音频数据收发、播放、采集和AEC操作。线程和队列之间的关系如图1
8、所示。4 queueFarend队列存储InThread通过socket接收到的远端音频数据排到队尾,WriteThread读出并播放,当queueFarend为空时,WriteThread线程不会暂停播放,而是播放一段空白。第二个队列queuePlayback队列,WriteThread播放过的音频数据放入该队列等待,等待AecThread线程使用。第三个queueRecord队列,存储ReadThread通过麦克风采集到的近端音频数据
此文档下载收益归作者所有