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

📄 sbr_dec_hf_adjust_int.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 3 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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 "sbr_settings.h"
#include "sbr_struct.h"
#include "sbr_dec_tabs_int.h"
#include "sbr_dec_api_int.h"
#include "sbr_dec_own_int.h"

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

/* (1.584893192)^2 * Q28 */
static const Ipp32s THRESHOLD_GAIN_BOOST = 0x2830AFD3;

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

static const Ipp32s POW_MINUS_UNIT[] =
  { 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1,
  1, -1, 1, -1, 1, -1, 1, -1, 1, -1,
  1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1,
  1, -1, 1, -1, 1, -1, 1, -1, 1, -1
};

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

static const Ipp32s SIN_FI_RE[4] = { 1, 0, -1, 0 };

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

static const Ipp32s SIN_FI_IM[4] = { 0, 1, 0, -1 };

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

/* Q30 */
static const Ipp32s TABLE_LIMIT_GAIN_INT_Q30[4] =
  { 0x20138CA7, 0x40000000, 0x7FB27DCE, THRESHOLD_GAIN };

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

/* Q31 */
static const Ipp32s ihSmoothFilter[] = {
  0x04130598, 0x0EBDB043, 0x1BECFA68, 0x2697A512, 0x2AAAAAAB
};

/****************************************************
 *
 * SBR_TABLE_INVERT[i] = 2^0 / (i + 1), Q31
 * see <sbrdec_math_int.c> && <sbrdec_own_int.h>
 *
 ****************************************************/

static Ipp32s sbrCalcGainGroups(Ipp32s* s_mapped, Ipp32s* degPatched, Ipp32s* f_group, Ipp32s kx, Ipp32s M )
{
  Ipp32s  grouping = 0, i = 0, n_group = 0, k = 0;

  for (k = kx; k < kx + M - 1; k++) {
    if (degPatched[k + 1] && (s_mapped[k - kx] == 0)) {
      if (grouping == 0) {
        f_group[i] = k;
        grouping = 1;
        i++;
      }
    } else {
      if (grouping == 1) {
        if (s_mapped[k - kx] == 0)
          f_group[i] = k + 1;
        else
          f_group[i] = k;

        grouping = 0;
        i++;
      }
    }
  }

  if (grouping == 1) {
    f_group[i] = M + kx;
    i++;
  }

  n_group = (i >> 1);

  return n_group;
}

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

Ipp32s sbriScale_64s32s(Ipp64s InData, Ipp32s *scaleFactor)
{
  Ipp32s  OutData;
#if 1
  Ipp32s  nGB;
  Ipp32s  shift = 0;

  if (InData >> 32) {
    nGB = sbri_CLZ((Ipp32s)(InData >> 32)) - 1; //remove "sign" bit
    shift = 32 - nGB;
    OutData = (Ipp32s)(InData >> shift);

  } else if (InData > (Ipp64s)IPP_MAX_32S ) {//(InData >> 31) {
    shift = 1;
    OutData = (Ipp32s)(InData >> shift);
  } else {
    OutData = (Ipp32s)InData;
  }

  *scaleFactor = -shift;
#endif

  return OutData;
}

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

static Ipp32s sbrPreProcAliasReduction(Ipp32s* pSrc, Ipp32s* pDst, Ipp32s len, Ipp32s minGB)
{
  Ipp32s absMax;
  Ipp32s nGB;
  Ipp32s offset;
  Ipp32s n;

 //---------------------------------------------------------
  ippsMaxAbs_32s(pSrc, len, &absMax);

  if (absMax == 0) {

    ippsCopy_32s(pSrc, pDst, len);
    return 0;   // OK
  }

/* step 2: calculate num Guard bit */
  nGB = sbri_CLZ(absMax);
  nGB -= 1;       // remove "sign"

/* step 3: check  nGuardBit >= 3 (!!!) */
  offset = 0;
  if (nGB < minGB)
    offset = minGB - nGB;

/* step 4: scale */
  //if (offset) {
    for (n = 0; n < 64; n++) {
      pDst[n] = pSrc[n] >> offset;
    }

    return offset;
  //}
  //------------------------------------------------------------------
}

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

static void sbrAliasReduction_32s(Ipp32s *degPatched,
                                  Ipp32s *inBufE, Ipp32s sfBufE,
                                  Ipp32s *inBufG, Ipp32s sfBufG,
                                  Ipp32s *inBufG2, Ipp32s sfBufG2,
                                  Ipp32s *s_mapped, Ipp32s kx, Ipp32s M)
{
  Ipp64s  denum_64s, energ_total_new_64s, energ_total_64s;

  const Ipp32s oneQ29 = 0x20000000;

  Ipp32s  new_gain, energ_total_new, alpha;
  Ipp32s  i, n_group, k, m, iStart, iEnd;
  Ipp32s  f_group[64];
  Ipp32s  bufE[64];
  Ipp32s  bufG[64];
  Ipp32s  bufG2[64];

  Ipp32s  sfTmp, sfE, sfG, sfG2, sfNewGain;

  Ipp32s  sfETN;

  /* E */
  sfTmp = sbrPreProcAliasReduction(inBufE, bufE, 64, 3);
  sfE   = sfBufE - sfTmp;

  /* G */
  sfTmp = sbrPreProcAliasReduction(inBufG, bufG, 64, 3);
  sfG   = sfBufG - sfTmp;

  /* G2 */
  sfTmp = sbrPreProcAliasReduction(inBufG2, bufG2, 64, 3);
  sfG2  = sfBufG2 - sfTmp;

  n_group = sbrCalcGainGroups( s_mapped, degPatched, f_group, kx, M );

  for (k = 0; k < n_group; k++) {

    iStart = f_group[2 * k] - kx;
    iEnd = f_group[2 * k + 1] - kx;

    denum_64s       = 0;
    energ_total_64s = 0;

    for (i = iStart; i < iEnd; i++) {
      energ_total_64s += MUL64_SBR_64S(bufG2[i], bufE[i]);
      denum_64s += (Ipp64s)bufE[i];
    }

    new_gain = 0;
    sfNewGain = 0;
    if( denum_64s )
    {
      Ipp32s num_32s, denum_32s;
      Ipp32s outSf;
      Ipp32s sfNum, sfDenum;

      //------------------------
      num_32s   = sbriScale_64s32s(energ_total_64s, &sfNum);
      denum_32s = sbriScale_64s32s(denum_64s, &sfDenum);

      denum_32s = sbriInvWrap_32s_Sf(denum_32s, &outSf);

      new_gain = MUL32_SBR_32S(num_32s, denum_32s);

      sfNewGain = 60 - (sfE + sfDenum + outSf) + (sfG2+sfE + sfNum) - 32;

      new_gain = sbriChangeScaleFactor(new_gain, sfNewGain, sfG2);
      sfNewGain = sfG2;
      //------------------------
    }

    for (m = iStart + kx; m < iEnd + kx; m++) {
      if (m < M + kx - 1) {
        alpha = IPP_MAX(degPatched[m], degPatched[m + 1]);
      } else {
        alpha = degPatched[m];
      }
      //bufG2[m - kx] = alpha * new_gain + (1.0f - alpha) * bufG2[m - kx];
      bufG2[m - kx] = (MUL32_SBR_32S( alpha, new_gain ) << 3) +
                      (MUL32_SBR_32S((oneQ29 - alpha), bufG2[m - kx])<<3);
    }

    energ_total_new_64s = 0L;
    for (i = iStart; i < iEnd; i++)
      energ_total_new_64s += MUL64_SBR_64S(bufG2[i], bufE[i]);


    sfETN = 0;
    energ_total_new = 0;
    if( energ_total_new_64s ) {

      Ipp32s energ_total_new_32s, energ_total_32s;
      Ipp32s outSf;
      Ipp32s sfTmpNew, sfTmpOld;

      energ_total_new_32s = sbriScale_64s32s(energ_total_new_64s, &sfTmpNew);
      energ_total_32s = sbriScale_64s32s(energ_total_64s, &sfTmpOld);

      energ_total_new_32s = sbriInvWrap_32s_Sf(energ_total_new_32s, &outSf);

      energ_total_new = MUL32_SBR_32S(energ_total_32s, energ_total_new_32s);

      sfETN = 60 - (sfG2+sfE + sfTmpNew + outSf) + (sfG2+sfE + sfTmpOld) - 32;
    }

    /* Ipp32f-point oeration */
    for (i = iStart; i < iEnd; i++) {
#if 0
      Ipp32f etn_32f = energ_total_new * pow(2, -sfETN );
      Ipp32f buf_g2_i_32f = bufG2[i] * pow(2, -sfG2 );
      Ipp32f bug_g_32f = (Ipp32f)(sqrt(etn_32f * buf_g2_i_32f));

      bufG[i] = (Ipp32s)(bug_g_32f * pow(2,sfG) );
#else
      Ipp32s inSf, outSf;// = sfETN + sfG2;
      Ipp64s varG_64s = MUL64_SBR_64S(energ_total_new, bufG2[i]);
      Ipp32s varG_32s = sbriScale_64s32s(varG_64s, &outSf);

      inSf = sfETN + sfG2 + outSf;

      varG_32s = sbriSqrtWrap_64s_Sfs(varG_32s, inSf, &outSf);
      //bufG[i] = sbrChangeScaleFactor(varG_32s, outSf, sfG);
      inBufG[i] = sbriChangeScaleFactor(varG_32s, outSf, sfBufG);
#endif

    }
  }

#if 0
  /* convert */
  for(i=0; i<64; i++){
    inBufG[i] = sbrChangeScaleFactor(bufG[i], sfG, sfBufG);
  }
#endif

  return;
}

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

static Ipp32s sbrSinAdd_LP_32s(Ipp32s* YRe, Ipp32s indxSine, Ipp32s tE0, Ipp32s m, Ipp32s kx, Ipp32s i,
                               Ipp32s* bufSM, Ipp32s M, Ipp32s* numSin)


{
  Ipp32s  fIndexSineMinus1 = 0;
  Ipp32s  fIndexSinePlus1 = 0;
  Ipp32s  num_sinusoids = *numSin;
  Ipp32s  ksi_middle = 0;
  Ipp32s  xScale = 0xFDE9E1B1;//(Ipp32s)(-0.00815f * pow(2, 32));
  Ipp64s  sumY_64s = 0L;

  fIndexSineMinus1 = (indxSine + (i - 1) - RATE * tE0) & 3;
  fIndexSinePlus1  = (indxSine + (i + 1) - RATE * tE0) & 3;

  if (m == 0) {
    //YRe[m + kx - 1] = -0.00815f * POW_MINUS_UNIT[kx - 1] * bufSM[0] * SIN_FI_RE[fIndexSinePlus1];
    YRe[m + kx - 1] = MUL32_SBR_32S(xScale, bufSM[0]) * POW_MINUS_UNIT[kx - 1] * SIN_FI_RE[fIndexSinePlus1];

    if (m < M - 1) {
      //YRe[m + kx] += -0.00815f * POW_MINUS_UNIT[kx] * bufSM[1] * SIN_FI_RE[fIndexSinePlus1];
      sumY_64s = YRe[m + kx] + MUL32_SBR_32S(xScale, bufSM[1]) * POW_MINUS_UNIT[kx] * SIN_FI_RE[fIndexSinePlus1];

      if (sumY_64s >= (Ipp64s)IPP_MAX_32S )
        YRe[m + kx] = IPP_MAX_32S;
      else if( sumY_64s <= (Ipp64s)IPP_MIN_32S )
        YRe[m + kx] = IPP_MIN_32S;
      else
        YRe[m + kx] = (Ipp32s)(sumY_64s);

    }
  } else if ((0 < m) && (m < M - 1) && (num_sinusoids < 16)) {
    ksi_middle = (bufSM[m - 1] * SIN_FI_RE[fIndexSineMinus1] + bufSM[m + 1] * SIN_FI_RE[fIndexSinePlus1]);
    //ksi_middle *= -0.00815f * POW_MINUS_UNIT[m + kx];
    ksi_middle = MUL32_SBR_32S(xScale, ksi_middle) * POW_MINUS_UNIT[m + kx];
    sumY_64s = YRe[m + kx] + ksi_middle;

    if (sumY_64s >= (Ipp64s)IPP_MAX_32S )
        YRe[m + kx] = IPP_MAX_32S;
      else if( sumY_64s <= (Ipp64s)IPP_MIN_32S )
        YRe[m + kx] = IPP_MIN_32S;
      else
        YRe[m + kx] = (Ipp32s)(sumY_64s);

    //YRe[m + kx] += ksi_middle;

    } else if ((m == M - 1) && (num_sinusoids < 16)) {
      if (m > 0) {

⌨️ 快捷键说明

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