下载Speex开源库编译https://www.speex.org/,不做详述!
//------------------------------头文件---------------------------------//
#ifndef SPEEX_EC_H
#define SPEEX_EC_H
#include <stdio.h>
#include <stdlib.h>
#include <speex/speex_echo.h>
#include <speex/speex_preprocess.h>
class CSpeexEC
{
public:
CSpeexEC();
~CSpeexEC();
void Init(int frame_size=160, int filter_length=1280, int sampling_rate=8000);
void DoAEC(short *mic, short *ref, short *out);
protected:
void Reset();
private:
bool m_bHasInit;
SpeexEchoState* m_pState;
SpeexPreprocessState* m_pPreprocessorState;
int m_nFrameSize;
int m_nFilterLen;
int m_nSampleRate;
spx_int32_t* m_pfNoise;
};
#endif
//-----------------------------AEC----------------------------------//
#include "stdafx.h"
#include "SpeexEC.h"
CSpeexEC::CSpeexEC()
{
m_bHasInit = false;
m_pState = NULL;
m_pPreprocessorState = NULL;
m_nFrameSize = 160;
m_nFilterLen = 160*8;
m_nSampleRate = 8000;
m_pfNoise = NULL;
}
CSpeexEC::~CSpeexEC()
{
Reset();
}
void CSpeexEC::Init(int frame_size, int filter_length, int sampling_rate)
{
Reset();
if (frame_size<=0 || filter_length<=0 || sampling_rate<=0)
{
m_nFrameSize =160;
m_nFilterLen = 160*8;
m_nSampleRate = 8000;
}
else
{
m_nFrameSize =frame_size;
m_nFilterLen = filter_length;
m_nSampleRate = sampling_rate;
}
m_pState = speex_echo_state_init(m_nFrameSize, m_nFilterLen);
m_pPreprocessorState = speex_preprocess_state_init(m_nFrameSize, m_nSampleRate);
m_pfNoise = new spx_int32_t[m_nFrameSize+1];
m_bHasInit = true;
}
void CSpeexEC::Reset()
{
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;
}
if (m_pfNoise != NULL)
{
delete []m_pfNoise;
m_pfNoise = NULL;
}
m_bHasInit = false;
}
void CSpeexEC::DoAEC(short* mic, short* ref, short* out)
{
if (!m_bHasInit)
return;
/*1.1.9版本中所使用的函数*/
//speex_echo_cancel(m_pState, mic, ref, out, m_pfNoise);
//speex_preprocess(m_pPreprocessorState, (__int16 *)out, m_pfNoise);
/*1.2beta3-win32版本中使用的函数,从参数可以看出最新版本没有参数m_pfNoise,所以CSpeex中可以删除数据成员m_pfNoise*/
/*本文依然保留,是为了测试两个版本的差别,从结果来看,至少人耳似乎听不出有多大差别*/
speex_echo_cancellation(m_pState, mic, ref, out);
speex_preprocess_run(m_pPreprocessorState, (__int16 *)out);
}
//----------------------------Demo-----------------------------------//
#include "stdafx.h"
#include "speexEC.h"
#include <stdio.h>
#include <speex/speex_echo.h>
#define NN 160
void main()
{
FILE *ref_fd;
FILE *mic_fd;
FILE *out_fd;
short ref[NN];
short mic[NN];
short out[NN];
ref_fd = fopen("FarEnd.pcm", "r+b");
mic_fd = fopen("NearEnd.pcm", "r+b");
out_fd = fopen("out.pcm", "w+b");
CSpeexEC ec;
ec.Init();
while (fread(mic, 1, NN*2, mic_fd))
{
fread(ref, 1, NN*2, ref_fd);
ec.DoAEC(mic, ref, out);
fwrite(out, 1, NN*2, out_fd);
}
fclose(ref_fd);
fclose(mic_fd);
fclose(out_fd);
}