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

📄 sbr_dec_hf_gen_int.c

📁 audio-video-codecs.rar语音编解码器
💻 C
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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-2006 Intel Corporation. All Rights Reserved.
//
*/

#include<math.h>
#include<string.h>
#include "ipps.h"
#include "ippac.h"
#include "sbr_settings.h"
#include "sbr_dec_struct.h"
#include "sbr_dec_settings_int.h"
#include "sbr_dec_own_int.h"

/********************************************************************/

/* Q(31) */
static Ipp32s SBR_TABLE_NEW_BW_INT_Q31[4][4] = {
  {0x00000000, 0x4ccccccd, 0x73333333, 0x7d70a3d7},
  {0x4ccccccd, 0x60000000, 0x73333333, 0x7d70a3d7},
  {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
  {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
};

/********************************************************************
 *
 * OutPut data: iBwArray, Q(14)
 ********************************************************************/
static Ipp32s sbrCalcChirpFactors(Ipp32s N_Q, Ipp32s *bs_invf_mode_prev,
                                  Ipp32s *bs_invf_mode, Ipp32s *iBwArray )
{
  Ipp32s  i;
  Ipp32s  iNewBw, iTmpBw;

  for (i = 0; i < N_Q; i++) {

    iNewBw = SBR_TABLE_NEW_BW_INT_Q31[bs_invf_mode_prev[i]][bs_invf_mode[i]];

    if (iNewBw < iBwArray[i])
      iTmpBw =
        MUL32_SBR_32S(0x60000000, iNewBw) +
        MUL32_SBR_32S(0x20000000, iBwArray[i]);
    else
      iTmpBw =
        MUL32_SBR_32S(0x74000000, iNewBw) +
        MUL32_SBR_32S(0x0C000000, iBwArray[i]);

    iTmpBw = iTmpBw << 1;
    iBwArray[i] = iTmpBw;

    if (iTmpBw < 0x02000000)
      iBwArray[i] = 0;

    bs_invf_mode_prev[i] = bs_invf_mode[i];
  }
  return 0;
}

/********************************************************************/

static Ipp32s sbrCalcAliasDegree(Ipp32s *ref, Ipp32s *deg, Ipp32s k0)
{

  Ipp32s  sign = 0;
  Ipp32s  k;

  ippsZero_32s(deg, k0);
  ref[0] = 0;
  deg[1] = 0;

  for (k = 2; k < k0; k++) {
    if ((k % 2 == 0) && (ref[k] < 0)) {
      sign = 1;
    } else if ((k % 2 == 1) && (ref[k] > 0)) {
      sign = -1;
    } else {
      sign = 0;
      continue;
    }

    if (sign * ref[k - 1] < 0) {
      deg[k] = 1 << 29;
      if (sign * ref[k - 2] > 0) {
        deg[k - 1] = (1 << 29) - (MUL32_SBR_32S( ref[k - 1] << 1, ref[k - 1] << 1) <<1 );
      }
    } else {
      if (sign * ref[k - 2] > 0) {
        //deg[k] = 1 - ref[k - 1] * ref[k - 1];
        deg[k] = (1 << 29) - (MUL32_SBR_32S( ref[k - 1] << 1, ref[k - 1] << 1) <<1 );
      }
    }
  }

  return 0;     // OK
}

/********************************************************************/

static Ipp32s sbrHFGeneratorHQ(
                      /*
                       * in data
                       */
                              Ipp32sc** iXBuf,
                              Ipp32s *vbwArray, sSBRDecComState * pSbr,
                              Ipp32s l_start, Ipp32s l_end,
                      /*
                       * out data
                       */
                              Ipp32sc** iYBuf)
{
  /* values */
  Ipp32s  i, x, q, k_0, k, p, g, l;

  Ipp32s  iBwAr, iBwAr2;
  Ipp32sc sumY;//sumYRe, sumYIm;
  Ipp32s  icA0Re, icA0Im, icA1Re, icA1Im;

  Ipp32sc** pX = iXBuf + SBR_TIME_HFADJ;

  Ipp32sc** pY = iYBuf + SBR_TIME_HFADJ;

  Ipp8u   isNonCalcPredictCoef[64];
  Ipp32sc a0Coefs[64], a1Coefs[64];

  /* reset values */
  ippsSet_8u(1, isNonCalcPredictCoef, 64);

  /* code */
  for (i = 0; i < pSbr->sbrFreqTabsState.numPatches; i++) {
    k_0 = 0;
    for (q = 0; q < i; q++) {
      k_0 += pSbr->sbrFreqTabsState.patchNumSubbandsTab[q];
    }

    k_0 += pSbr->kx;
    for (x = 0; x < pSbr->sbrFreqTabsState.patchNumSubbandsTab[i]; x++) {
      k = k_0 + x;
      p = pSbr->sbrFreqTabsState.patchStartSubbandTab[i] + x;

      for (g = 0; g < pSbr->sbrFreqTabsState.nNoiseBand; g++) {
        if ((k >= pSbr->sbrFreqTabsState.fNoiseBandTab[g]) && (k < pSbr->sbrFreqTabsState.fNoiseBandTab[g + 1]))
          break;
      }

      iBwAr = vbwArray[g];// Q(31)

      if ( iBwAr > 0) {

        /* Predict */
        if ( isNonCalcPredictCoef[p] ) {
          ippsPredictOneCoef_SBRHQ_32sc_D2L(iXBuf, &a0Coefs[p], &a1Coefs[p], p, 38);
          isNonCalcPredictCoef[p] = 0;
        }

        // Q(31) * Q(31) * Q(-32) = Q(30)
        iBwAr2 = MUL32_SBR_32S(vbwArray[g], vbwArray[g]);
        iBwAr2 <<= 1;       // Q(31)

      // BwArray
        // Q(31) * Q(29) * Q(-32) = Q(28)
        icA0Re = MUL32_SBR_32S(iBwAr, a0Coefs[p].re);

        // Q(31) * Q(29) * Q(-32) = Q(28)
        icA0Im = MUL32_SBR_32S(iBwAr, a0Coefs[p].im);

        // Q(31) * Q(29) * Q(-32) = Q(28)
        icA1Re = MUL32_SBR_32S(iBwAr2, a1Coefs[p].re);

        // Q(31) * Q(29) * Q(-32) = Q(28)
        icA1Im = MUL32_SBR_32S(iBwAr2, a1Coefs[p].im);

        for (l = l_start; l < l_end; l++) {

  /*
  * bw * Alpha0 * XLow[l-1] = Q(28) * Q(5) * Q(-32) = Q(1)
  */
          sumY.re =
            MUL32_SBR_32S(pX[l - 1][p].re,icA0Re) -
            MUL32_SBR_32S(pX[l - 1][p].im, icA0Im);

          sumY.im =
            MUL32_SBR_32S(pX[l - 1][p].re,icA0Im) +
            MUL32_SBR_32S(pX[l - 1][p].im, icA0Re);

  /*
  * bw^2 * Alpha1 * XLow[l-2] = Q(28) * Q(5) * Q(-32) = Q(1)
  */
          sumY.re +=
            MUL32_SBR_32S(pX[l - 2][p].re,icA1Re) -
            MUL32_SBR_32S(pX[l - 2][p].im, icA1Im);

          sumY.im +=
            MUL32_SBR_32S(pX[l - 2][p].re, icA1Im) +
            MUL32_SBR_32S(pX[l - 2][p].im, icA1Re);

  /*
  * this check may be improved in the future
  */
          if (abs(sumY.re) < (((1 << 30) - 1) >> 4) &&
              abs(sumY.im) < (((1 << 30) - 1) >> 4)) {
                sumY.re <<= 4;
                sumY.im <<= 4;

          } else {

            sumY.re = (sumY.re > 0) ? (1 << 30) - 1 : -(1 << 30);
            sumY.im = (sumY.im > 0) ? (1 << 30) - 1 : -(1 << 30);
          }

          pY[l][k].re = pX[l - 0][p].re + sumY.re;
          pY[l][k].im = pX[l - 0][p].im + sumY.im;

        }// for (l = l_start

      } else { //if (iBwAr == 0)

        for (l = l_start; l < l_end; l++) {
          pY[l][k].re = pX[l - 0][p].re;
          pY[l][k].im = pX[l - 0][p].im;
        }
      }// endif(bwArr > 0) ?

    }//for (x = 0

  }// for (i = 0;

  return 0;     // OK
}

/********************************************************************/

static Ipp32s sbrHFGeneratorLP(
                      /* in data  */
                              Ipp32s** piXBufRe,
                      /* out data */
                              Ipp32s** piYBufRe,
                              Ipp32s*  iBwArray,
                              sSBRDecComState* pSbr,
                              Ipp32s l_start,
                              Ipp32s l_end,
                              Ipp32s *deg,
                              Ipp32s *degPatched)
{
  Ipp32s  i, x, q, k_0, k, p, g, l;
  Ipp32s  iBwAr, iBwAr2;
  Ipp32s  sumYRe;
  Ipp32s  icA0Re, icA1Re;
  Ipp32s  coefA0Re, coefA1Re, iRefCoef;

  Ipp32s** pXRe = piXBufRe + SBR_TIME_HFADJ;
  Ipp32s** pYRe = piYBufRe + SBR_TIME_HFADJ;

  sSBRFeqTabsState* pFTState = &(pSbr->sbrFreqTabsState);


 // ippsZero_32f(degPatched, MAX_NUM_ENV_VAL);

  for (i = 0; i < pFTState->numPatches; i++) {
    k_0 = 0;
    for (q = 0; q < i; q++) {
      k_0 += pFTState->patchNumSubbandsTab[q];
    }

    k_0 += pSbr->kx;
    for (x = 0; x < pFTState->patchNumSubbandsTab[i]; x++) {
      k = k_0 + x;
      p = pFTState->patchStartSubbandTab[i] + x;

      for (g = 0; g < pFTState->nNoiseBand; g++) {
        if ((k >= pFTState->fNoiseBandTab[g]) && (k < pFTState->fNoiseBandTab[g + 1]))
          break;
      }

      iBwAr = iBwArray[g];// Q(31)

      if ( iBwAr > 0 ) {

        // if( ! isPredict[p] )
        {
           //ownPredictOneCoef_SBR_R_32s_D2L(piXBufRe, &coefA0Re, &coefA1Re, &iRefCoef, p, 38);
          ippsPredictOneCoef_SBRLP_32s_D2L(piXBufRe, &coefA0Re, &coefA1Re, &iRefCoef, p, 38, 1);
        }

        // Q(31) * Q(31) * Q(-32) = Q(30)
        iBwAr2 = MUL32_SBR_32S(iBwAr, iBwAr);
        iBwAr2 <<= 1;       // Q(31)

      // BwArray
        // Q(31) * Q(29) * Q(-32) = Q(28)
        icA0Re = MUL32_SBR_32S(iBwAr, coefA0Re);

        // Q(31) * Q(29) * Q(-32) = Q(28)
        icA1Re = MUL32_SBR_32S(iBwAr2, coefA1Re);


        for (l = l_start; l < l_end; l++) {

  /*
  * bw * Alpha0 * XLow[l-1] = Q(28) * Q(5) * Q(-32) = Q(1)
  */
          sumYRe = MUL32_SBR_32S(pXRe[l - 1][p],icA0Re);

  /*
  * bw^2 * Alpha1 * XLow[l-2] = Q(28) * Q(5) * Q(-32) = Q(1)
  */
          sumYRe += MUL32_SBR_32S(pXRe[l - 2][p],icA1Re);

  /*
  * this check may be improved in the future
  */
          if ( abs(sumYRe) < (((1 << 30) - 1) >> 4) ) {
            sumYRe <<= 4;

          } else {

            sumYRe = (sumYRe > 0) ? (1 << 30) - 1 : -(1 << 30);
          }

          pYRe[l][k] = pXRe[l - 0][p] + sumYRe;

          //pYBufRe[l+2][k] = pYRe[l][k] / 32.f ;

        }// for (l = l_start


      }else{ //if( bwArr == 0)

        for (l = l_start; l < l_end; l++) {
          pYRe[l][k] = pXRe[l - 0][p];
          //pYBufRe[l+2][k] = pYRe[l][k] / 32.f ;
        }

      }

/*-------------------------------------------------------------*/
      //if (mode == HEAAC_LP_MODE) {
        if (x == 0)
          degPatched[k] = 0;
        else
          degPatched[k] = deg[p];
    //  }
/*-------------------------------------------------------------*/
    }
  }

  //if (mode == HEAAC_LP_MODE) {
    k_0 = 0;
    for (q = 0; q < pFTState->numPatches; q++)
      k_0 += pFTState->patchNumSubbandsTab[q];

    for (k = pSbr->kx + k_0; k < 64; k++)
      degPatched[k] = 0;
  //}

  return 0;     // OK
}

/********************************************************************/

Ipp32s sbriGenerationHF(Ipp32s** iXBuf,
                        Ipp32s** iYBuf,
                        sSBRDecComState * comState, Ipp32s *bwArray,
                        Ipp32s *degPatchedCoefs, Ipp32s ch, Ipp32s decode_mode)
{
  Ipp32s refCoefs[64];
  Ipp32s a0Coefs[64];
  Ipp32s a1Coefs[64];

  Ipp32s degCoefs[64];

  Ipp32s  l_start = RATE * comState->sbrFIState[ch].bordersEnv[0];
  Ipp32s  l_end   = RATE * comState->sbrFIState[ch].bordersEnv[comState->sbrFIState[ch].nEnv];


  sbrCalcChirpFactors(comState->sbrFreqTabsState.nNoiseBand, &(comState->bs_invf_mode_prev[ch][0]),
                      &(comState->bs_invf_mode[ch][0]), bwArray);

  if (HEAAC_HQ_MODE == decode_mode)
    sbrHFGeneratorHQ( (Ipp32sc**)iXBuf, bwArray, comState, l_start, l_end, (Ipp32sc**)iYBuf);

  else { //if (HEAAC_LP_MODE == decode_mode)

    ippsZero_32s(degPatchedCoefs, 64);

   {
     Ipp32s k;
     for(k=0; k<comState->k0; k++)
     {
       ippsPredictOneCoef_SBRLP_32s_D2L(iXBuf, &a0Coefs[k], &a1Coefs[k], &refCoefs[k], k, 38, 0);
     }
   }

   sbrCalcAliasDegree(refCoefs, degCoefs, comState->k0);

   sbrHFGeneratorLP(iXBuf, iYBuf, bwArray, comState, l_start, l_end,
                    degCoefs, degPatchedCoefs);

  }

  return 0;     // OK
}

/********************************************************************/

⌨️ 快捷键说明

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