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
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值