语音聊天室源码开发,如何实现回音消除功能?

在语音聊天室源码开发中,做好回音消除功能对提升用户使用体验非常关键,比较完善的回音消除模块就是Speex了,有许多中小公司也拿它作为回音消除功能 。经过测试,Speex的消除效果还是不错的。

编写个jni文件,NDK 环境编译一下即可得到so 文件,在Android环境中调用即可。

      //初始化回音消除参数
      /*
       * jint frame_size        帧长      一般都是  80,160,320
       * jint filter_length     尾长      一般都是  80*25 ,160*25 ,320*25
       * jint sampling_rate     采样频率  一般都是  8000,16000,32000
       * 比如初始化 
       *  InitAudioAEC(80, 80*25,8000)   //8K,10毫秒采样一次
       *  InitAudioAEC(160,160*25,16000) //16K,10毫秒采样一次
       *  InitAudioAEC(320,320*25,32000) //32K,10毫秒采样一次
       */
jint Java_com_audioaec_talkdemo_AudioAEC_InitAudioAEC( JNIEnv* env,jobject thiz,
              jint frame_size,jint filter_length,jint sampling_rate)
{
if(nInitSuccessFlag == 1)
return 1 ;
 
m_nFrameSize  = frame_size; 
m_nFilterLen  = filter_length; 
m_nSampleRate = sampling_rate; 
 
//计算采样时长,即是10毫秒,还是20毫秒,还是30毫秒
nSampleTimeLong = (frame_size / (sampling_rate / 100)) * 10 ;
 
m_pState = speex_echo_state_init(m_nFrameSize, m_nFilterLen); 
if(m_pState == NULL)
return -1 ;
 
m_pPreprocessorState = speex_preprocess_state_init(m_nFrameSize, m_nSampleRate); 
if(m_pPreprocessorState == NULL)
return -2 ;
 
iArg = m_nSampleRate;
speex_echo_ctl(m_pState, SPEEX_SET_SAMPLING_RATE, &iArg);
speex_preprocess_ctl(m_pPreprocessorState, SPEEX_PREPROCESS_SET_ECHO_STATE, m_pState);
 
 nInitSuccessFlag = 1 ;
 
 return 1 ;
}
 
/*
 参数:
  jbyteArray recordArray  录音数据
  jbyteArray playArray    放音数据 
  jbyteArray szOutArray
*/
jint Java_com_audioaec_talkdemo_AudioAEC_AudioAECProc(JNIEnv* env,jobject thiz,
           jbyteArray recordArray,jbyteArray playArray,jbyteArray szOutArray  )
{
if(nInitSuccessFlag == 0)
return 0 ;
 
 jbyte* recordBuffer = (jbyte *)(*env)->GetByteArrayElements(env,recordArray, 0);
 jbyte* playBuffer = (jbyte *)(*env)->GetByteArrayElements(env,playArray, 0);
 jbyte* szOutBuffer = (jbyte *)(*env)->GetByteArrayElements(env,szOutArray, 0);
 
speex_echo_cancellation(m_pState,(spx_int16_t *)recordBuffer,
       (spx_int16_t *)playBuffer,(spx_int16_t *)szOutBuffer); 
int flag=speex_preprocess_run(m_pPreprocessorState,(spx_int16_t *)szOutBuffer);  
 
 (*env)->ReleaseByteArrayElements(env,recordArray,recordBuffer,0) ;
 (*env)->ReleaseByteArrayElements(env,playArray,playBuffer,0) ;
 (*env)->ReleaseByteArrayElements(env,szOutArray,szOutBuffer,0) ;
 
 return 1 ;
}
 
    //退出
jint Java_com_sosea_xmeeting_SpeexAEC_ExitSpeexDsp( JNIEnv* env,jobject thiz)
{
if(nInitSuccessFlag == 0)
return 0 ;
 
if (m_pState != NULL) 
{ 
speex_echo_state_destroy(m_pState); 
m_pState = NULL; 
} 
if (m_pPreprocessorState != NULL) 
{ 
speex_preprocess_state_destroy(m_pPreprocessorState); 
m_pPreprocessorState = NULL; 
} 
 
 nInitSuccessFlag = 0 ;
 
 return 1 ;
}

用户在使用语音聊天室源码进行语音社交时,语音通话中的回声是非常影响使用体验的,所以无论如何都需要在开发时利用一定的技术手段实现回声消除,以上就是回声消除功能的实现方式了,希望对大家有帮助。
本文转载自网络,转载仅为分享干货知识,如有侵权欢迎联系云豹科技进行删除处理

原文链接:https://www.cnblogs.com/jianglijs/p/8583603.html

原文地址:https://www.cnblogs.com/yunbao/p/14950795.html