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

📄 aac_enc_psychoacoustic_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) 2003-2007 Intel Corporation. All Rights Reserved.
//
//     Intel Integrated Performance Primitives AAC Encode Sample for Windows*
//
//  By downloading and installing this sample, you hereby agree that the
//  accompanying Materials are being provided to you under the terms and
//  conditions of the End User License Agreement for the Intel Integrated
//  Performance Primitives product previously accepted by you. Please refer
//  to the file ippEULA.rtf or ippEULA.txt located in the root directory of your Intel IPP
//  product installation for more information.
//
//  MPEG-4 and AAC are international standards promoted by ISO, IEC, ITU, ETSI
//  and other organizations. Implementations of these standards, or the standard
//  enabled platforms may require licenses from various entities, including
//  Intel Corporation.
//
*/

#include <stdlib.h>
#include <math.h>
#include "ipps.h"
#include "ippac.h"
#include "aac_enc_psychoacoustic_fp.h"
#include "aac_sfb_tables.h"
#include "align.h"

#define MIN(a,b)      (((a) < (b)) ? (a) : (b))
#define MAX_TRH_SHORT 100000

/****************************************************************************/
                                    /*x*/      /*y*/
static const float hiPassCoeff[] = {0.43409411784051444f, 0.13181176431897129f};
//static const float hiPassCoeff[] = {-0.4142f, 0.7071f};
//static const float hiPassCoeff[] = {-0.6128f, 0.8064f};

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

void BlockSwitching(sPsychoacousticBlock* pBlock,
                    sPsychoacousticBlockCom* pBlockCom,
                    Ipp32s ch)
{
  Ipp32f tmpDst[1024];
  Ipp32f winEnergy[8];
  Ipp32f max;
  Ipp32s w, attack;

  pBlock->attackIndex = pBlock->lastAttackIndex;

  for (w = 0; w < 3; w++) {
    ippsIIR_32f(pBlockCom->input_data[ch][1] + 128 * w + 576,
                tmpDst, 128, pBlock->IIRfilterState);
    ippsDotProd_32f(tmpDst, tmpDst, 128, &winEnergy[w]);
  }

  ippsIIR_32f(pBlockCom->input_data[ch][1] + 128 * 3 + 576,
              tmpDst, 64, pBlock->IIRfilterState);

  ippsIIR_32f(pBlockCom->input_data[ch][2],
              tmpDst+64, 64, pBlock->IIRfilterState);

  ippsDotProd_32f(tmpDst, tmpDst, 128, &winEnergy[3]);

  for (w = 4; w < 8; w++) {
    ippsIIR_32f(pBlockCom->input_data[ch][2] + 128 * (w - 4) + 64,
                tmpDst, 128, pBlock->IIRfilterState);
    ippsDotProd_32f(tmpDst, tmpDst, 128, &winEnergy[w]);
  }

  attack = 0;
  max = 0;
  pBlock->lastAttackIndex = -1;

  for (w = 0; w < 8; w++) {
    if (winEnergy[w] > pBlock->avWinEnergy * pBlockCom->attackThreshold) {
      attack = 1;
      pBlock->lastAttackIndex = w;
    }
    pBlock->avWinEnergy = (0.7f * pBlock->avWinEnergy) + (0.3f * winEnergy[w]);
    if (max < winEnergy[w]) max = winEnergy[w];
  }

  if (max < 1000000) {
    attack = 0;
  }

  if (attack) {
    pBlock->next_desired_block_type = EIGHT_SHORT_SEQUENCE;
  } else{
    pBlock->next_desired_block_type = ONLY_LONG_SEQUENCE;
  }
}

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

Ipp32f sprdngf(Ipp32f b1,
               Ipp32f b2)
{
  Ipp32f tmpx,tmpy,tmpz;

  tmpx = (b2 >= b1) ? 3*(b2-b1) : 1.5f*(b2-b1);

  tmpz = 8 * MIN((tmpx-0.5f)*(tmpx-0.5f) - 2*(tmpx-0.5f), 0);

  tmpy = 15.811389f + 7.5f*(tmpx + 0.474f)-
         17.5f*(Ipp32f)sqrt(1 + (tmpx+0.474f)*(tmpx+0.474f));

  return (tmpy < -100 ? 0 : (Ipp32f)pow(10,(Ipp32f)(tmpz + tmpy)/10));
}

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

void psy_long_window(sPsychoacousticBlock* pBlock,
                     sPsychoacousticBlockCom* pBlockCom,
                     Ipp32s ch)
{
__ALIGN Ipp32f  rsqr_long[1024];
  Ipp32f        e_b[MAX_PPT_LONG];
  Ipp32f        ecb[MAX_PPT_LONG];
  Ipp32f        *r;
  Ipp32f        *nb,*nb_l;
  Ipp32f        *noiseThr;
  Ipp32s        b, num_ptt, sb;

  r = (Ipp32f*)pBlock->r[0];

  ippsZero_32f(r + pBlockCom->non_zero_line_long, 1024 - pBlockCom->non_zero_line_long);

  ippsSqr_32f((Ipp32f*)r, rsqr_long, 1024);

  num_ptt = pBlockCom->longWindow->num_ptt;

  for (b = 0; b < num_ptt; b++) {
    Ipp32s w_high = pBlockCom->longWindow->w_high[b];
    Ipp32s w_low = pBlockCom->longWindow->w_low[b];
    Ipp32f *tmp_rsqr = &rsqr_long[w_low];
    Ipp32s len = w_high - w_low + 1;

    ippsSum_32f(tmp_rsqr, len, &e_b[b], ippAlgHintNone);
  }

  for (b = 0; b < num_ptt; b++) {
    Ipp32f *tmp_ptr = (Ipp32f*)pBlockCom->sprdngf_long + b * num_ptt;

    ippsDotProd_32f(e_b, tmp_ptr, num_ptt, &ecb[b]);
  }

  nb   = pBlock->nb_long[pBlockCom->nb_curr_index];
  nb_l = pBlock->nb_long[pBlockCom->nb_prev_index];

  ippsMulC_32f_I(ATTENUATION, ecb, num_ptt);
  ippsMul_32f((Ipp32f*)pBlockCom->rnorm_long, ecb, (Ipp32f*)nb, num_ptt);

  if (pBlock->block_type != LONG_STOP_SEQUENCE) {
    ippsMulC_32f(nb_l, 0.01f, ecb, num_ptt);
    ippsMaxEvery_32f_I(nb, ecb, num_ptt);
    ippsMulC_32f_I(2, nb_l, num_ptt);
    ippsMinEvery_32f_I(ecb, nb_l, num_ptt);
  } else {
    ippsCopy_32f(nb, nb_l, num_ptt);
  }

  ippsMaxEvery_32f_I(pBlockCom->longWindow->qsthr, nb, num_ptt);
  ippsMaxEvery_32f_I(pBlockCom->longWindow->qsthr, nb_l, num_ptt >> 1);

  noiseThr = &pBlockCom->noiseThr[ch][0];

  for (sb = 0; sb < pBlockCom->num_sfb_long; sb++) {
    Ipp32s start = pBlockCom->aacenc_p2sb_l[sb].bu;
    Ipp32s end = pBlockCom->aacenc_p2sb_l[sb].bo;

    noiseThr[sb] = pBlockCom->aacenc_p2sb_l[sb].w1 * nb_l[start] +
                    pBlockCom->aacenc_p2sb_l[sb].w2 * nb_l[end];

    for (b = start + 1; b < end; b++) {
      noiseThr[sb] += nb_l[b];
    }
    if ((noiseThr[sb] > 1.0e9f) && (sb < 11)) {
      noiseThr[sb] = 1.0e9f;
    }
  }
}

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

void psy_short_window(sPsychoacousticBlock* pBlock,
                      sPsychoacousticBlockCom* pBlockCom,
                      Ipp32s ch,
                      Ipp32s lastBlockType)
{
__ALIGN Ipp32f  rsqr_short[128];
  Ipp32f        *r;
  Ipp32s        win_counter;
  Ipp32f        e_b[MAX_PPT_SHORT];
  Ipp32f        ecb[MAX_PPT_SHORT];
  Ipp32f        *nb, *nb_s;
  Ipp32f        *noiseThr;
  Ipp32s        b, num_ptt, sb;

  for (win_counter = 0; win_counter < 8; win_counter++) {

    r = &pBlock->r[0][win_counter*128];

    ippsZero_32f(r + pBlockCom->non_zero_line_short, 128 - pBlockCom->non_zero_line_short);

    ippsSqr_32f(r, rsqr_short, 128);

    num_ptt = pBlockCom->shortWindow->num_ptt;

    for (b = 0; b < num_ptt; b++) {
      Ipp32s w_high = pBlockCom->shortWindow->w_high[b];
      Ipp32s w_low = pBlockCom->shortWindow->w_low[b];
      Ipp32f *tmp_rsqr = &rsqr_short[w_low];
      Ipp32s len = w_high - w_low + 1;

      ippsSum_32f(tmp_rsqr, len, &e_b[b], ippAlgHintNone);
    }

    for (b = 0; b < num_ptt; b++) {
      Ipp32f *tmp_ptr = (Ipp32f*)pBlockCom->sprdngf_short + b * num_ptt;

      ippsDotProd_32f(e_b, tmp_ptr, num_ptt, &ecb[b]);
    }

    nb = pBlock->nb_short[0][win_counter];
    if (win_counter == 0) {
      nb_s = pBlock->nb_short[0][7];
    } else {
      nb_s = pBlock->nb_short[0][win_counter - 1];
    }

    ippsMulC_32f_I(ATTENUATION, ecb, num_ptt);
    ippsMul_32f(pBlockCom->rnorm_short, ecb, nb, num_ptt);

    if ((lastBlockType != LONG_START_SEQUENCE) || (win_counter != 0)) {
      ippsMulC_32f(nb_s, 0.01f, ecb, num_ptt);
      ippsMaxEvery_32f_I(nb, ecb, num_ptt);
      ippsMulC_32f_I(2, nb_s, num_ptt);

⌨️ 快捷键说明

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