# NLP

## 互功率谱计算

cohde(Ωi)=|Rde(Ωi)|2Rd(Ωi)Re(Ωi);Rde(Ωi)=Df(Ωi)Ef(Ωi);

cohxd(Ωi)=|Rxd(Ωi)|2Rx(Ωi)Rd(Ωi);Rxd(Ωi)=Xf(Ωi)Df(Ωi);

Xf(Ωi)iEfAECiDfi


// 计算第3到第14子带互功率谱和
hNlXdAvg = 0;
for (i = 2; i < 14; i++)
{
hNlXdAvg += cohxd[i];
}

// 值越小，近端包含远端参考信号成分越少，相对为近端讲话(Near Talk NT)
// 值越大，近端包含远端参考信号成分越多；可能是双端讲话(Double Talk DT)时近端能量相对较低，或者仅远端讲话(Far Talk FT)时环境响应函数滤波严重。
hNlXdAvg /= 12; // 计算近端和远端的互功率谱

// 不相关性
hNlXdAvg = 1 - hNlXdAvg;

hNlDeAvg = 0;
for (i = 2; i < 14; i++)
{
hNlDeAvg += cohde[i];
}

// 值越小，AEC 强滤波；反之值越大，AEC 弱滤波
hNlDeAvg /= 12; // 计算近端和AEC输出的互功率谱

if (hNlXdAvg < 0.75f && hNlXdAvg < aec->hNlXdAvgMin)
{
aec->hNlXdAvgMin = hNlXdAvg;
}

// 无法确认时，保留上一帧判定
if (hNlDeAvg > 0.98f && hNlXdAvg > 0.9f)
{ // 相对为NT，且 AEC 弱滤波处理
aec->stNearState = 1;
}
else if (hNlDeAvg < 0.95f || hNlXdAvg < 0.8f)
{ // AEC 非弱滤波，或者不是NT
aec->stNearState = 0;
}

if (aec->hNlXdAvgMin == 1)
{ // 初始默认双端讲话
aec->echoState = 0;
aec->overDrive = min_overdrive[aec->nlp_mode];

// DT
if (aec->stNearState == 1)
{ // NT，hNl 选择偏大，取cohde
memcpy(hNl, cohde, sizeof(hNl));
hNlFb = hNlDeAvg;
hNlFbLow = hNlDeAvg;
}
else
{ // FT or DT，hNL选择偏小
for (i = 0; i < AEC_PART_LEN1; i++)
{
hNl[i] = 1 - cohxd[i];
}
hNlFb = hNlXdAvg;
hNlFbLow = hNlXdAvg;
}
}
else
{
if (aec->stNearState == 1)
{// NT，hNl 选择偏大，取cohde
aec->echoState = 0;
memcpy(hNl, cohde, sizeof(hNl));
hNlFb = hNlDeAvg;
hNlFbLow = hNlDeAvg;
}
else
{// FT or DT，hNL选择偏小
aec->echoState = 1;

for (i = 0; i < AEC_PART_LEN1; i++)
{
hNl[i] = WEBRTC_SPL_MIN(cohde[i], 1 - cohxd[i]);
}

// Select an order statistic from the preferred bands.
// TODO: Using quicksort now, but a selection algorithm may be preferred.
memcpy(hNlPref, &hNl[2], sizeof(float) * 12);
qsort(hNlPref, 12, sizeof(float), CmpFloat);

hNlFb = hNlPref[(int)floor(0.75f* 11)];
hNlFbLow = hNlPref[(int)floor(0.5f* 11)];
}
}

// Track the local filter minimum to determine suppression overdrive
if (hNlFbLow < 0.6f && hNlFbLow < aec->hNlFbLocalMin)
{
aec->hNlFbLocalMin = hNlFbLow;
aec->hNlFbMin = hNlFbLow;
aec->hNlNewMin = 1;
aec->hNlMinCtr = 0;
}

aec->hNlFbLocalMin = WEBRTC_SPL_MIN(aec->hNlFbLocalMin + 0.0008f / aec->mult, 1);
aec->hNlXdAvgMin   = WEBRTC_SPL_MIN(aec->hNlXdAvgMin + 0.0006f / aec->mult, 1);

if (aec->hNlNewMin == 1)
{
aec->hNlMinCtr++;
}

// 之所以是2，是为确认滤波器是极小值
if (aec->hNlMinCtr == 2)
{
aec->hNlNewMin = 0;
aec->hNlMinCtr = 0;
aec->overDrive = WEBRTC_SPL_MAX(kTargetSupp[aec->nlp_mode] / ((float)log(aec->hNlFbMin + AEC_DIV_PROTECT) + AEC_DIV_PROTECT), min_overdrive[aec->nlp_mode]);
}

// Smooth the overdrive. 平滑抑制系数
// 快速响应过抑制，慢响应欠抑制
if (aec->overDrive < aec->overDriveSm)
{
aec->overDriveSm = 0.99f * aec->overDriveSm + 0.01f * aec->overDrive;
}
else
{
aec->overDriveSm = 0.9f * aec->overDriveSm + 0.1f * aec->overDrive;
}

for (i = 0; i < 65; i++)
{
// Weight subbands
if (hNl[i] > hNlFb)
{
hNl[i] = weightCurve[i] * hNlFb + (1 - weightCurve[i]) * hNl[i];
}
hNl[i] = powf(hNl[i], aec->overDriveSm * overDriveCurve[i]);

if (EnableFlag == 1)
{
// Suppress error signal
efw[0][i] *= hNl[i];
efw[1][i] *= -hNl[i];
}
}
// [0:1:63]/64
weightCurve[65] =
{
0.0000f, 0.1000f, 0.1378f, 0.1535f, 0.1655f, 0.1756f, 0.1845f, 0.1926f,
0.2000f, 0.2069f, 0.2134f, 0.2195f, 0.2254f, 0.2309f, 0.2363f, 0.2414f,
0.2464f, 0.2512f, 0.2558f, 0.2604f, 0.2648f, 0.2690f, 0.2732f, 0.2773f,
0.2813f, 0.2852f, 0.2890f, 0.2927f, 0.2964f, 0.3000f, 0.3035f, 0.3070f,
0.3104f, 0.3138f, 0.3171f, 0.3204f, 0.3236f, 0.3268f, 0.3299f, 0.3330f,
0.3360f, 0.3390f, 0.3420f, 0.3449f, 0.3478f, 0.3507f, 0.3535f, 0.3563f,
0.3591f, 0.3619f, 0.3646f, 0.3673f, 0.3699f, 0.3726f, 0.3752f, 0.3777f,
0.3803f, 0.3828f, 0.3854f, 0.3878f, 0.3903f, 0.3928f, 0.3952f, 0.3976f,
0.4000f
};

overDriveCurve[65] =
{
1.0000f, 1.1250f, 1.1768f, 1.2165f, 1.2500f, 1.2795f, 1.3062f, 1.3307f,
1.3536f, 1.3750f, 1.3953f, 1.4146f, 1.4330f, 1.4507f, 1.4677f, 1.4841f,
1.5000f, 1.5154f, 1.5303f, 1.5449f, 1.5590f, 1.5728f, 1.5863f, 1.5995f,
1.6124f, 1.6250f, 1.6374f, 1.6495f, 1.6614f, 1.6731f, 1.6847f, 1.6960f,
1.7071f, 1.7181f, 1.7289f, 1.7395f, 1.7500f, 1.7603f, 1.7706f, 1.7806f,
1.7906f, 1.8004f, 1.8101f, 1.8197f, 1.8292f, 1.8385f, 1.8478f, 1.8570f,
1.8660f, 1.8750f, 1.8839f, 1.8927f, 1.9014f, 1.9100f, 1.9186f, 1.9270f,
1.9354f, 1.9437f, 1.9520f, 1.9601f, 1.9682f, 1.9763f, 1.9843f, 1.9922f,
2.0000f
};