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

📄 sbr_enc_encoder_fp.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 "aaccmn_const.h"
#include "aac_status.h"
#include "sbr_freq_tabs.h"
#include "sbr_huff_tabs.h"
#include "sbr_enc_settings.h"
#include "sbr_enc_api_fp.h"
#include "sbr_enc_own_fp.h"
#include "vm_strings.h"

/* AYALog */
#ifdef SBR_NEED_LOG
#include "sbr_enc_dbg.h"
#endif

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

#ifndef UNDEF_SBR_FREQ_IDX
#define UNDEF_SBR_FREQ_IDX -999
#endif

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

AACStatus sbrencCheckParams(Ipp32s sampleRate,
                            Ipp32s numCh,
                            Ipp32s bitRate,
                            Ipp32s* indx)
{
  AACStatus status = AAC_OK;

  /* check of frequency (half from inFreqSample) */
  if( (2*sampleRate < MIN_SBR_ENC_FREQ) || (2*sampleRate > MAX_SBR_ENC_FREQ) ){
    return AAC_UNSUPPORTED;
  }

  /* check of channel */
  if( numCh > SBR_MAX_CH ){
    return AAC_UNSUPPORTED;
  }

  //-------------------
  switch( numCh ) {
  case 1:
    status = sbrencGetTuningTab(sampleRate, ID_SCE, bitRate, indx);
    break;

  case 2:
    status = sbrencGetTuningTab(sampleRate, ID_CPE, bitRate, indx);
    break;

  /* may be inserted more detailed analysis, but in my opinion it will be sybaritism */
  default:
    bitRate = bitRate / numCh ;
    status = sbrencGetTuningTab(sampleRate, ID_SCE, bitRate, indx);
    if ( AAC_OK != status ) return status;

/* support asymmetric cutoff freq is turned OFF  */
#if 0
    bitRate *= 2;
    status = sbrencGetTuningTab(sampleRate, ID_CPE, bitRate, indx+1);
    if ( AAC_OK != status ) return status;
#else
    indx[1] = indx[0];
#endif

      break;
  }
  //-------------------

  return status;
}

/********************************************************************
 *
 * this table from coreAAC ( "aac_dec_api.c" )
 * if tables has been changed then SBR will work incorrect
 *
 *  static Ipp32s sampling_frequency_table[] = {
 *    96000, 88200, 64000, 48000, 44100, 32000, 24000,
 *    22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0
 *  };
 *
 ********************************************************************/

static Ipp32s sampling_frequency_table[] = {
  96000, 88200, 64000, 48000, 44100, 32000, 24000,
  22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0
};

static Ipp32s sbrencGetSbrFreqIndx(Ipp32s sampleRate)
{
  Ipp32s indx = UNDEF_SBR_FREQ_IDX;
  Ipp32s i;

  for(i=0; i<16; i++){
    if( sampling_frequency_table[i] ==  sampleRate  ){
      indx = i;
      break;
    }
  }

  return indx;
}

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

static Ipp32f sbrencGetSplitThr(Ipp32s sampleFreq)
{
  const Ipp32s frameSize = 2048;
  Ipp32f frameDur = 0.0f;
  Ipp32f frameDur001 = 0.0f;
  Ipp32f splitThr = 0.0f;
  Ipp32f ratioBitRates = 1.0f; // ratioBitRates = totalBitRate / codecBitRate

  frameDur = (Ipp32f)frameSize / (Ipp32f)sampleFreq;

  frameDur001 = frameDur - 0.01f;

  frameDur001 = ( frameDur001 < 0.01f ) ? 0.01f : frameDur001;

  splitThr = ratioBitRates * 7.5e-5f * 1.f / ( frameDur001 * frameDur001 );

  return splitThr;
}

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

AACStatus sbrencReset(sSBREncState* pState, Ipp32s* indxTuningTab)
{
  sSBRFeqTabsState* pFreqTabsState = (pState->sbrFreqTabsState);
  sSBREnc_SCE_State* pSCE_Element = (pState->pSCE_Element);
  sSBRHeader* pHeader = (pState->sbrHeader);
  Ipp32s* indx_CE_Tab = (pState->indx_CE_Tab);

  Ipp32s indx = 0;//indxTuningTab; /* here indx MUST be correct */
  Ipp32s k0 = 0, k2 = 0, kx = 0, M = 0;
  Ipp32s error = 0;
  Ipp32s sampleRate = 0;
  Ipp32s nf_max_level = 1;

  Ipp32s bs_xover_band = 0; /* may be corrected by usr */
  Ipp32s i = 0;
  Ipp32s ch = 0;

  Ipp32s tabPatchMap[2][ 64 ];

  /* offset for any CE is 0: default */
  pState->indx_FreqOffset_Tab[ID_SCE] = 0;
  pState->indx_FreqOffset_Tab[ID_CPE] = 0;

  //------------------------------------------------------------------------------
  //while ( EMPTY_MAPPING != indx_CE_Tab[numCh++] )

  //------------------------------------------------------------------------------
  indx = indxTuningTab[0]; // nonchalant
  /* MAIN: get correct sbr_freq_indx */
  sampleRate = SBR_TUNING_TABS[indx].sampleRate << 1; // because sample rate is core aac sample rate

  pState->sbrFreqIndx = sbrencGetSbrFreqIndx( sampleRate );

  /* calculate split threshold */
  pState->splitThr = sbrencGetSplitThr( sampleRate );

  if (UNDEF_SBR_FREQ_IDX == pState->sbrFreqIndx ){
    return HEAAC_UNSUPPORTED;
  }

  //------------------------------------------------------------------------------
  i = 0;
  while( EMPTY_MAPPING != indxTuningTab[i] ){
    /* HEADER: up-date init params of freq tabs */
    sSBRFeqTabsState* pCurFreqTabsState = pFreqTabsState + i;
    sSBRHeader* pCurHeader = pHeader + i;
    Ipp32s indx = indxTuningTab[i];

    pCurHeader->bs_start_freq  = SBR_TUNING_TABS[indx].bs_start_freq;
    pCurHeader->bs_stop_freq   = SBR_TUNING_TABS[indx].bs_stop_freq;

    /* bs_header_extra_1 ? */
    pCurHeader->bs_extra_1 = 0;

    pCurHeader->bs_noise_bands = SBR_TUNING_TABS[indx].bs_noise_bands;
    pCurHeader->bs_freq_scale  = SBR_TUNING_TABS[indx].bs_freq_scale;
    pCurHeader->bs_alter_scale = BS_ALTER_SCALE_DEFAULT;
    /* CHECK: DEFAULT/ UNDEFAULT ? */
    if (pCurHeader->bs_noise_bands != BS_NOISE_BANDS_DEFAULT ||
        pCurHeader->bs_freq_scale  != BS_FREQ_SCALE_DEFAULT  ||
        pCurHeader->bs_alter_scale != BS_ALTER_SCALE_DEFAULT) {

        pCurHeader->bs_extra_1 = 1;
    }

    /* calculation number of header send */
    pCurHeader->nSendSBRHeader = (Ipp32s)(SBR_HEADER_SEND_TIME * 0.001f * sampleRate / 2048.0f);
    pCurHeader->nSendSBRHeader = IPP_MAX(pCurHeader->nSendSBRHeader, 1);

    pCurHeader->cntSentSBRHeader = 0;
    pCurHeader->flag_SBRHeaderActive = 0;

    /* header extra params */
    /* bs_header_extra_2 ? */
    pCurHeader->bs_extra_2 = 0;

    pCurHeader->bs_limiter_bands = BS_LIMITER_BANDS_DEFAULT;
    pCurHeader->bs_limiter_gains = BS_LIMITER_GAINS_DEFAULT;
    pCurHeader->bs_interpol_freq = BS_INTERPOL_FREQ_DEFAULT;
    pCurHeader->bs_smoothing_mode= BS_SMOOTHING_MODE_DEFAULT;

    if (pCurHeader->bs_limiter_bands  != BS_LIMITER_BANDS_DEFAULT ||
        pCurHeader->bs_limiter_gains  != BS_LIMITER_GAINS_DEFAULT ||
        pCurHeader->bs_interpol_freq  != BS_INTERPOL_FREQ_DEFAULT ||
        pCurHeader->bs_smoothing_mode != BS_SMOOTHING_MODE_DEFAULT) {

        pCurHeader->bs_extra_2 = 1;
    }

    /* header reset: internal default */
    pCurHeader->bs_amp_res = 1; //3dB

  //}

    //------------------------------------------------------------------------------
    /* FREQ TABS: up-date freq tabs */
    error = sbrCalcMasterFreqBoundary(pCurHeader->bs_start_freq,
                                      pCurHeader->bs_stop_freq,
                                      pState->sbrFreqIndx,
                                      &k0,
                                      &k2);

    if ( error ){
      return HEAAC_UNSUPPORTED;
    }

    error = sbrCalcMasterFreqBandTab(k0,
                                     k2,
                                     pCurHeader->bs_freq_scale,
                                     pCurHeader->bs_alter_scale,
                                     pCurFreqTabsState->fMasterBandTab,
                                     &(pCurFreqTabsState->nMasterBand));

    if ( error ){
      return HEAAC_UNSUPPORTED;
    }

    error = sbrCalcHiFreqTab(pCurFreqTabsState->fMasterBandTab,
                             pCurFreqTabsState->nMasterBand, bs_xover_band,
                             pCurFreqTabsState->fHiBandTab,
                             &(pCurFreqTabsState->nHiBand));
    if ( error ){
      return HEAAC_UNSUPPORTED;
    }

    kx = pCurFreqTabsState->fHiBandTab[ 0 ];
    M = pCurFreqTabsState->fHiBandTab[ pCurFreqTabsState->nHiBand ] - pCurFreqTabsState->fHiBandTab[ 0 ];

    sbrCalcLoFreqTab(pCurFreqTabsState->fHiBandTab,
                     pCurFreqTabsState->nHiBand,
                     pCurFreqTabsState->fLoBandTab,
                     &(pCurFreqTabsState->nLoBand));

    error = sbrCalcNoiseTab(pCurFreqTabsState->fLoBandTab,
                            pCurFreqTabsState->nLoBand,
                            pCurHeader->bs_noise_bands,
                            k2,
                            kx,
                            pCurFreqTabsState->fNoiseBandTab,
                            &(pCurFreqTabsState->nNoiseBand));
    if ( error ){
      return HEAAC_UNSUPPORTED;
    }

    error = sbrCalcPatchConstruct_indxTab(pCurFreqTabsState->fMasterBandTab,
                                          pCurFreqTabsState->nMasterBand,
                                          k0,
                                          M,
                                          pState->sbrFreqIndx,
                                          tabPatchMap[i]);
    if ( error ){
      return HEAAC_UNSUPPORTED;
    }

    /* correct offset for freq tab */
    pState->indx_FreqOffset_Tab[i] = i;

    //increment
    i++;
  }
  //------------------------------------------------------------------------------
  ch = 0;

  /* SCE init */
  while(EMPTY_MAPPING != indx_CE_Tab[ch]){
    Ipp32s indx = pState->indx_FreqOffset_Tab[ indx_CE_Tab[ch] ];
    sSBRFeqTabsState* pCurFreqTabsState = pFreqTabsState + indx;
    sSBREnc_SCE_State* pCurSCE_Element = pSCE_Element + ch;

    pCurSCE_Element->bs_amp_res = 1; //3dB

    /* patch */
    ippsCopy_32s(tabPatchMap[indx], pCurSCE_Element->tabPatchMap, 64);

    /* invf estimation init */
    for(i = 0; i < pCurFreqTabsState->nNoiseBand; i++){

      pCurSCE_Element->sbrInvfEst.prev_bs_invf_mode[i]   = INVF_OFF_LEVEL;
      pCurSCE_Element->sbrInvfEst.prevRegionOrig[i] = 0;
      pCurSCE_Element->sbrInvfEst.prevRegionSBR[i]  = 0;
    }

    /* noisef estimation state */
    nf_max_level = SBR_TUNING_TABS[indx].nf_max_level;
    pCurSCE_Element->sbrNoiseEst.nf_max_level = (Ipp32f)pow(2, nf_max_level/3.0f);

    pCurSCE_Element->sbrEDState.flagEnvUpDate   = 0;
    pCurSCE_Element->sbrEDState.flagNoiseUpDate = 0;

    /* addition initialization */
    pCurSCE_Element->sbrTransientState.flagTransferTran = 0;

    ch++;

    /* patch */
    if ( ID_LFE == indx_CE_Tab[ch]) {
      return AAC_OK;
    }
  }
  return AAC_OK;
}

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

static Ipp32s
sbrencUpDateAmpRes(Ipp32s nEnv, Ipp32s frameClass)
{
  Ipp32s ampRes = 1; // 3.0dB

  if( (FIXFIX == frameClass) && (1 == nEnv) ){
    ampRes = 0;// 1.5dB
  }

  return ampRes;
}

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

AACStatus sbrencGetFrame(sSBREncState* pState, ownFilterSpec_SBR_C_32fc* pSpec)
{
  AACStatus status = AAC_OK;

  /* common part */
  Ipp32s offset = pState->sbr_offset;
  Ipp32s indx = pState->indx_FreqOffset_Tab[ pState->indx_CE_Tab[offset] ];
  Ipp32s ch;

  sSBRFeqTabsState* pFreqTabsState = (pState->sbrFreqTabsState + indx);
  sSBRHeader* pHeader = (pState->sbrHeader + indx);

  sSBREnc_SCE_State* pRoot_SCE_Element = ( pState->pSCE_Element + offset);

⌨️ 快捷键说明

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