声学回声消除(AEC)嵌入式软件(Acoustic Echo Cancellation (AEC)

2019-07-30 06:39发布

我做的嵌入式设备上的网络电话项目。 我已经建立了采用32位MCU与低级别音频编解码器的样品。 现在我发现我的设备上的回声问题,这是我能听到我从发言者说。 我做了一些研究,发现大多数appliaction使用带有回音消除功能,一个DSP编解码器。 但是,是有可能,我做的声学回声消除软件中的,用我的32位MCU?

你能adive算法,甚至源代码:P,做声学回声消除? 我知道复杂的方法是不可能在MCU,而一个简单的算法也很欢迎。

谢谢

[后续]:我已经尝试了一些AEC代码,但他们不能在我的MCU工作得很好,大概是MCU电源的限制。 我发现,执行这些代码时(但在VoIP需要实时响应)我的设备成为非实时性。 最后,我通过添加AEC芯片,因为我不想在另一个DSP芯片重新编写代码实现的模拟硬件的解决方案。

Answer 1:

我有与回声消除时间赫克。 我写了一个软电话,并且用户可以切换周围的音频输入和输出设备,以满足他们的幻想。 我试过Speex语音回声消除库,和其他几个开源库我在网上找到。 无工作很适合我。 我尝试不同的扬声器/话筒的配置和回波总是在那里以某种形式或方式。

我相信这将是很难创建AEC代码,将适用于所有可能的扬声器配置/房间大小/背景noises..etc。 最后,我坐下来,写我自己的回声消除模块为我的网络电话这一算法。

这有点粗糙,但它运作良好,是可靠的。

变量1:保持的平均幅度是当人你说谁是讲一个什么样的记录。 (不要因素安静时)

变量2:保持的平均幅度是输入(麦克)什么记录,但只有当支持语音再次 - 不要因素安静的时间。

只要有音频播放 - 切麦克风。 并假设人听就是不说话,打开麦克150-300ms最后Audible音频帧成为后播放。

如果从麦克风音频(你正在播放过程中掉落)大于OH-说(变量2 * 1.5),开始发送音频输入帧指定的持续时间,每次重置该持续时间输入幅度达到(变量2 * 1.5)。

这样的人说话就知道他们被打断,停下来看看有什么人在说什么。 如果这个人说话没有太嘈杂背景的,他们可能会听到大部分中断,如果不是全部。

就像我说的,不是最优雅,但它不使用了大量的资源(CPU,内存)和它的实际工作相当不错的好。 我感到非常高兴,我的音效。

为了实现它,我只是做了一些功能。

在接收到的音频帧,我调用一个函数,我叫:

void audioin( AEC *ec, short *frame ) {
    unsigned int tas=0; /* Total sum of all audio in frame (absolute value) */
    int i=0;
    for (;i<160;i++)
        tas+=ABS(frame[i]);
    tas/=160; /* 320 byte frames muLaw */
    if (tas>300) { /* I assume this is audiable */
        lockecho(ec);
        ec->lastaudibleframe=GetTickCount64();
        unlockecho(ec);
    }
    return;
}

和发送帧之前,我做的:

#define ECHO_THRESHOLD 300 /* Time to keep suppression alive after last audible frame */
#define ONE_MINUTE 3000 /* 3000 20ms samples */
#define AVG_PERIOD 250 /* 250 20ms samples */
#define ABS(x) (x>0?x:-x)


char removeecho( AEC *ec, short *aecinput ) {
    int tas=0; /* Average absolute amplitude in this signal */
    int i=0;
    unsigned long long *tot=0;
    unsigned int *ctr=0;
    unsigned short *avg=0;
    char suppressframe=0;
    lockecho(ec);
    if (ec->lastaudibleframe+ECHO_THRESHOLD > GetTickCount64() ) {
        /* If we're still within the threshold for echo (speaker state is ON) */
        tot=&ec->t_aiws;
        ctr=&ec->c_aiws;
        avg=&ec->aiws;
    } else {
        /* If we're outside the threshold for echo (speaker state is OFF) */
        tot=&ec->t_aiwos;
        ctr=&ec->c_aiwos;
        avg=&ec->aiwos;
    }
    for (;i<160;i++) {
        tas+=ABS(aecinput[i]);
    }
    tas/=160;
    if (tas>200) {
        (*tot)+=tas;
        (*avg)=(unsigned short)((*tot)/( (*ctr)?(*ctr):1));
        (*ctr)++;
        if ((*ctr)>AVG_PERIOD) {
            (*tot)=(*avg);
            (*ctr)=0;
        }
    }
    if ( (avg==&ec->aiws) ) {
        tas-=ec->aiwos;
        if (tas<0) {
            tas=0;
        }
        if ( ((unsigned short) tas > (ec->aiws*1.5)) && ((unsigned short)tas>=ec->aiwos) && (ec->aiwos!=0) ) {
            suppressframe=0;
        } else {
            suppressframe=1;
        }
    }
    if (suppressframe) { /* Silence frame */
        memset(aecinput, 0, 320);
    }
    unlockecho(ec);
    return suppressframe;
}

这将沉默框架是否需要。 我把我所有的变量,如定时器,和幅度平均在AEC结构,这是我从一个呼叫到

AEC *initecho( void ) {
    AEC *ec=0;
    ec=(AEC *)malloc(sizeof(AEC));
    memset(ec, 0, sizeof(AEC));
    ec->aiws=200; /* Just a default guess as to what the average amplitude would be */
    return ec;
}





typedef struct aec {
    unsigned long long lastaudibleframe; /* time stamp of last audible frame */
    unsigned short aiws; /* Average mike input when speaker is playing */
    unsigned short aiwos; /*Average mike input when speaker ISNT playing */
    unsigned long long t_aiws, t_aiwos; /* Internal running total (sum of PCM) */
    unsigned int c_aiws, c_aiwos; /* Internal counters for number of frames for     averaging */
    unsigned long lockthreadid; /* Thread ID with lock */
    int stlc; /* Same thread lock-count */
} AEC;

你可以适应,因为你需要和的想法踢球,但就像我说的。 它实际上听起来很不错的党。 我唯一的问题是,如果他们有很多背景噪音。 但对我来说,如果他们拿起自己的手机USB或者使用耳机是,他们可以把回声消除掉,而不用担心...但虽然PC扬声器,一个麦克风...我与它很高兴。

我希望它能帮助,或给你的东西的基础上...



Answer 2:

如果你正在做一个商业项目,这应该很容易。 您可以集成在VoIP应用商业消音软件。



文章来源: Acoustic Echo Cancellation (AEC) in embedded software