Webrtc 回音消除 二


目前成果:speaker读本地数据,mic录实时数据,可以90%消除回音,AecDelay还需调优,NS和VAD正常可用。先保证AEC正常,下一步speaker实时网络数据,离Double Talk 还有很长一段路,加油!


效果图:


Webrtc 回音消除 二_第1张图片


实时音频回音消除流程图:


Webrtc 回音消除 二_第2张图片



关键知识点:


1、回音消除目的是实现双向对讲(double talk)

2、硬件要求,低端设备视频音频加AEC后CPU(99%),声音一卡一卡,AEC没法运算。目前只做双向语音对讲,关闭设备视频录像,解决。

3、speaker为放大电路播放的数据能量太大,AEC无法精确消除,出现真声和回声都消除的现象。调试阶段手动降低speaker放大参数,解决。


//------------------------------------------------------Demo  Start------------------------------------------------------------------------------------//


while(1)
    {
      if (3200 == fread(far_frame_c, sizeof(char), 3200, fp_far))
      {
        fread(near_frame_c, sizeof(char), 3200, fp_near);
        for(i = 0;i < NN*10; i++) {
        
          far_frame_s[i] =  (far_frame_c[i*2+1]<< 8) | (far_frame_c[i*2]&0xFF);//两个char型拼成一个short
          far_frame[i] = far_frame_s[i];//转float型接口需要
         
          near_frame_s[i] =  (near_frame_c[i*2+1]<<8) | (near_frame_c[i*2]&0xFF);
          near_frame[i] = near_frame_s[i];

        }
         

        for(i = 0 ;i < 10;i ++) {      
          NOTICE("AEC_BufferFarend......\n");
          EWebRtcAEC_BufferFarend(handleAec, far_frame+NN*i, NN);//对参考声音(回声)的处理


          NOTICE("AEC_Processs......\n");
          EWebRtcAEC_Process(handleAec,near_frame+NN*i,1, aecout_frame+NN*i,NN,AecDelay,0);//回声消除
        

        }
        for(i = 0; i < NN*10; i ++) {
          aecout_frame_s[i] = aecout_frame[i];
        }

        fwrite(aecout_frame_s, sizeof(short),NN*10, fp_outAec);

#if 0 //NS
      NOTICE("NS_Processs......\n");
      EWebRtcNS_Analyze(handleNS,near_frame);//NS
      EWebRtcNS_Process(handleNS,aecout_frame,1,nsout_frame);
      for(i = 0 ;i < NN ;i ++) {
        nsout_frame_s[i] = nsout_frame[i];
       }
      fwrite(nsout_frame_s, sizeof(short),NN, fp_outNS);

#endif

#if 0 //Delay
        NOTICE("GetDelayMetrics......\n");
        //EWebRtcAEC_GetDelayMetrics(handleAecDelay,median,std,frac);
        EWebRtcAEC_GetDelayMetrics(handleAec,median,std,frac);
        NOTICE("median %d std %d frac %f\n",median[0],std[0],frac[0]);
#endif

#if 0//VAD is ok
        NOTICE("VAD_Process......\n");
        if(0 < EWebRtcVAD_Process(handleVad,SAMPLE_RATE,far_frame_s,NN) ) {
          NOTICE("Voice~~~~~ sum %d\n",CirculargetSum());
          CircularaddData(1);
          
        } else {
          NOTICE("silence~~~~~ sum %d\n",CirculargetSum());
          CircularaddData(0);
        }

        if ( 230 < CirculargetSum()) {
          int newValue = MAX(0,median[0]-20);
          NOTICE("newValue=%d AecDealy=%d\n",newValue,AecDelay);
          if(abs(newValue-AecDelay) >= 8) {
            AecDelay = MAX(newValue,0);
            NOTICE("AecDelay %d\n",AecDelay);
          }
        }

#endif
      }
      else
      {
        break;
      }
    }

//------------------------------------------------------Demo  End------------------------------------------------------------------------------------//


基本参数:

参数名      

数据类型

描述

SampleRate

Int

采样率8000

SamplePerframe

int

160*10

channelCount

int

单声道1

audioEncoding

Int

2个字节 ENCODING_PCM_16BIT

CodecID

Int

AUDIO_CODEC_GSM

8000HZ,一个Sample采样1600次,即每个sample是3200byte。一秒钟5个Sample,每个Sample是200ms,这么做是由于cpu性能。将3200byte拆分成10个320byte依次进行GSM编码,GSM要求320byte。

你可能感兴趣的:(回音抑制,webrtc,&,speex)