📄 lecas.cpp
字号:
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_high
/*-------------------------------------------------------------------------*/
(
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_low
/*-------------------------------------------------------------------------*/
(
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_err2
/*-------------------------------------------------------------------------*/
(
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_slow
/*-------------------------------------------------------------------------*/
(
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_fast
/*-------------------------------------------------------------------------*/
(
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_fast2
/*-------------------------------------------------------------------------*/
(
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;
}
/*-------------------------------------------------------------------------*/
void lec_adapt_fast
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc
)
{
S16 base;
U16 uEn;
pSc->slEn = lec_get_xz(pDb->psHst + LEC_FLT2_SZ,
pDb->psTxF + LEC_FLT2_SZ);
for (base = 0; base < ILEC_FR_SZ; base++)
{
S32 slEn;
S16 SSS; /* corrected step size */
/* CANCEL ECHO */
pSc->asErr2[base] = lec_cancel(
pDb->psHst + LEC_FLT2_SZ + base,
pDb->asAdf2,
pSc->psRx[base]
);
if (base != 0)
{
pSc->slEn = lec_update_xz(pSc->slEn,
pDb->psHst + LEC_FLT2_SZ + base,
pDb->psTxF + LEC_FLT2_SZ + base
);
}
slEn = pSc->slEn + pDb->Adf2.slAcc;
uEn = lec_step_size(slEn, &pSc->sStepSize);
pSc->uAdaptMode |= uEn<<2;
/* compute energy and step size */
/* ADJUST STEP SIZE */
pSc->sStepCorr = lec_step_size_corr_fast2(pDb, pSc, base);
SSS = (S16)((pSc->sStepSize * (S32) pSc->sStepCorr + (1<<11))>>12);
switch(uEn) {
case 1:
lec_adapt_fast_high(pDb, pSc, base, SSS);
break;
case 2:
lec_adapt_fast_low(pDb, pSc, base, SSS);
break;
default:
break;
}
} /* end of for: ILEC_FR_SZ */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -