java speex回声消除_android – Speex回音消除配置
我正在使用其AudioRecord和AudioTrack类制作Android-to-Android VoIP(扬声器)应用程序,以及通过NDK的Speex进行回声消除.我能够成功传入并从Speex的speex_echo_cancellation()函数中检索数据,但回声仍然存在.
这是记录/发送和接收/播放音频的相关android线程代码:
//constructor
public MyThread(DatagramSocket socket, int frameSize, int filterLength){
this.socket = socket;
nativeMethod_initEchoState(frameSize, filterLength);
}
public void run(){
short[] audioShorts, recvShorts, recordedShorts, filteredShorts;
byte[] audioBytes, recvBytes;
int shortsRead;
DatagramPacket packet;
//initialize recorder and player
int samplingRate = 8000;
int managerBufferSize = 2000;
AudioTrack player = new AudioTrack(AudioManager.STREAM_MUSIC, samplingRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, managerBufferSize, AudioTrack.MODE_STREAM);
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, samplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, managerBufferSize);
recorder.startRecording();
player.play();
//record first packet
audioShorts = new short[1000];
shortsRead = recorder.read(audioShorts, 0, audioShorts.length);
//convert shorts to bytes to send
audioBytes = new byte[shortsRead*2];
ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(audioShorts);
//send bytes
packet = new DatagramPacket(audioBytes, audioBytes.length);
socket.send(packet);
while (!this.isInterrupted()){
//recieve packet/bytes (received audio data should have echo cancelled already)
recvBytes = new byte[2000];
packet = new DatagramPacket(recvBytes, recvBytes.length);
socket.receive(packet);
//convert bytes to shorts
recvShorts = new short[packet.getLength()/2];
ByteBuffer.wrap(packet.getData(), 0, packet.getLength()).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(recvShorts);
//play shorts
player.write(recvShorts, 0, recvShorts.length);
//record shorts
recordedShorts = new short[1000];
shortsRead = recorder.read(recordedShorts, 0, recordedShorts.length);
//send played and recorded shorts into speex,
//returning audio data with the echo removed
filteredShorts = nativeMethod_speexEchoCancel(recordedShorts, recvShorts);
//convert filtered shorts to bytes
audioBytes = new byte[shortsRead*2];
ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(filteredShorts);
//send off bytes
packet = new DatagramPacket(audioBytes, audioBytes.length);
socket.send(packet);
}//end of while loop
}
这是相关的NDK / JNI代码:
void nativeMethod_initEchoState(JNIEnv *env, jobject jobj, jint frameSize, jint filterLength){
echo_state = speex_echo_state_init(frameSize, filterLength);
}
jshortArray nativeMethod_speexEchoCancel(JNIEnv *env, jobject jObj, jshortArray input_frame, jshortArray echo_frame){
//create native shorts from java shorts
jshort *native_input_frame = (*env)->GetShortArrayElements(env, input_frame, NULL);
jshort *native_echo_frame = (*env)->GetShortArrayElements(env, echo_frame, NULL);
//allocate memory for output data
jint length = (*env)->GetArrayLength(env, input_frame);
jshortArray temp = (*env)->NewShortArray(env, length);
jshort *native_output_frame = (*env)->GetShortArrayElements(env, temp, 0);
//call echo cancellation
speex_echo_cancellation(echo_state, native_input_frame, native_echo_frame, native_output_frame);
//convert native output to java layer output
jshortArray output_shorts = (*env)->NewShortArray(env, length);
(*env)->SetShortArrayRegion(env, output_shorts, 0, length, native_output_frame);
//cleanup and return
(*env)->ReleaseShortArrayElements(env, input_frame, native_input_frame, 0);
(*env)->ReleaseShortArrayElements(env, echo_frame, native_echo_frame, 0);
(*env)->ReleaseShortArrayElements(env, temp, native_output_frame, 0);
return output_shorts;
}
这些代码运行良好,音频数据肯定是从android-to-android发送/接收/处理/播放.鉴于音频采样率为8000 Hz,数据包大小为2000bytes / 1000shorts,我发现需要一个1000的frameSize才能使播放的音频流畅. filterLength的大多数值(根据Speex doc也称为尾长)将运行,但似乎对回声消除没有影响.
有没有人理解足够的AEC为我提供一些关于实现或配置Speex的指示?谢谢阅读.
java speex回声消除_android – Speex回音消除配置相关推荐
- python 回声程序_一种回声消除系统及回音消除方法与流程
本发明涉及通信技术领域,具体涉及一种回声消除系统及回音消除方法. 背景技术: 回声消除器通常由滤波器和算法组成,根据具体应用和性能要求的不同可以有多种选择. 滤波器有FIR(有限长度冲激晌应)滤波器和 ...
- 回音消除 Speex AEC 录音放音同步对齐
一 .因为Windows不是实时操作系统,造成声卡的录音.放音他们之间有一定 时间的延时,而且这个延时的时间长每台电脑可能都不一样 .从而给回音 消除增加一定的难度,再加上房间的大小造成声音反射也不一 ...
- 论android等平台回音消除解决方案
来源 http://www.qttaudio.com/android-aec.html 回声消除介绍 http://www.baike.com/wiki/%E5%9B%9E%E9%9F%B3%E6%B ...
- Android app 录音回音消除两种方法
在app开发录音功能的时候 会遇到回音的问题,今天就来借助android 自带的api 来解决回音的问题 1.通过设置AudioManager.MODE_IN_COMMUNICATION模式进行录音, ...
- 实时语音通讯的回音消除技术详解
本文是一篇详细介绍实时音频通讯过程中的回音消除技术的文章,主要描述的是回音消除技术理论和算法原理等. 内容概述 笔者从2004年开始接触回音消除(Echo Cancellation)技术,而后一直在某 ...
- 即时通讯音视频开发(十):实时语音通讯的回音消除技术详解
前言 即时通讯应用中的实时音视频技术,几乎是IM开发中的最后一道高墙.原因在于:实时音视频技术 = 音视频处理技术 + 网络传输技术 的横向技术应用集合体,而公共互联网不是为了实时通信设计的.有关实时 ...
- android音频杂音问题_Android 音视频去回声、降噪(Android音频采集及回音消除)(转)...
好久没写文章了,其实是想记录一下自己在Android开发的成长历程.谈到音视频这块,对于新手来说刚接触到这一块,那是非常非常的恶心~我自己弄这一块也是从头开始,在 网上也翻阅了无数的资料.浏览了无数的 ...
- android speex AEC 回音消除
android speex AEC 回音消除. 有时候喇叭声音会被mic录制进去,就会产生回音数据,这是非常让人头疼的,所以去回音在音视频应用中非常重要. 现在主流的回音消除手段有android自带a ...
- 开源 基于Android的SIP电话-----Speex 回音消除 在android 平台
我的毕业论文题目是: 基于Android的移动VoIP高清视频通话系统的设计与实现 可以去CNKI下载察看,希望对大家有帮助 搞了将近一个月的时间,将Speex的编码和解码做好了,发现还不错. 参考A ...
- Speex 回声消除
为什么需要声学回声消除呢?在一般的VOIP软件或视频会议系统中,假设我们只有A和B两个人在通话,首先,A的声音传给B,B然后用喇叭放出来,而这时B的MIC呢则会采集到喇叭放出来的声音,然后传回给A,如 ...
最新文章
- jquery改变html元素的样式,给input标签赋值,onclick中文传参问题等
- 转载-IronPython入门:什么是IronPython?
- 搜狗手机浏览器_搜狗推广开户费多少钱?【搜狗开户代理商】
- java内部类练习题,学习笔记——Java内部类练习题
- 读书笔记_代码大全_第14章_组织直线型代码_第15章_使用条件语句
- java并发编程之线程的生命周期详解
- CCF201604-4 游戏(100分)
- ARM嵌入式系统开发之接收函数的实现
- python中文文本聚类_python进行中文文本聚类实例(TFIDF计算、词袋构建)
- vld检测不输出_原创干货 | 基于机器学习的webshell检测踩坑小记
- UVa 12911 Subset Sum
- 本地iis部署之后网页无法打开
- 通过ThreadLoad实现线程范围内的共享变量
- Linux查看端口命令:netstat -tln
- c语言---25 扫雷游戏
- qq邮箱的发件服务器怎么设,如何利用QQ邮箱实现网站SMTP发信,详细邮箱的配置教程...
- 计算机平均数据传输速率怎么算,如何计算总线数据传输速率
- KSM与KVM CPU、内存控制
- 使用加速度计DIY自制基于Arduino手势控制的空中鼠标
- Ubuntu18.04系统安装并配置mosquitto