1000分求AEC(回音消除)的代码、思路、资料,分不够可以再加!

SmallBigCat 2005-07-26 03:45:04
1000分求AEC(回音消除)的代码、思路、资料,分不够可以再加!
...全文
422 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
lianhuiyong 2005-10-31
  • 打赏
  • 举报
回复
现在skype,qq都用GIPS的音频技术,大家可以看看,如果能做到gips的效果,估计msn就不找gips,就找你了,呵呵
XinMaJia 2005-10-21
  • 打赏
  • 举报
回复
to ccxian123(力挽狂澜):

呵呵,这个我用过了,效果不理想啊
ccxian123 2005-10-18
  • 打赏
  • 举报
回复
网上找到的。。没试过,有人试过给我讲下效果啊
ccxian123 2005-10-18
  • 打赏
  • 举报
回复
#include <mex.h>
#ifndef _AEC_H


const float M0dB = 1.0f;
const float M3dB = 0.71f;
const float M6dB = 0.50f;


const float M10dB_PCM = 10362.0f;
const float M20dB_PCM = 3277.0f;
const float M25dB_PCM = 1843.0f;
const float M30dB_PCM = 1026.0f;
const float M35dB_PCM = 583.0f;
const float M40dB_PCM = 328.0f;
const float M45dB_PCM = 184.0f;
const float M50dB_PCM = 104.0f;
const float M55dB_PCM = 58.0f;
const float M60dB_PCM = 33.0f;

const float MAXPCM = 32767.0f;


#define NLMS_LEN (240*8)
const float PreWhiteAlphaTF = (4000.0f/8000.0f);

const float GeigelThreshold = 0.71f;
const int Thold = 30*8;
const float UpdateThreshold = 1026.0f;


const float NLPAttenuation = 1.0f;



class IIR_HP {
float lowpassf;
float alphaTF;
public:
IIR_HP() {
lowpassf = 0.0f;
alphaTF = 0.0f;
}

void init(float alphaTF_) {
alphaTF = alphaTF_;
}

float highpass(float in) {

lowpassf += alphaTF*(in - lowpassf);
return in - lowpassf;
}
};


#define POL 6

class IIR_HP6 {
float lowpassf[2*POL+1];
float highpassf[2*POL+1];

public:
IIR_HP6();
float highpass(float in) {
const float AlphaHp6 = 0.075;
const float Gain6 = 1.45f;

highpassf[0] = in;
int i;
for (i = 0; i < 2*POL; ++i) {

lowpassf[i+1] += AlphaHp6*(highpassf[i] - lowpassf[i+1]);
highpassf[i+1] = highpassf[i] - lowpassf[i+1];
}
return Gain6*highpassf[2*POL];
}
};


class FIR1 {
float a0, a1, b1;
float last_in, last_out;

public:
FIR1();
void init(float preWhiteTransferAlpha);
float highpass(float in) {
float out = a0 * in + a1 * last_in + b1 * last_out;
last_in = in;
last_out = out;

return out;
}
};


#define NLMS_EXT (10*8)
#define DTD_LEN 16


class AEC {
/*Time domain Filters*/
IIR_HP6 hp0;
IIR_HP hp1;
FIR1 Fx, Fe;
float max_max_x;
int hangover;
float max_x[NLMS_LEN/DTD_LEN];
int dtdCnt;
int dtdNdx;


float x[NLMS_LEN+NLMS_EXT];
float xf[NLMS_LEN+NLMS_EXT];
float w[NLMS_LEN];
int j;
int lastupdate;
double dotp_xf_xf;

public:
AEC();


int dtd(float d, float x);


float nlms_pw(float mic, float spk, int update);


int AEC::doAEC(int d, int x);
};

#define _AEC_H
#endif


A.2 aec.cpp

#include <mex.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "aec.h"


IIR_HP6::IIR_HP6()
{
memset(this, 0, sizeof(IIR_HP6));
}



float dotp(float a[], float b[]) {
float sum0 = 0.0, sum1 = 0.0;
int j;

for (j = 0; j < NLMS_LEN; j+= 2) {

sum0 += a[j] * b[j];
sum1 += a[j+1] * b[j+1];
}
return sum0+sum1;
}





FIR1::FIR1()
{
}

void FIR1::init(float preWhiteTransferAlpha)
{
int M_PI=3.14159;
float x = exp(-2.0 * M_PI * preWhiteTransferAlpha);

a0 = (1.0f + x) / 2.0f;
a1 = -(1.0f + x) / 2.0f;
b1 = x;
last_in = 0.0f;
last_out = 0.0f;
}

AEC::AEC()
{
hp1.init(0.01f); /* 10Hz */
Fx.init(PreWhiteAlphaTF);
Fe.init(PreWhiteAlphaTF);

max_max_x = 0.0f;
hangover = 0;
memset(max_x, 0, sizeof(max_x));
dtdCnt = dtdNdx = 0;

memset(x, 0, sizeof(x));
memset(xf, 0, sizeof(xf));
memset(w, 0, sizeof(w));
j = NLMS_EXT;
lastupdate = 0;
dotp_xf_xf = 0.0f;
}


float AEC::nlms_pw(float mic, float spk, int update)
{
float d = mic;
x[j] = spk;
xf[j] = Fx.highpass(spk);


float e = d - dotp(w, x + j);
float ef = Fe.highpass(e);
if (update) {
if (lastupdate) {

dotp_xf_xf += (xf[j]*xf[j] - xf[j+NLMS_LEN-1]*xf[j+NLMS_LEN-1]);
} else {
dotp_xf_xf = dotp(xf+j, xf+j);
}


float mikro_ef = 0.5f * ef / dotp_xf_xf;


int i;
for (i = 0; i < NLMS_LEN; i += 2) {

w[i] += mikro_ef*xf[i+j];
w[i+1] += mikro_ef*xf[i+j+1];
}
}
lastupdate = update;

if (--j < 0) {

j = NLMS_EXT;
memmove(x+j+1, x, (NLMS_LEN-1)*sizeof(float));
memmove(xf+j+1, xf, (NLMS_LEN-1)*sizeof(float));
}

return e;
}


int AEC::dtd(float d, float x)
{

x = fabs(x);
if (x > max_x[dtdNdx]) {
max_x[dtdNdx] = x;
if (x > max_max_x) {
max_max_x = x;
}
}
if (++dtdCnt >= DTD_LEN) {
dtdCnt = 0;

max_max_x = 0.0f;
for (int i = 0; i < NLMS_LEN/DTD_LEN; ++i) {
if (max_x[i] > max_max_x) {
max_max_x = max_x[i];
}
}

if (++dtdNdx >= NLMS_LEN/DTD_LEN) dtdNdx = 0;
max_x[dtdNdx] = 0.0f;
}


if (fabs(d) >= GeigelThreshold * max_max_x) {
hangover = Thold;
}

if (hangover) --hangover;

if (max_max_x < UpdateThreshold) {

return 1;
} else {
return (hangover > 0);
}
}


int AEC::doAEC(int d, int x)
{
float s0 = (float)d;
float s1 = (float)x;


s0 = hp0.highpass(s0);


s1 = hp1.highpass(s1);


int update = !dtd(s0, s1);


s0 = nlms_pw(s0, s1, update);


if (update) {

s0 *= NLPAttenuation;
}


if (s0 > MAXPCM) {
return (int)MAXPCM;
} else if (s0 < -MAXPCM) {
return (int)-MAXPCM;
} else {
return (int)(s0);
}
}


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "aec.h"

#define TAPS (80*8)

typedef signed short MONO;

typedef struct {
signed short l;
signed short r;
} STEREO;

/* Read a raw audio file (8KHz sample frequency, 16bit PCM, stereo)
* from stdin, echo cancel it and write it to stdout
*/
int main(int argc, char *argv[]) {
STEREO inbuf[TAPS], outbuf[TAPS];

fprintf(stderr, "usage: aec_test <in.raw >out.raw\n");

AEC aec;

int taps;
while (taps = fread(inbuf, sizeof(STEREO), TAPS, stdin)) {
int i;
for (i = 0; i < taps; ++i) {
int s0 = inbuf[i].l; /* left channel microphone */
int s1 = inbuf[i].r; /* right channel speaker */

/* and do NLMS*/
s0 = aec.doAEC(s0, s1);

/* copy back */
outbuf[i].l = 0; /* left channel silence */
outbuf[i].r = s0; /* right channel echo cancelled mic */
}

fwrite(outbuf, sizeof(STEREO), taps, stdout);
}
fflush(NULL);
return 0;
}


SmallBigCat 2005-10-17
  • 打赏
  • 举报
回复
to chendf78():
我加你QQ了,交流一下如何
chendf78 2005-08-09
  • 打赏
  • 举报
回复
这个问题,我们已经通过软件实现了
chendf78 2005-08-03
  • 打赏
  • 举报
回复
我也正在做,包括AGC,都是比较难做好,希望能多多交流~~~
QQ:125497646
SmallBigCat 2005-07-29
  • 打赏
  • 举报
回复
再顶
constantine 2005-07-28
  • 打赏
  • 举报
回复
帮顶
SmallBigCat 2005-07-28
  • 打赏
  • 举报
回复
没人顶吗
ablewindy 2005-07-28
  • 打赏
  • 举报
回复
顶!
我也想找这个算法。
想来简单,做来就难罗!
一般现在都是硬件去做了,软件的算法源码没见过!
jink 2005-07-28
  • 打赏
  • 举报
回复
将话筒输入的声音和一定间隔前输出的声音做个处理,尽量去掉输出的声音


这完意人家做了都是卖钱的,代码难找哦,而且使用上有很大限制.
日总是我哥 2005-07-26
  • 打赏
  • 举报
回复

上次有个学无线电的跟我讲过 思路 ,都忘得差不多了

好像讲到了"倒相"

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧