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

📄 dtxamrwb.c

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*/////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2005 Intel Corporation. All Rights Reserved.
//
//     Intel(R) Integrated Performance Primitives
//     USC - Unified Speech Codec interface library
//
// By downloading and installing USC codec, you hereby agree that the
// accompanying Materials are being provided to you under the terms and
// conditions of the End User License Agreement for the Intel(R) Integrated
// Performance Primitives product previously accepted by you. Please refer
// to the file ipplic.htm located in the root directory of your Intel(R) IPP
// product installation for more information.
//
// A speech coding standards promoted by ITU, ETSI, 3GPP and other
// organizations. Implementations of these standards, or the standard enabled
// platforms may require licenses from various entities, including
// Intel Corporation.
//
//
// Purpose: AMRWB speech codec DTX utilities.
//
*/

#include "ownamrwb.h"

static void ownAverageIsfHistory(short *pIsfOldvec, short *pIndices, int *pIsfAvrvec);
static void ownFindFrameIndices(short *pIsfOldvec, short *pIndices, SDtxEncoderState *st);
static short ownDitherCtrl(SDtxEncoderState *st);
static void ownCNDithering(short *pIsfvec, int *valLogIntEnergy, short *pDitherSeed);

short ownDTXEncReset(SDtxEncoderState *st, short *pIsfInit)
{
    int i;

    if (st == (SDtxEncoderState*)NULL) return -1;

    st->siHistPtr = 0;
    st->siLogEnerIndex = 0;

    for (i = 0; i < DTX_HIST_SIZE; i++)
    {
        ippsCopy_16s(pIsfInit, &st->asiIsfHistory[i * LP_ORDER], LP_ORDER);
    }
    st->siCngSeed = RND_INIT;

    ippsZero_16s(st->siLogEnerHist, DTX_HIST_SIZE);

    st->siHangoverCount = DTX_HANG_CONST;
    st->siAnaElapsedCount = 32767;

    ippsZero_16s((short*)st->aiDistMatrix, 28*2);
    ippsZero_16s((short*)st->aiSumDist, (DTX_HIST_SIZE - 1)*2);

    return 1;
}

short ownDTXEnc(SDtxEncoderState *st, short *pIsfvec, short *pExc2vec, unsigned short *pPrmsvec)
{
    short valLogEnergy, valGain, valLevelTmp, valExp, valExpTmp, tmp;
    short valLogIntPart, valLogFracPart;
    int i, valEner, valLevel;
    short pIsfOrdervec[3];
    short valCNDith;
    IPP_ALIGNED_ARRAY(16, int, pIsf32svec, LP_ORDER);

    /* VOX mode computation of SID parameters */
    ippsZero_16s((short*)pIsf32svec, LP_ORDER*2);
    /* average energy and isf */
    /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer */
    ippsSum_16s_Sfs(st->siLogEnerHist, DTX_HIST_SIZE, &valLogEnergy, 0);
    ownFindFrameIndices(st->asiIsfHistory, pIsfOrdervec, st);
    ownAverageIsfHistory(st->asiIsfHistory, pIsfOrdervec, pIsf32svec);

    for (i = 0; i < LP_ORDER; i++)
    {
        pIsfvec[i] = (short)(pIsf32svec[i] >> 3);
    }

    /* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E) */
    valLogEnergy >>= 2;
    valLogEnergy += 512;

    /* Multiply by 2.625 to get full 6 bit range */
    valLogEnergy = Mul_16s_Sfs(valLogEnergy, 21504, 15);

    /* Quantize Energy */
    st->siLogEnerIndex = valLogEnergy >> 6;
    if (st->siLogEnerIndex > 63) st->siLogEnerIndex = 63;
    if (st->siLogEnerIndex < 0) st->siLogEnerIndex = 0;

    /* Quantize ISFs */
    ippsISFQuantDTX_AMRWB_16s(pIsfvec, pIsfvec, (short*)pPrmsvec);
    pPrmsvec += 5;

    *(pPrmsvec)++ = st->siLogEnerIndex;

    valCNDith = ownDitherCtrl(st);
    *(pPrmsvec)++ = valCNDith;

    /* level = (float)( pow( 2.0f, (float)st->siLogEnerIndex / 2.625 - 2.0 ) );    */
    valLogEnergy = (st->siLogEnerIndex << 9);

    /* Divide by 2.625; siLogEnergy will be between 0:24  */
    valLogEnergy = Mul_16s_Sfs(valLogEnergy, 12483, 15);

    valLogIntPart = valLogEnergy >> 10;
    valLogFracPart = (short) (valLogEnergy & 0x3ff);
    valLogFracPart <<= 5;
    valLogIntPart += 15;

    valLevel = ownPow2_AMRWB(valLogIntPart, valLogFracPart);
    valExpTmp = 15 - Norm_32s_I(&valLevel);
    valLevelTmp = (short)(valLevel >> 16);

    /* generate white noise vector */
    for (i = 0; i < FRAME_SIZE; i++)
    {
        pExc2vec[i] = Random(&(st->siCngSeed)) >> 4;
    }

    /* energy of generated excitation */
    ippsDotProd_16s32s_Sfs( pExc2vec, pExc2vec,FRAME_SIZE, &valEner, -1);
    valEner = Add_32s(valEner, 1);

    valExp = (30 - Norm_32s_I(&valEner));
    ownInvSqrt_AMRWB_32s16s_I(&valEner, &valExp);

    valGain = (short)(valEner >> 16);
    valGain = Mul_16s_Sfs(valLevelTmp, valGain, 15);

    valExp += valExpTmp;

    /* Multiply by sqrt(FRAME_SIZE)=16, i.e. shift left by 4 */
    valExp += 4;

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

    return 0;
}

short ownDTXDecReset(SDtxDecoderState * st, short *pIsfInit)
{
    int i;

    if (st == (SDtxDecoderState*) NULL) return -1;

    st->siSidLast = 0;
    st->siLogEnergy = 3500;
    st->siLogEnergyOld = 3500;
    st->siSidPeriodInv = (1 << 13);

    /* low level noise for better performance in  DTX handover cases */

    st->siCngSeed = RND_INIT;
    st->siHistPtr = 0;

    ippsCopy_16s(pIsfInit, st->asiIsf, LP_ORDER);
    ippsCopy_16s(pIsfInit, st->asiIsfOld, LP_ORDER);
    ippsSet_16s(st->siLogEnergy, st->siLogEnerHist, DTX_HIST_SIZE);

    for (i = 0; i < DTX_HIST_SIZE; i++)
    {
        ippsCopy_16s(pIsfInit, &st->asiIsfHistory[i * LP_ORDER], LP_ORDER);
    }

    st->siAnaElapsedCount = 32767;
    st->siHangoverCount = DTX_HANG_CONST;
    st->siValidData = 0;
    st->siSidFrame = 0;
    st->siGlobalState = SPEECH;
    st->siHangoverAdded = 0;
    st->siDitherSeed = RND_INIT;
    st->siDataUpdated = 0;
    st->siComfortNoiseDith = 0;

    return 0;
}

short ownDTXDec(SDtxDecoderState *st, short *pExc2vec, short valDTXState, short *pIsfvec,
              const unsigned short *pPrmsvec)
{
    short valLogEnergyIndex;
    short valIntFac;
    short valGain;
    short valHistPtr;
    short valInterFac;
    short tmp, valExp, valExpTmp, valLogIntPart, valLogFracPart, valLevelTmp;
    int i, j, valLogIntEnergy, valLevel, valEner;
    IPP_ALIGNED_ARRAY(16, int, pIsf32svec, LP_ORDER);

    if ((st->siHangoverAdded != 0) && (st->siSidFrame != 0))
    {
        /* sid_first after dtx hangover period or sid_upd after dtxhangover */
        /* consider  twice the last frame */
        valHistPtr = st->siHistPtr + 1;
        if (valHistPtr == DTX_HIST_SIZE) valHistPtr = 0;

        ippsCopy_16s(&st->asiIsfHistory[st->siHistPtr * LP_ORDER], &st->asiIsfHistory[valHistPtr * LP_ORDER], LP_ORDER);
        st->siLogEnerHist[valHistPtr] = st->siLogEnerHist[st->siHistPtr];

        ippsZero_16s((short*)pIsf32svec, LP_ORDER*2);

        ippsSum_16s_Sfs(st->siLogEnerHist, DTX_HIST_SIZE, &st->siLogEnergy, 0);
        for (i = 0; i < DTX_HIST_SIZE; i++)
        {
            for (j = 0; j < LP_ORDER; j++)
            {
                pIsf32svec[j] += (int)(st->asiIsfHistory[i * LP_ORDER + j]);
            }
        }

        st->siLogEnergy >>= 1;
        st->siLogEnergy += 1024;

        if (st->siLogEnergy < 0) st->siLogEnergy = 0;

        for (j = 0; j < LP_ORDER; j++)
        {
            st->asiIsf[j] = (short)(pIsf32svec[j] >> 3);
        }
    }

    if (st->siSidFrame != 0)
    {
        ippsCopy_16s(st->asiIsf, st->asiIsfOld, LP_ORDER);
        st->siLogEnergyOld = st->siLogEnergy;

        if (st->siValidData != 0)           /* new data available (no CRC) */
        {
            valInterFac = st->siSidLast;
            if (valInterFac > 32) valInterFac = 32;
            if (valInterFac >= 2)
                st->siSidPeriodInv = (1 << 15) / valInterFac;
            else
                st->siSidPeriodInv = (1 << 14);

            ippsISFQuantDecodeDTX_AMRWB_16s((short*)pPrmsvec, st->asiIsf);
            pPrmsvec += 5;

            valLogEnergyIndex = *(pPrmsvec)++;

            /* read background noise stationarity information */
            st->siComfortNoiseDith = *(pPrmsvec)++;
            st->siLogEnergy = valLogEnergyIndex << 9;
            st->siLogEnergy = Mul_16s_Sfs(st->siLogEnergy, 12483, 15);

            if ((st->siDataUpdated == 0) || (st->siGlobalState == SPEECH))
            {
                ippsCopy_16s(st->asiIsf, st->asiIsfOld, LP_ORDER);
                st->siLogEnergyOld = st->siLogEnergy;
            }
        }
    }

    if ((st->siSidFrame != 0) && (st->siValidData != 0))
    {
        st->siSidLast = 0;
    }
    /* Interpolate SID info */
    valIntFac = st->siSidLast << 10;
    valIntFac = Mul_16s_Sfs(valIntFac, st->siSidPeriodInv, 15);

    if (valIntFac > 1024) valIntFac = 1024;
    valIntFac <<= 4;

    valLogIntEnergy = 2 * valIntFac * st->siLogEnergy;
    ownMulC_16s_Sfs(st->asiIsf, valIntFac, pIsfvec, LP_ORDER, 15);

    valIntFac = 16384 - valIntFac;

    valLogIntEnergy += 2 * valIntFac * st->siLogEnergyOld;

    for (i = 0; i < LP_ORDER; i++)
    {
        pIsfvec[i] += Mul_16s_Sfs(valIntFac, st->asiIsfOld[i], 15);
        pIsfvec[i] <<= 1;
    }

    /* If background noise is non-stationary, insert comfort noise dithering */
    if (st->siComfortNoiseDith != 0)
    {
        ownCNDithering(pIsfvec, &valLogIntEnergy, &st->siDitherSeed);
    }
    valLogIntEnergy >>= 9;
    valLogIntPart = (short)(valLogIntEnergy >> 16);
    valLogFracPart = (short)((valLogIntEnergy - (int)(valLogIntPart << 16)) >> 1);
    valLogIntPart += (16 - 1);

    valLevel = ownPow2_AMRWB(valLogIntPart, valLogFracPart);
    valExpTmp = 15 - Norm_32s_I(&valLevel);
    valLevelTmp = (short)(valLevel >> 16);

    /* generate white noise vector */
    for (i = 0; i < FRAME_SIZE; i++)
    {
        pExc2vec[i] = Random(&(st->siCngSeed)) >> 4;
    }

    /* energy of generated excitation */
    ippsDotProd_16s32s_Sfs( pExc2vec, pExc2vec,FRAME_SIZE, &valEner, -1);
    valEner = Add_32s(valEner, 1);

    valExp = (30 - Norm_32s_I(&valEner));
    ownInvSqrt_AMRWB_32s16s_I(&valEner, &valExp);

    valGain = (short)(valEner >> 16);
    valGain = Mul_16s_Sfs(valLevelTmp, valGain, 15);

⌨️ 快捷键说明

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