⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtxamrwb.c

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 C
📖 第 1 页 / 共 2 页
字号:

    valExp += valExpTmp;
    valExp += 4;

    for (i = 0; i < FRAME_SIZE; i++)
    {
        tmp = Mul_16s_Sfs(pExc2vec[i], valGain, 15);
        if (valExp > 0)
            pExc2vec[i] = ShiftL_32s(tmp, valExp);
        else
            pExc2vec[i] = tmp >> (-valExp);
    }

    if (valDTXState == DTX_MUTE)
    {
        /* mute comfort noise as it has been quite a long time since last SID update  was performed  */
        valInterFac = st->siSidLast;
        if (valInterFac > 32) valInterFac = 32;

        st->siSidPeriodInv = (1 << 15) / valInterFac;
        st->siSidLast = 0;
        st->siLogEnergyOld = st->siLogEnergy;
        st->siLogEnergy -= 64;
    }
    /* reset interpolation length timer if data has been updated */

    if ((st->siSidFrame != 0) &&
        ((st->siValidData != 0) || ((st->siValidData == 0) && (st->siHangoverAdded) != 0)))
    {
        st->siSidLast = 0;
        st->siDataUpdated = 1;
    }
    return 0;
}

short ownRXDTXHandler(SDtxDecoderState *st, short frameType)
{
    short valDTXState;

    /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */

   if ((frameType == RX_SID_FIRST)  ||
       (frameType == RX_SID_UPDATE) ||
       (frameType == RX_SID_BAD)    ||
       (((st->siGlobalState == DTX) ||
       (st->siGlobalState == DTX_MUTE)) &&
       ((frameType == RX_NO_DATA)   ||
       (frameType == RX_SPEECH_BAD) ||
       (frameType == RX_SPEECH_LOST))))
    {
        valDTXState = DTX;

        if ((st->siGlobalState == DTX_MUTE) &&
            ((frameType == RX_SID_BAD)     ||
             (frameType == RX_SID_FIRST)   ||
             (frameType == RX_SPEECH_LOST) ||
             (frameType == RX_NO_DATA)))
        {
            valDTXState = DTX_MUTE;
        }
        st->siSidLast += 1;

        if (st->siSidLast > DTX_MAX_EMPTY_THRESH)
            valDTXState = DTX_MUTE;
    } else
    {
        valDTXState = SPEECH;
        st->siSidLast = 0;
    }

    if ((st->siDataUpdated == 0) && (frameType == RX_SID_UPDATE))
        st->siAnaElapsedCount = 0;
    st->siAnaElapsedCount = Cnvrt_32s16s(st->siAnaElapsedCount+1);
    st->siHangoverAdded = 0;

    if ((frameType == RX_SID_FIRST)  ||
        (frameType == RX_SID_UPDATE) ||
        (frameType == RX_SID_BAD)    ||
        (frameType == RX_NO_DATA))
    {
       if (st->siAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH)
       {
            st->siHangoverAdded = 1;
            st->siAnaElapsedCount = 0;
            st->siHangoverCount = 0/*1*/;
       } else if (st->siHangoverCount == 0)
       {
            st->siAnaElapsedCount = 0;
       } else
       {
            st->siHangoverCount -= 1;
       }
    } else
    {
       st->siHangoverCount = DTX_HANG_CONST;
    }

    if (valDTXState != SPEECH)
    {
        /* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do
         * backwards analysis if a hangover period has been added according to the state machine above */

        st->siSidFrame = 0/*2*/;
        st->siValidData = 0;

        if (frameType == RX_SID_FIRST)
        {
            st->siSidFrame = 1;
        } else if (frameType == RX_SID_UPDATE)
        {
            st->siSidFrame = 1;
            st->siValidData = 1;
        } else if (frameType == RX_SID_BAD)
        {
            st->siSidFrame = 1;
            st->siHangoverAdded = 0;
        }
    }
    return valDTXState;
}

static void ownAverageIsfHistory(short *pIsfOldvec, short *pIndices, int *pIsfAvrvec)
{
    int i, j, k;
    IPP_ALIGNED_ARRAY(16, short, pIsfTmpvec, 2 * LP_ORDER);
    int s;

    for (k = 0; k < 2; k++)
    {
        if ((pIndices[k] + 1) != 0)
        {
            ippsCopy_16s(&pIsfOldvec[pIndices[k] * LP_ORDER], &pIsfTmpvec[k * LP_ORDER], LP_ORDER);
            ippsCopy_16s(&pIsfOldvec[pIndices[2] * LP_ORDER], &pIsfOldvec[pIndices[k] * LP_ORDER], LP_ORDER);
        }
    }

    for (j = 0; j < LP_ORDER; j++)
    {
        s = 0;
        for (i = 0; i < DTX_HIST_SIZE; i++)
            s += (int)(pIsfOldvec[i * LP_ORDER + j]);
        pIsfAvrvec[j] = s;
    }

    for (k = 0; k < 2; k++)
    {
        if ((pIndices[k] + 1) != 0)
            ippsCopy_16s(&pIsfTmpvec[k * LP_ORDER], &pIsfOldvec[pIndices[k] * LP_ORDER], LP_ORDER);
    }
    return;
}

static void ownFindFrameIndices(short *pIsfOldvec, short *pIndices, SDtxEncoderState *st)
{
    int s, valSumMin, valSumMax, valSumMax2;
    short i, j, tmp;
    short valHistPtr;

    tmp = DTX_HIST_SIZE_MIN_ONE;
    j = -1;
    for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
    {
        j += tmp;
        st->aiSumDist[i] -= st->aiDistMatrix[j];
        tmp -= 1;
    }

    ippsMove_32f((float*)st->aiSumDist, (float*)&st->aiSumDist[1], DTX_HIST_SIZE_MIN_ONE);
    st->aiSumDist[0] = 0;

    tmp = 0;
    for (i = 27; i >= 12; i = (short) (i - tmp))
    {
        tmp += 1;
        ippsMove_32f((float*)&st->aiDistMatrix[i - tmp - tmp], (float*)&st->aiDistMatrix[i - tmp + 1], tmp);
    }

    valHistPtr = st->siHistPtr;
    for (i = 1; i < DTX_HIST_SIZE; i++)
    {
        /* Compute the distance between the latest isf and the other isfs. */
        valHistPtr -= 1;
        if (valHistPtr < 0) valHistPtr = DTX_HIST_SIZE_MIN_ONE;
        s = 0;
        for (j = 0; j < LP_ORDER; j++)
        {
            tmp = pIsfOldvec[st->siHistPtr * LP_ORDER + j] - pIsfOldvec[valHistPtr * LP_ORDER + j];
            s += tmp * tmp;
        }
        st->aiDistMatrix[i - 1] = s << 1;
        st->aiSumDist[0] += st->aiDistMatrix[i - 1];
        st->aiSumDist[i] += st->aiDistMatrix[i - 1];
    }

    /* Find the minimum and maximum distances */
    valSumMax = st->aiSumDist[0];
    valSumMin = st->aiSumDist[0];
    pIndices[0] = 0;
    pIndices[2] = 0;
    for (i = 1; i < DTX_HIST_SIZE; i++)
    {
        if (st->aiSumDist[i] > valSumMax)
        {
            pIndices[0] = i;
            valSumMax = st->aiSumDist[i];
        }
        if (st->aiSumDist[i] < valSumMin)
        {
            pIndices[2] = i;
            valSumMin = st->aiSumDist[i];
        }
    }

    /* Find the second largest distance */
    valSumMax2 = IPP_MIN_32S + 1;
    pIndices[1] = -1;
    for (i = 0; i < DTX_HIST_SIZE; i++)
    {
        if ((st->aiSumDist[i] > valSumMax2) && (i != pIndices[0]))
        {
            pIndices[1] = i;
            valSumMax2 = st->aiSumDist[i];
        }
    }

    for (i = 0; i < 3; i++)
    {
        pIndices[i] = st->siHistPtr - pIndices[i];
        if (pIndices[i] < 0) pIndices[i] += DTX_HIST_SIZE;
    }

    tmp = Norm_32s_I(&valSumMax);
    valSumMin <<= tmp;
    s = 2 * Cnvrt_NR_32s16s(valSumMax) * INV_MED_THRESH;
    if (s <= valSumMin) pIndices[0] = -1;

    valSumMax2 <<= tmp;
    s = 2 * Cnvrt_NR_32s16s(valSumMax2) * INV_MED_THRESH;
    if (s <= valSumMin) pIndices[1] = -1;

    return;
}

static short ownDitherCtrl(SDtxEncoderState *st)
{
    short tmp, valMean, valCNDith, valGainDiff;
    int i, valIsfDiff;

    /* determine how stationary the spectrum of background noise is */
    ippsSum_32s_Sfs(st->aiSumDist, 8, &valIsfDiff, 0);
//    valIsfDiff = 0;
//    for (i = 0; i < 8; i++)
//    {
//        valIsfDiff = Add_32s(valIsfDiff, st->aiSumDist[i]);
//    }
    if ((valIsfDiff >> 26) > 0)
        valCNDith = 1;
    else
        valCNDith = 0;

    /* determine how stationary the energy of background noise is */
    ippsSum_16s_Sfs(st->siLogEnerHist, DTX_HIST_SIZE, &valMean, 3);
    valGainDiff = 0;
    for (i = 0; i < DTX_HIST_SIZE; i++)
    {
        tmp = Abs_16s((short)(st->siLogEnerHist[i] - valMean));
        valGainDiff += tmp;
    }
    if (valGainDiff > GAIN_THRESH) valCNDith = 1;

    return valCNDith;
}

static void ownCNDithering(short *pIsfvec, int *valLogIntEnergy, short *pDitherSeed)
{
    short temp, temp1, valDitherFac, valRandDither, valRandDither2;
    int i;

    /* Insert comfort noise dithering for energy parameter */
    valRandDither = Random(pDitherSeed) >> 1;
    valRandDither2 = Random(pDitherSeed) >> 1;
    valRandDither += valRandDither2;
    *valLogIntEnergy += 2 * valRandDither * GAIN_FACTOR;
    if (*valLogIntEnergy < 0) *valLogIntEnergy = 0;

    /* Insert comfort noise dithering for spectral parameters (ISF-vector) */
    valDitherFac = ISF_FACTOR_LOW;
    valRandDither = Random(pDitherSeed) >> 1;
    valRandDither2 = Random(pDitherSeed) >> 1;
    valRandDither += valRandDither2;
    temp = pIsfvec[0] + ((valRandDither * valDitherFac + 0x00004000) >> 15);

    if (temp < ISF_GAP)
        pIsfvec[0] = ISF_GAP;
    else
        pIsfvec[0] = temp;

    for (i = 1; i < LP_ORDER - 1; i++)
    {
        valDitherFac += ISF_FACTOR_STEP;
        valRandDither = Random(pDitherSeed) >> 1;
        valRandDither2 = Random(pDitherSeed) >> 1;
        valRandDither += valRandDither2;
        temp = pIsfvec[i] + ((valRandDither * valDitherFac + 0x00004000) >> 15);
        temp1 = temp - pIsfvec[i - 1];

        /* Make sure that isf spacing remains at least ISF_DITHER_GAP Hz */
        if (temp1 < ISF_DITHER_GAP)
            pIsfvec[i] = pIsfvec[i - 1] + ISF_DITHER_GAP;
        else
            pIsfvec[i] = temp;
    }

    /* Make sure that pIsfvec[LP_ORDER-2] will not get values above 16384 */
    if (pIsfvec[LP_ORDER - 2] > 16384) pIsfvec[LP_ORDER - 2] = 16384;

    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -