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

📄 sbr_dec_hf_gen_fp.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 "ipps.h"
#include "ippac.h"
#include "sbr_settings.h"
#include "sbr_dec_struct.h"

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

static Ipp32f SBR_TABLE_NEW_BW[4][4] = {
  {0.f, 0.6f, 0.9f, 0.98f},
  {0.6f, 0.75f, 0.9f, 0.98f},
  {0.f, 0.75f, 0.9f, 0.98f},
  {0.f, 0.75f, 0.9f, 0.98f}
};

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

static  IppStatus ownPredictCoef_SBR_R_32f_D2L(Ipp32f **pSrc,
                                               Ipp32f *pAlpha0, Ipp32f *pAlpha1,
                                               Ipp32f *pReflectCoef, Ipp32s k0,
                                               Ipp32s len);

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

static Ipp32s sbrCalcAliasDegree(Ipp32f *ref, Ipp32f *deg, Ipp32s k0)
{
  Ipp32s  sign = 0;
  Ipp32s  k;

  ippsZero_32f(deg, k0);
  ref[0] = 0.0f;
  deg[1] = 0.0f;

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

    if (sign * ref[k - 1] < 0) {
      deg[k] = 1.0f;
      if (sign * ref[k - 2] > 0.0f) {
        deg[k - 1] = 1 - ref[k - 1] * ref[k - 1];
      }
    } else {
      if (sign * ref[k - 2] > 0.0f) {
        deg[k] = 1 - ref[k - 1] * ref[k - 1];
      }
    }
  }

  return 0;     // OK
}

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

static Ipp32s sbrCalcChirpFactors(Ipp32s N_Q, Ipp32s *bs_invf_mode_prev,
                                  Ipp32s *bs_invf_mode, Ipp32f *bwArray)
{
  Ipp32s  i;
  Ipp32f  tmpBw, newBw;

  for (i = 0; i < N_Q; i++) {
    newBw = SBR_TABLE_NEW_BW[bs_invf_mode_prev[i]][bs_invf_mode[i]];

    if (newBw < bwArray[i])
      tmpBw = 0.75f * newBw + 0.25f * bwArray[i];
    else
      tmpBw = 0.90625f * newBw + 0.09375f * bwArray[i];

    if (tmpBw < 0.015625f)
      bwArray[i] = 0.f;
    else
      bwArray[i] = tmpBw;

    bs_invf_mode_prev[i] = bs_invf_mode[i];
  }

  return 0;
}

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

static Ipp32s sbrHFGenerator(
                      /*
                       * in data
                       */
                              Ipp32f **XBuf,
                              Ipp32f *vbwArray,
                              Ipp32f *alpha_0,
                              Ipp32f *alpha_1,
                              sSBRDecComState* pSbr, Ipp32s ch,
                              Ipp32f *deg, Ipp32f *degPatched,
                      /*
                       * out data
                       */
                              Ipp32f **YBuf, Ipp32s mode)
{
  Ipp32s  i, x, q, k_0, k, p, g, l;

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

  Ipp32f  accYRe, accYIm;
  Ipp32f  bwArr, bwArr2;
  Ipp32f  cA0Re, cA0Im, cA1Re, cA1Im;

  Ipp32fc** pXcmp = (Ipp32fc**)XBuf;
  Ipp32fc** pYcmp = (Ipp32fc**)YBuf;

  Ipp32f** pXre = XBuf;
  Ipp32f** pYre = YBuf;

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

  //------------------------

  Ipp32fc* pA0cmp = (Ipp32fc*)alpha_0 ;
  Ipp32fc* pA1cmp = (Ipp32fc*)alpha_1 ;

  Ipp32f* pA0re = alpha_0 ;
  Ipp32f* pA1re = alpha_1 ;

  /* CODE */
  if (mode == HEAAC_LP_MODE) {
    ippsZero_32f(degPatched, MAX_NUM_ENV_VAL);
    ippsCopy_32f(deg, 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;
      }

      if (mode == HEAAC_LP_MODE) {
        if (x == 0)
          degPatched[k] = 0.0f;
        else
          degPatched[k] = deg[p];
      }

      bwArr    = vbwArray[g];
      /******************************************
       * code may be optimized because:
       * if ( 0 == bwArr )
       *   pY[ l ][ k ] = pX[ l ][ p ] ONLY!!!
       * else
       *  ippsPredictCoef_SBR_C_32f_D2L(...)
       *  and code is written below,
       *  but it is impossible because
       *  ipp function works only k = [0, k0)
       *
       ******************************************/
      bwArr2   = bwArr * bwArr;

      if (mode == HEAAC_HQ_MODE) {
        cA0Re = bwArr * pA0cmp[p].re ;
        cA0Im = bwArr * pA0cmp[p].im ;

        cA1Re = bwArr2 * pA1cmp[p].re;
        cA1Im = bwArr2 * pA1cmp[p].im;

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

            /*  bw * Alpha0 * XLow[l-1] */
            accYRe = pXcmp[l - 1 + 0][p].re * cA0Re  -
                     pXcmp[l - 1 + 0][p].im * cA0Im ;

            accYIm = pXcmp[l - 1 + 0][p].re * cA0Im  +
                     pXcmp[l - 1 + 0][p].im * cA0Re;

            /*  bw^2 * Alpha1 * XLow[l-2] */
            accYRe += pXcmp[l - 2 + 0][p].re * cA1Re -
                      pXcmp[l - 2 + 0][p].im * cA1Im;

            accYIm += pXcmp[l - 2 + 0][p].re * cA1Im +
                      pXcmp[l - 2 + 0][p].im * cA1Re;

            pYcmp[l + 0][k].re = pXcmp[l - 0 + 0][p].re + accYRe;
            pYcmp[l + 0][k].im = pXcmp[l - 0 + 0][p].im + accYIm;
        }// end for
      } else {// if (mode == HEAAC_HQ_MODE)

        //------------

        cA0Re = bwArr * pA0re[p];

        cA1Re = bwArr2 * pA1re[p];

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

            /*  bw * Alpha0 * XLow[l-1] */
            accYRe = pXre[l - 1 + 0][p] * cA0Re;

            /*  bw^2 * Alpha1 * XLow[l-2] */
            accYRe += pXre[l - 2 + 0][p] * cA1Re;

            pYre[l + 0][k] = pXre[l - 0 + 0][p] + accYRe;
        }
        //------------

      }

    }
  }

  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 < MAX_NUM_ENV_VAL; k++)
      degPatched[k] = 0;
  }

  return 0;     // OK
}

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

Ipp32s sbrGenerationHF(Ipp32f **XBuf, Ipp32f **YBuf,
                       sSBRDecComState* comState, Ipp32f* bwArray, Ipp32f* degPatched,
                       Ipp32s ch, Ipp32s decode_mode)
{
  Ipp32f  alpha_0[128];
  Ipp32f  alpha_1[128];

  Ipp32f  ref_coef[64];
  Ipp32f  alias_degree[64];

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

  if (decode_mode == HEAAC_LP_MODE) {
    ownPredictCoef_SBR_R_32f_D2L(XBuf, alpha_0, alpha_1,
                                 ref_coef, comState->k0, NUM_TIME_SLOTS * RATE + 6);

   sbrCalcAliasDegree(ref_coef, alias_degree, comState->k0);
  } else {
    ippsPredictCoef_SBR_C_32fc_D2L( (const Ipp32fc**)XBuf, (Ipp32fc*)alpha_0,
                                    (Ipp32fc*)alpha_1,
                                    comState->k0, NUM_TIME_SLOTS * RATE + 6);
  }

  sbrHFGenerator(XBuf+SBR_TIME_HFADJ,
                 bwArray,
                 alpha_0, alpha_1,
                 comState, ch,
                 alias_degree,
                 degPatched,
                 YBuf+SBR_TIME_HFADJ,
                 decode_mode);

  return 0;     // OK
}

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

IppStatus ownPredictCoef_SBR_R_32f_D2L(Ipp32f **pSrc, Ipp32f *pAlpha0,
                                       Ipp32f *pAlpha1, Ipp32f *pReflectCoef,
                                       Ipp32s k0, Ipp32s len) {
  const Ipp32s TIME_HF_ADJ = 2;
  Ipp32s  i, j, k, n;
  const Ipp32f rel = 1.f / (1.f + 1e-6f);
  Ipp32f  fi[3][3];
  Ipp32f  d;
  Ipp32f** ppX = pSrc + TIME_HF_ADJ;

  for (k = 0; k < k0; k++) {
    fi[0][0] = fi[0][1] = fi[0][2] = fi[1][0] = fi[1][1] = fi[1][2] = fi[2][0] =
      fi[2][1] = fi[2][2] = 0.f;
/*
 * auto correlation
 */
    for (n = 0; n < len; n++) {
      i = 0;
      j = 1;
      fi[0][1] += ppX[n - i][k] * ppX[n - j][k];

      i = 0;
      j = 2;
      fi[0][2] += ppX[n - i][k] * ppX[n - j][k];

      i = 1;
      j = 1;
      fi[1][1] += ppX[n - i][k] * ppX[n - j][k];

      i = 1;
      j = 2;
      fi[1][2] += ppX[n - i][k] * ppX[n - j][k];

      i = 2;
      j = 2;
      fi[2][2] += ppX[n - i][k] * ppX[n - j][k];
    }

    d = fi[1][1] * fi[2][2] - rel * fi[1][2] * fi[1][2];
/*
 * pAlpha1
 */
    if ((Ipp64f)d * d > 0.f) {  /* if (d != 0) */
      pAlpha1[k] = (fi[0][1] * fi[1][2] - fi[0][2] * fi[1][1]) * (1.f / d);
    } else {
      pAlpha1[k] = 0.f;
    }
/*
 * pAlpha0
 */
    if (fi[1][1] > 0.f) {       /* if (fi[1][1] != 0) */
      pAlpha0[k] = -(fi[0][1] + pAlpha1[k] * fi[1][2]) * (1.f / fi[1][1]);
    } else {
      pAlpha0[k] = 0.f;
    }

    if (((pAlpha1[k] * pAlpha1[k]) >= 16.f) ||
        ((pAlpha0[k] * pAlpha0[k]) >= 16.f)) {
      pAlpha1[k] = pAlpha0[k] = 0.f;
    }

    if (fi[1][1] == 0.0f) {
      pReflectCoef[k] = 0.0f;
    } else {
      pReflectCoef[k] = IPP_MIN(IPP_MAX(-fi[0][1] / fi[1][1], -1), 1);
    }
  }

  return ippStsNoErr;
}

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

⌨️ 快捷键说明

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