📄 gaecadf.c
字号:
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 + -