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 + -
显示快捷键?