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

📄 gaecnlp.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"          *
 *                                                                         *
 *-------------------------------------------------------------------------*/
#if !defined(_dsp)
#include <memory.h>
#else
#include <string.h>
#endif
#include "gaeci.h"

/*--------------------- local defs ----------------------------------------*/


#define _TCL_MIN                (GAEC_DB(10))

#define _MULT                   (31821)
#define _INC                    (13849)

/*--------------------- public vars ---------------------------------------*/
/*--------------------- local vars ----------------------------------------*/
/*--------------------- local functions -----------------------------------*/
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
void						gaec_nlp_get_coefs
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    int band;
	S16 sAttDist = 0;

	// scale att according to asErlCrit
	S16 sEpcCrit = pDb->sEpcCrit;
	if (sEpcCrit < 0)
		sEpcCrit = 0;
	if (sEpcCrit > GAEC_CRIT_MRGN)
		sEpcCrit = GAEC_CRIT_MRGN;

//	sEpcCrit = 0;

	// if we suspect that there are distortions on strong RCV signal, then we add attenuation
	// it will be added to each and every band
	if (pSc->sErleMax < GAEC_ERLE_MAX)
	{
//		sAttDist = (pDb->sErleAv - pSc->sErle) << 1;
		sAttDist = GAEC_ERLE_MAX - pSc->sErleMax;
		if (sAttDist < 0)
			sAttDist = 0;
	}

	// if this is not a double talk but rather a echo path change, 
	// we shall allow to decrease attenuation in either of the bands,
	// moreover, the asErleAv is not valid anymore, we shall decrease it as well

    for (band = 0; band < GAEC_BANDS+1; band++)
    {
        S32 ac0;
        S16 sCorr;
		S16 sAttMin;

        // we should suppress echo below noise
        // sExpectedErrEn takes into account previous Tx Att
        S16 sAtt = pDb->asExpectedErrEn[band] - 
                   (pDb->asVadErrNse[band] - GAEC_DB(3.0));
        S16 sTclA = pDb->asErlAv[band] + pDb->asErleAv[band];
        U16 uEchoAboveNoise = (sAtt > 0);

		if (pDb->uIsDT) // half erle if epc
		{
			ac0 = pDb->asErleAv[band] * (S32) sEpcCrit;
			sTclA -= (S16)(ac0 >> (GAEC_CRIT_SHFT+1));
		}

        // if att is too high:
        // total coupling loss needn't be higher than target TCL;
        if (sAtt > (pDb->Cfg.sTCLst + pDb->sVolume - sTclA))
        {
            sAtt = pDb->Cfg.sTCLst + pDb->sVolume - sTclA;
        }
        else; // tcl (erl+erle+att) is lower than the target,
              // but that's enough to put the echo under noise floor

        // the circuit must be unconditionally stable
        if (sAtt < (_TCL_MIN + pDb->sVolume - sTclA))
        {
            sAtt = _TCL_MIN + pDb->sVolume - sTclA;
        }

		// here we shall increase overall attenuation if needed
		sAtt += sAttDist;

        // negative att - nonsense
        if (sAtt < 0)
        {
            sAtt = 0;
        }

		sAttMin = sAtt - (pDb->Cfg.sTCLst - pDb->Cfg.sTCLdt);
		ac0 = (sAtt - sAttMin) * (S32) sEpcCrit;
		sAttMin += (S16)(ac0 >> GAEC_CRIT_SHFT);
		if (sAttMin < 0)
		{
			sAttMin = 0;
		}
		
        // if expected echo below noise floor
        if (!uEchoAboveNoise)
        {
			S16 sDltCrit = pDb->asVadErrCrit[band] - 
						   pDb->asVadRinCrit[band];
			if (sDltCrit < -GAEC_CRIT_MRGN)
				sDltCrit = -GAEC_CRIT_MRGN;
			if (sDltCrit > GAEC_CRIT_MRGN)
				sDltCrit = GAEC_CRIT_MRGN;

			// sCorr = sAttMin if Rx is Active and Tx is inactive
			// sCorr = -sAttMin if Tx is active and Rx is under noise
            ac0 = sAttMin * (S32) sDltCrit;
            sCorr = (S16)(ac0 >> GAEC_CRIT_SHFT);

            pSc->asAttRin[band] = (sAttMin + sCorr) >> 1;
            pSc->asAttErr[band] = (sAttMin - sCorr) >> 1;

        }
        else // residual echo above noise
        {
            // now let's account for double talk
			S16 sDtCrit = pDb->asDtCrit[band];

            if (sDtCrit > GAEC_CRIT_MRGN) // sure DT
            {
				// if DT is very strong, and near-end signal masks echo,
				// then we shall pass SND as is, attenuating RCV instead
				S16 sErlCrit = pDb->asErlCrit[band];
				if (sErlCrit < 0)
					sErlCrit = 0;
				if (sErlCrit > GAEC_CRIT_MRGN)
					sErlCrit = GAEC_CRIT_MRGN;

				ac0 = sAttMin * (S32) sErlCrit;
				sCorr = (S16)(ac0 >> GAEC_CRIT_SHFT);
                pSc->asAttErr[band]  = (sAttMin - sCorr)>>1;
                pSc->asAttRin[band]  = sAttMin - pSc->asAttErr[band];
            }
            else if (sDtCrit > 0) // may-be DT
            {
                // we start to insert a bit of att into RCV,
                // and decrease the overall att, because dt masks echo

				ac0 = (sAtt - sAttMin) * (S32)sDtCrit;
				sAtt = sAtt - (S16)(ac0 >> GAEC_CRIT_SHFT);

                // sCorr = sAtt * sCrit / THR;
                ac0 = sAttMin * (S32)sDtCrit;
                sCorr = (S16)(ac0 >> (GAEC_CRIT_SHFT+1));

                pSc->asAttRin[band] = sCorr;
                pSc->asAttErr[band] = sAtt - sCorr;
            }
            else // no DT
            {
                pSc->asAttRin[band] = 0;
                pSc->asAttErr[band] = sAtt;
            }
        }
        // att is already smooth, because it is based on Exp error,
        // taking into account the tail len,
        // and ErlAv/ErleAv
	}
}
/*-------------------------------------------------------------------------*/
void						gaec_nlp_corect_coefs
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    int band;

    // is Snd is muted, we need to pass Rcv unattenuated
	if ((pDb->uControl & IGAEC_CMD_SND_MUTED) ||
		(pSc->uNlpMode == GAEC_NLP_MODE_CLEAR))
    {
	    for (band = 0; band < GAEC_BANDS+1; band++)
		{
            pSc->asAttErr[band] += pSc->asAttRin[band];
            pSc->asAttRin[band] = 0;
        }
	}

    // ... or pass as is
    if (pDb->uControl & IGAEC_CMD_NLP_OFF)
    {
	    for (band = 0; band < GAEC_BANDS+1; band++)
		{
            pSc->asAttErr[band] = 0;
            pSc->asAttRin[band] = 0;
        }
    }

    for (band = 0; band < GAEC_BANDS+1; band++)
    {
        pSc->asAttErr[band] = gaec_utl_exp((S16)-pSc->asAttErr[band]);
    }
}
/*-------------------------------------------------------------------------*/
void						gaec_nlp_stts_update
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
	int band;
   	S32 ac0 = 0;
   	S16 sAtt;

    for (band = 1; band < 9; band++)
    {
    	ac0 += pSc->asAttRin[band];
    }
    sAtt = (S16)(ac0 >> 3);
    pDb->Stts.sRcvAtt = _by17(sAtt);
    
    ac0 = 0;
    for (band = 1; band < 9; band++)
    {
    	ac0 += pSc->asAttErr[band];
    }
    sAtt = (S16)(ac0 >> 3);
    pDb->Stts.sSndAtt = _by17(sAtt);
}

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

/*-------------------------------------------------------------------------*/
void                        gaec_nlp
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    gaec_nlp_get_coefs(pDb, pSc);
	gaec_nlp_corect_coefs(pDb, pSc);
	gaec_nlp_stts_update(pDb, pSc);

    switch(pSc->uNlpMode)
    {
    case GAEC_NLP_MODE_CLEAR:
        memclr(&pSc->aasErr0[0][0], GAEC_BANDS*2*GAEC_ERR_SZ);
        gaec_nlp_mix_noise(pDb, pSc, FALSE);
        break;
    case GAEC_NLP_MODE_MODIFY:
        gaec_nlp_att_rx(pDb, pSc);
        gaec_nlp_mix_noise(pDb, pSc, TRUE);
        break;
    case GAEC_NLP_MODE_PASS:
        memcpy(&pSc->aasErr0[0][0], 
               &pDb->aasErrSav[0][0], 
               GAEC_BANDS*2*GAEC_ERR_SZ);
        break;
    }
}

⌨️ 快捷键说明

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