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

📄 gaecadf.c

📁 TI公司DSP/tms320c55x/tms320c54x系列的声学回声消除代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        case 2:
            // we allow 6 dB loss in Erle till we converge
            sExpectedErrEn += GAEC_DB(6.0);
            // lower bands shall converge slower 
            sAddLoss = pSc->u.asTmp[band];
            break;
        case 3:
            sAddLoss = pSc->u.asTmp[band] >> 1;
            break;
        case 4:
        case 0:
        default:
            break;
        }
        sErleLoss = pSc->asErrEn[band] - sExpectedErrEn;

//        if (pDb->uAdfMode < 3)
//            sErleLoss -= GAEC_DB(6.0); // dB
        if (sErleLoss < 0)
            sErleLoss = 0;
#if !defined (_dsp)
        if (band == 1)
            pSc->u.asTmp[GAEC_TMP_SZ-1] = sErleLoss;
#endif
        sErleLoss <<= 1;
        sErleLoss += sAddLoss;
//      (-sErleLoss) = 6 + Send - Erle - Err;
        pSc->asSSC[band] = gaec_utl_exp (-sErleLoss);
    }

// if erle is low, then we control ss by erl loss
// or ... control by asErlCrit ???
//
    for (band = 0; band < GAEC_BANDS+1; band++)
    {
//        if (pDb->asErlCrit[band] > GAEC_CRIT_MAX/2)
//            pSc->asSSC[band] = 0;
    }

    // if double talk, suspect the echo path change - adapt faster...

    if (pDb->uIsDT)
    {
        for (band = 0; band < GAEC_BANDS+1; band++)
        {
            S32 ac0 = pSc->asSSC[band];
            ac0 <<= 3;
            if (ac0 > 4096)
                ac0 = 4096;
            pSc->asSSC[band] = (S16) ac0;

//            pSc->asSSC[band] = 4096;
        }
    }
}
/*-------------------------------------------------------------------------*/
void                        gaec_adf_epc_control
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    S16 sDerleMax = GAEC_CRIT_MAX/2;
    S16 band;


    switch (pDb->uAdfMode)
    {
    case 2: 
        sDerleMax = GAEC_CRIT_MAX/8;
        break;
    case 3: 
        sDerleMax = GAEC_CRIT_MAX/4;
        break;
    default:
        break;
    }

    for (band = 0; band < GAEC_BANDS+1; band++)
    {
        // sDerle > 0 if 'new' err is less than 'old'
        S16 sDerle = (pSc->asErrMEn[band] - pSc->asErrEn[band])>>4;
#if !defined(_dsp)
            _auCopyAdf[band] = 0;
#endif
        if (sDerle < 0) // ErrM < Err
        {
            gaec_copy_err(pSc, band);
#if !defined(_dsp)
            _auCopyAdf[band] += 1;
#endif
        }

        if (pDb->asErlCrit[band] < GAEC_CRIT_MAX/2)
        {
            if (! pDb->uIsDT)
            {
	            pDb->asDerle[band] += sDerle;
                if (pDb->asDerle[band] > sDerleMax)
                {
                    // adapted good, copy adf to permanent
                    gaec_copy_adf(pDb->psAdfM, pDb->psAdf, band);
                    pDb->asDerle[band] = 0;
#if !defined(_dsp)
                    _auCopyAdf[band] += 2; 
#endif
                }
                else if (pDb->asDerle[band] < -sDerleMax)
                {
                    // too bad, it's screwed up
                    gaec_copy_adf(pDb->psAdf, pDb->psAdfM, band);
#if !defined(_dsp)
                    _auCopyAdf[band] += 4; 
#endif
                    pDb->asDerle[band] = 0;
                }
                else; // keep working
            }
            else  
			{
				// only if echo path change suspected...
				if (pDb->sEpcCrit > GAEC_CRIT_MAX/4)
				{
					sDerle <<= 1;
				}

				pDb->asDerle[band] += sDerle;
				if (pDb->asDerle[band] > GAEC_CRIT_MAX)
					pDb->asDerle[band] = GAEC_CRIT_MAX;
				if (pDb->asDerle[band] < -GAEC_CRIT_MAX*2)
					pDb->asDerle[band] = -GAEC_CRIT_MAX*2;

				// wait till global dt is over with adfm->adf decision
			}
        }
        else ; // it's pure RX.
    }
}
/*-------------------------------------------------------------------------*/
void                        gaec_adf_dt_start
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    int band;
    for (band = 0; band < GAEC_BANDS+1; band++)
    {
        pDb->asDerle[band] = 0;
        pDb->aslAdEnM[band] = pDb->aslAdEn[band];
        pDb->aslAdEn[band] = (S32)(GAEC_ADF_SZ * 3 * 3.);
    }
    pDb->uAdfMode = 2;

}
/*-------------------------------------------------------------------------*/
void                        gaec_adf_dt_end
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    S16 band;
    S16 sChangedBands = 0;

    for (band = 0; band < GAEC_BANDS+1; band++)
    {
        // if it was really an echo path change
        if (pDb->asDerle[band] > GAEC_CRIT_MAX/2)
        {
            // adapted good, copy adf to permanent
            gaec_copy_adf(pDb->psAdfM, pDb->psAdf, band);
            pDb->asDerle[band] = 0;
            sChangedBands++;
        }
        else // too bad, it's screwed up 
        {
            gaec_copy_adf(pDb->psAdf, pDb->psAdfM, band);
            pDb->aslAdEn[band] = pDb->aslAdEnM[band];
            pDb->asDerle[band] = 0;
        }

    }

    // if echo path really changed a lot
    if (sChangedBands > (GAEC_BANDS/3))
    {
		S16 sErleLoss = 0;

        // decrease erle
        for (band = 0; band < GAEC_BANDS+1; band++)
        {
            pDb->asErleAv[band] = pSc->asErle[band];
        }
		sErleLoss = pDb->sErleAv - pSc->sErle;
        pDb->sErleAv = pSc->sErle;

		if (sErleLoss > GAEC_DB(10))
		{
            pDb->sConvAcc = _CONV_ACC2;
            pDb->uAdfMode = 2;
		}
		else 
		{
			if (pDb->sConvAcc > _CONV_ACC3)
			{
				// force adf mode back to adf mode 3
				pDb->sConvAcc = _CONV_ACC3;
				pDb->uAdfMode = 3;
			}
			else if (pDb->sConvAcc > _CONV_ACC2)
			{
				// force adf mode back to adf mode 2
				pDb->sConvAcc = _CONV_ACC2;
				pDb->uAdfMode = 2;
			}
			else ; // we are still in the very beginning
		}
    }
}
/*-------------------------------------------------------------------------*/
void                        gaec_adf_control
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    if (!pDb->uIsDT) 
    {
        if (pSc->sErle > 0)
        {
            pDb->sConvAcc += pSc->sErle >> 9;
        }

        switch (pDb->uAdfMode)
        {
        case 0: // start
            pDb->sConvEnCnt++;
            if (pDb->sConvEnCnt > _CONV_ACC2)
            {
                pDb->sConvEnCnt = 0;
                pDb->uAdfMode = 2;
            }
            break;
        case 2: // fast
            if (pDb->sConvAcc >= _CONV_ACC3)
            {
                pDb->uAdfMode = 3;
            }
            break;
        case 3: // medium
            if (pDb->sConvAcc >= _CONV_ACC_MAX)
            {
                pDb->sConvAcc = _CONV_ACC_MAX;
                pDb->uAdfMode = 4;
            }
            break;
        case 4: // slow 
            pDb->sConvAcc = _CONV_ACC_MAX;
            break;
        default:
            break;
        }
    }
}
/*-------------------------------------------------------------------------*/
void                        gaec_adf_scale
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
	S16 sMax = pSc->sMaxCoef;
	int band = pDb->sMaxCoefBand;

	if (pDb->sConvAcc < _CONV_ACC2)
		return;

	if (sMax > 24000) // scale up
	{
		if (pDb->asShft[band] < 3)
		{
			pDb->asShft[band]++;
			gaec_scale_band(pDb->psAdf, pDb->psAdfM, band, -1);
		}
	}
	else if (sMax < 6000) // scale down
	{
		if (pDb->asShft[band] > -3)
		{
			pDb->asShft[band]--;
			gaec_scale_band(pDb->psAdf, pDb->psAdfM, band, 1);
		}

	}
	else; // leave as is
}

⌨️ 快捷键说明

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