lecas.c

来自「The line echo canceller (LEC) is designe」· C语言 代码 · 共 658 行 · 第 1/2 页

C
658
字号
        /*    *pFilter += (S16)(Sum/ 0x8000L);  correct coeff */

            *psFlt++ = (S16)(Sum >> 15);
        }
        
    }
    slNormErr = ((S32)pSc->asNormErr[base])<<(16-4);
    slNormErr += 0x8000L;
    slNormErr >>= 16;
    for (Tap = 0; Tap < ILEC_FR_SZ*2; Tap += 1)
    {
	    S32 Sum = (((S32)*psFlt) << 15) + 0x4000L;
    	    Sum += slNormErr * *pData--;

    /*    *pFilter += (S16)(Sum/ 0x8000L);  correct coeff */

        *psFlt++ = (S16)(Sum >> 15);
    }
}
/*-------------------------------------------------------------------------*/
void                        lec_adapt_fast_lowC
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc,
S16 base,
S16 SSS
)
{
	S16 *pData;
	S16 *psFlt;
	S16 Tap;
	S16 k;
	S32 slNormErr;
	
    S32 Tmp = pSc->asErr2[base] * (long)SSS;
    if (Tmp > 32767) Tmp = 32767;
    if (Tmp < -32768) Tmp = -32768;
    pSc->asNormErr[base] = (S16)Tmp;
/* ADAPT */
    pData = pDb->psTxF + LEC_FLT2_SZ + base;
    psFlt = pDb->asAdf2;
    /* Frame 0, pm = 1 */

    slNormErr = ((S32)pSc->asNormErr[base]);

    for (Tap = 0; Tap < ILEC_FR_SZ; Tap += 1)
    {
	    S32 Sum = (((S32)*psFlt) << 15) + 0x4000L;
	        Sum += (slNormErr * *pData--)<<4;

    /*    *pFilter += (S16)(Sum/ 0x8000L);  correct coeff */

        *psFlt++ = (S16)(Sum >> 15);
    }
    for (k = 0; k < 4; k++)
    {
        for (Tap = 0; Tap < ILEC_FR_SZ/2; Tap += 1)
        {
	        S32 Sum = (((S32)*psFlt) << 15) + 0x4000L; 
    	        Sum += (slNormErr * *pData--)<<(6-k);

        /*    *pFilter += (S16)(Sum/ 0x8000L);  correct coeff */

            *psFlt++ = (S16)(Sum >> 15);
        }
    }
}
/*-------------------------------------------------------------------------*/
void                        lec_adapt_slow_highC
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc,
S16 base,
S16 SSS
)
{
	S16 *psData;
	S16 *psFlt;
	S16 Tap;
	S16 k;
	S32 slAcc;

/* NORMALIZE ERROR */
    for (k = 0; k < LEC_SECTION_SZ; k++)
    {
	    slAcc = ((pSc->asErr2[k+base] * (long)SSS + 0x8) >> 4);
        if (slAcc > 32767) slAcc = 32767;
        if (slAcc < -32768) slAcc = -32768;
	    pSc->asNormErr[k+base] = (S16)slAcc;
    }

/* ADAPT */

    psData = pDb->psTxF + LEC_FLT2_SZ + base;
    psFlt = pDb->asAdf2;

    for (Tap = 0; Tap < LEC_FLT2_SZ; Tap += 1)
    {
        S32 slB = 0;
	    slAcc = ((long)*psFlt << 15) + 0x4000L;
	    for (k = 0; k < LEC_SECTION_SZ; k++)
	    {
		    slB += (S32)(pSc->asNormErr[k+base]) * *psData++;
	    }
        slAcc += slB>>2;
        /*    *pFilter += (S16)(Sum/ 0x8000L);  correct coeff */

	    *psFlt++ = (S16)(slAcc >> 15);
        psData   -= LEC_SECTION_SZ + 1; /* next back */
    }
}
/*-------------------------------------------------------------------------*/
void                        lec_adapt_slow_lowC
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc,
S16 base,
S16 SSS
)
{
	S16 *psData;
	S16 *psFlt;
	S16 Tap;
	S16 k;
	S32 slAcc;


    for (k = 0; k < LEC_SECTION_SZ; k++)
    {
	    slAcc = pSc->asErr2[k+base] * (long)SSS;
        if (slAcc > 32767) slAcc = 32767;
        if (slAcc < -32768) slAcc = -32768;
	    pSc->asNormErr[k+base] = (S16)slAcc;
    }

    psData = pDb->psTxF + LEC_FLT2_SZ + base;
    psFlt = pDb->asAdf2;

    for (Tap = 0; Tap < LEC_FLT2_SZ; Tap += 1)
    {
        S32 slB = 0;
	    slAcc = ((long)*psFlt << 15) + 0x4000L;
	    for (k = 0; k < LEC_SECTION_SZ; k++)
	    {
		    slB += (S32)(pSc->asNormErr[k+base]) * *psData++;
	    }
        slAcc += slB << (6-2);

        /*    *pFilter += (S16)(Sum/ 0x8000L);  correct coeff */

	    *psFlt++ = (S16)(slAcc >> 15);
        psData   -= LEC_SECTION_SZ + 1; /* next back */
    }
}

/*-------------------------------------------------------------------------*/
void                         lec_shift_err2C
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc
)
{
	S16 sShift = pDb->Adf2.sShift;
	
    if (sShift) {
    	S16 k;
	    for (k = 0; k < ILEC_FR_SZ; k++)
    	{
    		S32 acc = pSc->asErr2[k];
    		acc += (1<<(sShift-1));
    		acc >>= sShift; 
        	pSc->asErr2[k] = (S16)acc;
        }
    }
}

/*-------------------------------------------------------------------------*/
S16                         lec_step_size_corr_slowC
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc,
S16 sBase
)
{
    /* current error averaging */
    S32 ac0 = 0;
    S16 sEn;
    S16 sErleLoss;
    S16 k;

    for (k = 0; k < LEC_SECTION_SZ; k++)
    {
        ac0 += pSc->asErr2[sBase+k] * (S32) pSc->asErr2[sBase+k];
    }
    ac0 /= LEC_SECTION_SZ;
    ac0 >>= pDb->Adf2.sShift*2;

    sEn = lec_en2log(ac0) + 512*(5-2)+125;

    /* fast up, slow down */
    if (sEn > pDb->sErrAvrEn)
    {
        pDb->sErrAvrEn += (sEn - pDb->sErrAvrEn + 1) >> 1;
    }
    else
    {
        pDb->sErrAvrEn += (sEn - pDb->sErrAvrEn + 4) >> 3;
    }

    sErleLoss = pDb->sErrAvrEn - pSc->sExpectedErrorEn;

    if (pSc->sExpectedErrorEn < pDb->VadErr.sEnNoise)
    {
        if (pSc->sExpectedErrorEn > (pDb->VadErr.sEnNoise - LEC_DB(6)))
        {
            /// within allowed range
            sErleLoss -= (pDb->VadErr.sEnNoise - pSc->sExpectedErrorEn);
        }
        else
        {
            /// lower than allowed range
            sErleLoss -= LEC_DB(6);
        }
    }
    else ; // that's pure loss

    if (sErleLoss < 0) 
        sErleLoss = 0;

    /* we need to take squared coeff */
    return lec_exp(-sErleLoss);

}

/*-------------------------------------------------------------------------*/
S16                         lec_step_size_corr_fastC
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc,
S16 sBase
)
{
    /* current error averaging */
    S32 ac0 = 0;
    S16 sEn;
    S16 sErleLoss;

    ac0 = pSc->asErr2[sBase] * (S32) pSc->asErr2[sBase];
    ac0 >>= pDb->Adf2.sShift*2;

    sEn = lec_en2log(ac0) + 512*(5-2)+125;

    /* fast up, slow down */
    if (sEn > pDb->sErrAvrEn)
    {
        pDb->sErrAvrEn += (sEn - pDb->sErrAvrEn + 4) >> 3;
    }
    else
    {
        pDb->sErrAvrEn += (sEn - pDb->sErrAvrEn + 16) >> 5;
    }

    sErleLoss = pDb->sErrAvrEn - pSc->sExpectedErrorEn;

    if (sErleLoss < 0) 
        sErleLoss = 0;

    /* we need to take squared coeff */
    return lec_exp(-sErleLoss);

}

/*-------------------------------------------------------------------------*/
S16                         lec_step_size_corr_fast2C
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc,
S16 sBase
)
{
    /* current error averaging */
    S32 ac0 = 0;
    S16 sEn;
    S16 sErleLoss;
    S16 sCorr;

    ac0 = pSc->asErr2[sBase] * (S32) pSc->asErr2[sBase];
//    ac0 >>= pDb->Adf2.sShift*2;

    sEn = lec_en2log(ac0)+512*(5-2)+125;

    /* fast up, slow down */
    if (sEn > pDb->sErrAvrEn)
    {
        pDb->sErrAvrEn += (sEn - pDb->sErrAvrEn + 4) >> 3;
    }
    else
    {
        pDb->sErrAvrEn += (sEn - pDb->sErrAvrEn + 16) >> 5;
    }

    sErleLoss = pDb->sErrAvrEn - pSc->sExpectedErrorEn;

    if (sErleLoss < 0) 
        sErleLoss = 0;

    /* we need to take squared coeff */
    {
    	S16 log = -sErleLoss;
    	S32 a = log<<2;
    	S16 t = log>>10;
    	S16 x = 4096 + (S16)(a&4095);
    	if (t > 0) sCorr = x<<t; else sCorr = x>>(-t);
    }
	return sCorr;
}





⌨️ 快捷键说明

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