⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gaecrcv.c

📁 TI公司DSP/tms320c55x/tms320c54x系列的声学回声消除代码
💻 C
字号:
/*-------------------------------------------------------------------------*
 *                                                                         *
 *   THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY   *
 *   INFORMATION.  IF PUBLICATION OCCURS, THE FOLLOWING NOTICE APPLIES:    *
 *      "COPYRIGHT 2002 MIKET DSP SOLUTIONS, ALL RIGHTS RESERVED"          *
 *                                                                         *
 *-------------------------------------------------------------------------*/
#include "gaeci.h"
/*--------------------- local defs ----------------------------------------*/

#define _EN_LOW     GAEC_DB(-40.0)
#define _EN_HIGH    GAEC_DB(-17.0)
#define _EN_THR     GAEC_DB(25.0)

/* tone state machine defs */
#define _TONE_OFF               (0)
#define _TONE_ON                (1)
#define _TONE_HANGOVER          (2)
#define _TONE_ON_EXT            (3)
#define _TONE_HANGOVER_EXT      (4)

#define _TONE_CNT               (6) /* 30 ms tone echo */

#define _TONE_DETECT_THR        (Q15(0.05))
#define _TONE_RELEASE_THR       (Q15(0.12))

#if ! defined(_dsp)
static S16 _abs16(int x)
{
    if (x > 0) return (S16)(x); else return (S16)(-x);
}
#else
#define _abs16 	abs
#endif
/*--------------------- public vars ---------------------------------------*/
/*--------------------- local vars ----------------------------------------*/
/*--------------------- local functions -----------------------------------*/

/*-------------------------------------------------------------------------*/
static void                     _detect_tone
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tScRcv *pScr
)
{
    S16 sRcvEn;
    S16 sMean;
	// the signal in tD buffer was shifted 2 bits down...
    sRcvEn = gaec_utl_pkt_energy(pScr->asTdBuf + 5) + GAEC_DB(12);

    /* silence was preceeding */
    pScr->uLow = ((sRcvEn - pDb->asRinEnHst[6]) > _EN_THR) &&
	    	    ((sRcvEn - pDb->asRinEnHst[5]) > _EN_THR) &&
		        ((sRcvEn - pDb->asRinEnHst[4]) > _EN_THR);

    /* 3 frames with high energy */
    pScr->uHigh = (pDb->asRinEnHst[1] > _EN_HIGH-GAEC_DB(6.0)) &&
                 (pDb->asRinEnHst[0] > _EN_HIGH) &&
				 (sRcvEn             > _EN_HIGH);

    /* these 3 frames have similar energy */
#if !defined(_dsp)    
    sMean = (sRcvEn + pDb->asRinEnHst[0] + pDb->asRinEnHst[1])/3;
#else 
	sMean = sRcvEn + pDb->asRinEnHst[0] + pDb->asRinEnHst[1];
	sMean = _smpy(sMean, 10923); // 10923 = 2^15/3
#endif    
    pScr->uEven = (_abs16(sMean - sRcvEn) < GAEC_DB(3.0)) &&
                 (_abs16(sMean - pDb->asRinEnHst[0]) < GAEC_DB(3.0)) &&
                 (_abs16(sMean - pDb->asRinEnHst[1]) < GAEC_DB(3.0));

    pScr->uEdge = (pScr->uLow && pScr->uHigh && pScr->uEven);

    /* if a sharp edge & singularity */
    if (pScr->sJ0 < _TONE_DETECT_THR)
    {
        if (pScr->asK[2] < Q15(-0.65))
        {
            pScr->uIsSingular = TRUE;
        }
        else
        {
            if ((pScr->asK[4] < Q15(-0.65)) &&
                (pScr->asK[1] < Q15(0.5)))
            {
                pScr->uIsSingular = TRUE;
            }
        }
    }

    switch (pDb->uIsTone)
    {
    case _TONE_OFF:
        {
            if (pScr->uEdge && pScr->uIsSingular) 
            {
                pDb->uIsTone = _TONE_ON;
            }
			if (pDb->uControl & IGAEC_CMD_TONE)
			{
                pDb->uIsTone = _TONE_ON_EXT;
			}
            break;
        }
    case _TONE_ON:
        {
            // if tone ended...
            // if there are phase reversals ??? TBD
            if ((pScr->sJ0 > _TONE_RELEASE_THR) ||
                (sRcvEn < _EN_LOW)) 
            {
                pDb->uIsTone = _TONE_HANGOVER;
                pDb->sToneCnt = _TONE_CNT;
            }
            break;
        }
    case _TONE_HANGOVER:
        {
            if ((pScr->sJ0 > _TONE_RELEASE_THR) ||
                (sRcvEn < _EN_LOW) ||
				(!(pDb->uControl & IGAEC_CMD_TONE)))
            {
                pDb->sToneCnt--;
            }
            else
            {
                pDb->sToneCnt++;
            }

            if (pDb->sToneCnt >= _TONE_CNT)
            {
                pDb->uIsTone = _TONE_ON;
            }
            else if (pDb->sToneCnt <= 0)
            {
                pDb->uIsTone = _TONE_OFF;
                pDb->sToneCnt = 0;
            }
            else; // intermediate values
        }
    case _TONE_ON_EXT:
        {
			if (!(pDb->uControl & IGAEC_CMD_TONE))
			{
                pDb->uIsTone = _TONE_HANGOVER_EXT;
                pDb->sToneCnt = _TONE_CNT;
            }
            break;
        }
    case _TONE_HANGOVER_EXT:
        {
            if (!(pDb->uControl & IGAEC_CMD_TONE))
            {
                pDb->sToneCnt--;
            }
            else
            {
                pDb->sToneCnt++;
            }

            if (pDb->sToneCnt >= _TONE_CNT)
            {
                pDb->uIsTone = _TONE_ON_EXT;
            }
            else if (pDb->sToneCnt <= 0)
            {
                pDb->uIsTone = _TONE_OFF;
                pDb->sToneCnt = 0;
            }
            else; // intermediate values
        }
    }

    /* delay energy array */
    {
        S16 i;
        S16 *p1 = &(pDb->asRinEnHst[6]);
        S16 *p2 = p1 - 1;
    	for (i = 6; i > 0; i--)
    	{
            *p1-- = *p2--;
    	}
        *p1 = sRcvEn;
    }
}

/*-------------------------------------------------------------------------*/
void                    _avrg_moments
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tScRcv *pScr
)
{
	S16 k;
    S32 ac0;
    S32 ac1;
    S32 ac2;

    for (k = 0; k < 6; k++)
    {
        ac0 = pScr->aslRkTx[k];
        ac1 = pDb->aslRkSav1[k];
        ac2 = pDb->aslRkSav2[k];
        pDb->aslRkSav1[k] = ac0;
        pDb->aslRkSav2[k] = ac1;
        pScr->aslRk[k] = ac0 + ac1 + ac2;
    }
}

/*--------------------- public  functions ---------------------------------*/

#if !defined(_dsp)
GAEC_tScRcv _GaecScRcv;
#endif

/*-------------------------------------------------------------------------*/
void                     gaec_rcv_detect_tone
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc,
S16 *psRcv
)
{
    GAEC_tScRcv *pScr = &pSc->u.Rcv;

	gaec_rcv_moments(pDb, pScr, psRcv);
    _avrg_moments(pDb, pScr);
    gaec_rcv_normalise_rk(pDb, pScr, -7, (1<<2));
    pScr->sJ0 = gaec_rcv_durbin(pDb, pScr);
    _detect_tone(pDb, pScr);

#if !defined(_dsp)
    _GaecScRcv = *pScr;
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -