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

📄 sbr_enc_frame_gen.c

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

#include <ipps.h>
#include <ippac.h>
#include <math.h>
#include "aac_status.h"
#include "sbr_settings.h"
#include "sbr_struct.h"
#include "sbr_freq_tabs.h"
#include "sbr_enc_settings.h"
#include "sbr_enc_api_fp.h"
#include "sbr_enc_own_fp.h"

#ifdef SBR_NEED_LOG
#include "sbr_enc_dbg.h"
#endif

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

#define MAX_SLOTS        12

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

static const sSBRFrameInfoState
sbrFrameInfo_FIXFIX_Env1 = {
  1,
  {0, 16},
  {1},
  0,
  1,
  {0, 16},
  /* empy data */
  1,
  {0},
  1
};

static const sSBRFrameInfoState
sbrFrameInfo_FIXFIX_Env2 = {
  2,
  {0, 8, 16},
  {1, 1},
  0,
  2,
  {0, 8, 16},
  /* empy data */
  1,
  {0},
  1
};

static const sSBRFrameInfoState
sbrFrameInfo_FIXFIX_Env4 = {
  4,
  {0, 4, 8, 12, 16},
  {1, 1, 1, 1},
  0,
  2,
  {0, 8, 16},
  /* empy data */
  1,
  {0},
  1
};

static const sSBRFrameInfoState*
sbr_FIXFIX_FrameInfoTabs[] = {
  &sbrFrameInfo_FIXFIX_Env1,

  &sbrFrameInfo_FIXFIX_Env2,

  &sbrFrameInfo_FIXFIX_Env4
};

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

static Ipp32s sbrencCalcFrameClass(Ipp32s frameClassOld, Ipp32s tranFlag)
{
  Ipp32s frameClass = FIXFIX;

  switch (frameClassOld) {
  case FIXFIX:
    if (tranFlag)
      frameClass = FIXVAR;// stationary to transient transition
    else
      frameClass = FIXFIX;// when no transients are present, FIXFIX frames are used

    break;

  case FIXVAR:
    if (tranFlag)
      frameClass = VARVAR;// "tight" transients are handeled by VARVAR frames
    else
      frameClass = VARFIX;// "sparse" transients are handeled by [FIXVAR, VARFIX] pairs

    break;

  case VARFIX:
    if (tranFlag)
      frameClass = FIXVAR;
    else
      frameClass = FIXFIX;// transient to stationary transition

    break;

  case VARVAR:
    if (tranFlag)
      frameClass = VARVAR;// "tight" transients are handeled by VARVAR frames
    else
      frameClass = VARFIX;

    break;
  }

  return frameClass;

}

/********************************************************************/
/*              utility functions are used by frame generator       */
/********************************************************************/

static void sbrencAddRE2Buf(Ipp32s* pBuf, Ipp32s* lenBuf, Ipp32s val)
{
  pBuf[*lenBuf] = val;
  (*lenBuf)++;

  return;
}

/********************************************************************/
/*               AddLE2Buf = Add Left Element To Buffer             */
/********************************************************************/

static void sbrencAddLE2Buf(Ipp32s* pBuf, Ipp32s* lenBuf, Ipp32s val)
{
  Ipp32s i;

  for (i = *lenBuf; i > 0; i--) {
    pBuf[i] = pBuf[i - 1];
  }

  pBuf[0] = val;

  (*lenBuf)++;

  return;
}

/********************************************************************/
/*               AddLB2Buf = Add Left Buffer To Buffer              */
/********************************************************************/

static void sbrencAddLB2Buf(Ipp32s *pSrc, Ipp32s lenSrc, Ipp32s *pDst, Ipp32s* lenDst)
{
  Ipp32s i;

  for (i = lenSrc - 1; i >= 0; i--) {

    sbrencAddLE2Buf(pDst, lenDst, pSrc[i]);
  }

  return;
}

/********************************************************************/
/* subdivides dist by calc segments quant to the lengths   */
static void
sbrencCalcSegments(Ipp32s dist0, Ipp32s maxSegment, Ipp32s* nSegments, Ipp32s* segment)
{
  Ipp32s dist, curSegment = 1;

  *nSegments = 1;
  dist = dist0;

  while (dist > MAX_SLOTS) {

    (*nSegments)++;

    curSegment = dist0 / (*nSegments);

    curSegment = (Ipp32s) floor ( curSegment * 0.5f);
    curSegment = IPP_MIN( maxSegment, 2 * curSegment );

    dist = dist0 - ((*nSegments) - 1) * curSegment;
  }

  *segment = curSegment;

  return;
}

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

static void
sbrencLoadTransientBord(Ipp32s* borders, Ipp32s* lenBord,
                        Ipp32s* freq_res, Ipp32s* lenFreqRes,
                        Ipp32s* minBord, Ipp32s* maxBord, Ipp32s tranPos)
{
  /* reset vectors */
  *lenBord = 0;
  *lenFreqRes = 0;

  /* fill vecBorders: 3 elements [ tranPos + 4, tranPos + 6, tranPos + 10 ] */
  sbrencAddRE2Buf(borders, lenBord, tranPos + 4 );
  sbrencAddRE2Buf(borders, lenBord, tranPos + 6 );
  sbrencAddRE2Buf(borders, lenBord, tranPos + 10);

  /* fill vecFreqRes: 3 elements [ LOW=0, LOW=0, HI=1 ] */
  sbrencAddRE2Buf(freq_res, lenFreqRes, LO );
  sbrencAddRE2Buf(freq_res, lenFreqRes, LO );
  sbrencAddRE2Buf(freq_res, lenFreqRes, HI );

  /* patch */
  *minBord = borders[ 0 ];
  *maxBord = borders[ *lenBord - 1 ];

  return;
}

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

static void sbrencLoadBordPreProc(Ipp32s* borders, Ipp32s* lenBord,
                                  Ipp32s* freqRes, Ipp32s* lenFreqRes,
                                  Ipp32s minBord, Ipp32s rest)
{
  Ipp32s segment, nSegments;
  Ipp32s bord = minBord;
  Ipp32s j;

  /* fillHelper( GP.aBorders[0], 8 ) */
  sbrencCalcSegments( rest, 8, &nSegments, &segment);

  /*
   * GP.aBorders = cat(fliplr(aBordersFill), GP.aBorders);
   * GP.aFreqRes = cat(ones(length(aBordersFill)), GP.aFreqRes);
   */
  for (j = 0; j <= nSegments - 2; j++) {

    bord = bord - segment;

    sbrencAddLE2Buf(borders, lenBord, bord);

    sbrencAddLE2Buf(freqRes, lenFreqRes, HI);
  }

  return;
}

/********************************************************************/
static void sbrencLoadBordPostProc(Ipp32s tranPos,
                                   Ipp32s* borders, Ipp32s* lenBord,
                                   Ipp32s* freqRes, Ipp32s* lenFreqRes,
                                   Ipp32s* nSegments)
{
  Ipp32s segment = 0;
  Ipp32s bord = 0;
  Ipp32s j = 0;
  Ipp32s maxStep = 0;

  //****
  if (tranPos < 4){
      maxStep = 6;
  } else if (tranPos == 4 || tranPos == 5) {
      maxStep = 4;
  } else {
      maxStep = 8;
  }

  bord = borders[ *lenBord - 1 ];
  bord = 32 - bord;

  /* mandatory patch */
  if ( bord <= 0 ) {

    *nSegments = 1;
    *lenBord = *lenBord - 1;
    *lenFreqRes = *lenFreqRes - 1;

    return;
  }

  /* else if( bord > 0 ) */
  sbrencCalcSegments(bord, maxStep, nSegments, &segment);

  bord = borders[ *lenBord - 1 ];

  for (j = 0; j <= *nSegments - 2; j++) {

    bord += segment;

    sbrencAddRE2Buf(borders, lenBord, bord);

    sbrencAddRE2Buf(freqRes, lenFreqRes, HI);
  }
}

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

static void sbrencSplitGrid(Ipp32s* borders, Ipp32s* lenBord,
                            Ipp32s* freqRes, Ipp32s* lenFreqRes,
                            Ipp32s tran, /* tran = tranPos + 4 */
                            Ipp32s* bordersNext, Ipp32s* lenBordNext,
                            Ipp32s* freqResNext, Ipp32s* lenFreqResNext,
                            Ipp32s* pIndxTran, Ipp32s* pIndxSplt,
                            Ipp32s* pIndxTranNext, Ipp32s* pIdxFillNext,
                            Ipp32s nSegments)
{
  Ipp32s iSplit = 0;
  Ipp32s iTran  = EMPTY_MAPPING;
  Ipp32s i, j;
  Ipp32s iTranNext;

  *lenBordNext = 0;
  *lenFreqResNext = 0;

  while( (borders[iSplit] < MAX_SLOTS + 4) && (iSplit < *lenBord) ) iSplit++;

  for (i = 0; i < *lenBord; i++) {
    if (borders[i] >= tran) {
      iTran = i;
      break;
    }
  }

  for (j = 0, i = iSplit; i < *lenBord; i++, j++) {

    bordersNext[j] = borders[i] - 16;

    freqResNext[j] = freqRes[i];

    (*lenBordNext)++;
    (*lenFreqResNext)++;
  }

  /* mandatory patch */
  iTranNext = EMPTY_MAPPING;
  if (iTran != EMPTY_MAPPING) {
    iTranNext = iTran - iSplit;
  }

  /* I can't stand it */
  *pIdxFillNext = *lenBord - (nSegments - 1) - iSplit;

  //---------------------
  // return result
  *pIndxTran = iTran;
  *pIndxSplt = iSplit;

  *pIndxTranNext = iTranNext;
  //--------------------

  return;
}

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

static void
sbrencConflictResolution (Ipp32s *borders, Ipp32s *lenBord,
                          Ipp32s minBord,
                          Ipp32s *freqRes, Ipp32s *lenFreqRes,

                          Ipp32s *bordersNext, Ipp32s *lenBordNext,
                          Ipp32s *freqResNext, Ipp32s *lenFreqResNext,

                          Ipp32s iFillNext,
                          Ipp32s dmin, Ipp32s dmax,

                          Ipp32s *nLeftBord)
{
  Ipp32s nBordNext, maxBordNext, i;
  Ipp32s middleBord;

  /* be careful: transfer */
#if 1
  if (iFillNext >= 1) {

    *lenBordNext   = iFillNext;
    *lenFreqResNext = iFillNext;
  }
#endif

  nBordNext = *lenBordNext;

  maxBordNext = bordersNext[nBordNext - 1];

  middleBord = minBord - maxBordNext;

  while (middleBord < 0) {

    nBordNext--;
    maxBordNext = bordersNext[nBordNext - 1];
    middleBord = minBord - maxBordNext;
  }

  *lenBordNext = nBordNext;
  *lenFreqResNext = nBordNext;

  *nLeftBord = nBordNext - 1;

  //----------------------------
  if (middleBord <= dmax) {

    if (middleBord >= dmin) {

       sbrencAddLB2Buf(bordersNext, *lenBordNext, borders, lenBord);

       sbrencAddLB2Buf(freqResNext, *lenFreqResNext, freqRes, lenFreqRes);

    } else { /* middleBord > dmin */

      if (*lenBordNext > 1) {

        sbrencAddLB2Buf(bordersNext, *lenBordNext-1, borders, lenBord);

        sbrencAddLB2Buf(freqResNext, *lenFreqResNext - 1, freqRes, lenFreqRes);

        *nLeftBord--;
      } else {

        /* lenBord ==== lenFreqRes */
        for (i = 0; i < *lenBord - 1; i++) {
          borders[i] = borders[i + 1];
          freqRes[i] = freqRes[i + 1];
        }

        (*lenBord)--;
        (*lenFreqRes)--;

        sbrencAddLB2Buf(bordersNext, *lenBordNext, borders, lenBord);

        sbrencAddLB2Buf(freqResNext, *lenFreqResNext, freqRes, lenFreqRes);

      } /*  */
    } /*  */
  } else { /* (middleBord > dmax) */

    sbrencLoadBordPreProc(borders, lenBord, freqRes, lenFreqRes, minBord, middleBord);

    sbrencAddLB2Buf(bordersNext, *lenBordNext, borders, lenBord);

    sbrencAddLB2Buf(freqResNext, *lenFreqResNext, freqRes, lenFreqRes);
  }

  return;
}

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

static void
sbrencCalcSBRGrid(sSBRGrid* pGridState,
                  Ipp32s frameClass,

                  Ipp32s *borders, Ipp32s lenBord,
                  Ipp32s *freqRes, Ipp32s lenFreqRes,
                  Ipp32s iSplit, Ipp32s iTran, Ipp32s nLeftBord)
{
  Ipp32s i, n, absBordLead, absBordTrail, nRightBord, env;
  Ipp32s absBord    = 0;
  Ipp32s bs_pointer = 0;
  Ipp32s rel_bord   = 0;

  Ipp32s *bs_freq_res    = pGridState->bs_freq_res;
  Ipp32s *bs_freq_res_LR = pGridState->bs_freq_res_LR;

  Ipp32s *bs_rel_bord    = pGridState->bs_rel_bord;
  Ipp32s *bs_rel_bord_0  = pGridState->bs_rel_bord_0;
  Ipp32s *bs_rel_bord_1  = pGridState->bs_rel_bord_1;

  /* set all length to ZERO */
  Ipp32s len_bs_rel_bord   = 0;
  Ipp32s len_bs_rel_bord_1 = 0;
  Ipp32s len_bs_rel_bord_0 = 0;

  switch (frameClass) {
//-----------------------
  case FIXVAR:

    absBord = borders[iSplit];
    i = iSplit;

    while (i >= 1) {
      rel_bord = borders[i] - borders[i - 1];
      sbrencAddRE2Buf(bs_rel_bord, &len_bs_rel_bord, rel_bord);
      i--;

⌨️ 快捷键说明

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