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

📄 ac3_dec_downmixing.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) 2002-2006 Intel Corporation. All Rights Reserved.
//
*/

#include "ac3_dec.h"
#include "ac3_dec_own_fp.h"

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

#define DB11           7509 * 256

#define COMP_CUSTOM_A  0
#define COMP_CUSTOM_D  1
#define COMP_LINE      2
#define COMP_RF        3

static const Ipp16s NFRONT[8] = { 2, 1, 2, 3, 2, 3, 2, 3 };

static const Ipp16s NREAR[8] = { 0, 0, 0, 0, 1, 1, 2, 2 };

//#define m6dB  0.5000345f    /* -6.0 dB */
//#define m3dB  0.7071312f    /* -3.0 dB */
//#define m45dB 0.594292158f  /* -4.5 dB */

#define m6dB  0.5f          /* -6.0 dB */
#define m3dB  0.707106781f  /* -3.0 dB */
#define m45dB 0.594603557f  /* -4.5 dB */

const Ipp32f cmixlev_lut[4] = {
  m3dB, m45dB, m6dB, m45dB
};

const Ipp32f smixlev_lut[4] = {
  m3dB, m6dB, 0, m6dB
};

static const Ipp32f karaokeTable[4][18] = {
  {1.00000000f,  0.00000000f,  0.00000000f,  0.70710677f,
   0.70710677f,  0.00000000f,  0.00000000f,  0.00000000f,
   0.00000000f,  1.00000000f,  1.00000000f,  1.00000000f,
   0.00000000f,  0.00000000f,  0.00000000f,  1.00000000f,
   0.00000000f,  0.00000000f},

  {1.00000000f,  0.70713121f,  0.00000000f,  0.70710677f,
   0.70710677f,  0.70710677f,  0.70710677f,  0.00000000f,
   0.00000000f,  1.00000000f,  1.00000000f,  1.00000000f,
   0.00000000f,  0.00000000f,  0.00000000f,  1.00000000f,
   1.00000000f,  0.00000000f},

  {1.00000000f,  0.00000000f,  0.70713121f,  0.70710677f,
   0.70710677f,  0.00000000f,  0.00000000f,  0.70710677f,
   0.70710677f,  1.00000000f,  1.00000000f,  1.00000000f,
   0.00000000f,  0.00000000f,  0.00000000f,  1.00000000f,
   0.00000000f,  1.00000000f},

  {1.00000000f,  0.70713121f,  0.70713121f,  0.70710677f,
   0.70710677f,  1.00000000f,  0.00000000f,  0.00000000f,
   1.00000000f,  1.00000000f,  1.00000000f, -1.00000000f,
   0.00000000f,  1.00000000f,  1.00000000f,  1.00000000f,
   0.00000000f,  0.00000000f},
};

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

static Ipp32f drc(Ipp32s compre,
                  Ipp32s compr,
                  Ipp32s dynrng,
                  Ipp32s downmix,
                  Ipp32f dialnorm,
                  AC3Dec *state)
{
  Ipp32s tmp;
  Ipp32f gain;

  if (state->out_compmod == COMP_RF) {
    if (compre) {
      if (compr)        gain = (Ipp32f)compr + DB11;
      else              gain = (Ipp32f)dynrng + DB11;
    } else if (downmix) gain = (Ipp32f)dynrng - DB11;
    else gain = (Ipp32f)dynrng;
  } else if (state->out_compmod == COMP_LINE) {
    if (dynrng > 0)     gain = (Ipp32f)dynrng * state->drc_scaleLow;
    else if (downmix)   gain = (Ipp32f)dynrng;
    else                gain = (Ipp32f)dynrng * state->drc_scaleHigh;
  } else {
    if (dynrng > 0)     gain = (Ipp32f)dynrng * state->drc_scaleLow;
    else                gain = (Ipp32f)dynrng * state->drc_scaleHigh;
    if (downmix)        gain = gain - DB11;
  }

  tmp = (Ipp32s)(gain);
  gain = ((Ipp32f)((tmp & 0xFFFFF) + 1048576)) /
         ((Ipp32f)(1 << (20 - (tmp >> 20))));

  if (state->out_compmod != COMP_CUSTOM_A)
    gain *= dialnorm;

  return gain;
}

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

void  Downmix(Ipp32s dynrng,
              Ipp32s dynrng2,
              Ipp32s before_imdct,
              AC3Dec *state)
{
  Ipp32s downmix, i;
  Ipp32f cmixgain;  /* center channel mix gain */
  Ipp32f smixgain;  /* surround channel mix gain */
  Ipp32f gain = .0f;
  Ipp16s infront, inrear, outfront, outrear;
  Ipp32f *samples[7];
  Ipp32f *samL  = NULL;
  Ipp32f *samC  = NULL;
  Ipp32f *samR  = NULL;
  Ipp32f *samSL = NULL ;
  Ipp32f *samSR = NULL;
  Ipp32f *samS  = NULL;
  Ipp32f *samLFE= NULL;
  Ipp32f *karaokeSL= NULL;

  if (before_imdct) {
    for (i = 0; i < 7; i++) {
      samples[i] = state->coeffs[i];
    }
  } else {
    for (i = 0; i < 7; i++) {
      samples[i] = state->samples[i];
    }
  }

/* init in_channel */
  switch (state->bsi.acmod) {
  case ACMOD_0:
    samL = samples[0];
    samR = samples[1];

    samC = samples[2];
    samSL = samples[3];
    samSR = samples[4];
    samS = samples[6];
    break;

  case ACMOD_10:
    samC = samples[0];

    samL = samples[1];
    samR = samples[2];
    samSL = samples[3];
    samSR = samples[4];
    samS = samples[6];

    break;
  case ACMOD_20:
    samL = samples[0];
    samR = samples[1];

    samC = samples[2];
    samSL = samples[3];
    samSR = samples[4];
    samS = samples[6];

    break;
  case ACMOD_30:
    samL = samples[0];
    samC = samples[1];
    samR = samples[2];

    samSL = samples[3];
    samSR = samples[4];
    samS = samples[6];

    break;
  case ACMOD_21:
    samL = samples[0];
    samR = samples[1];
    samS = samples[2];

    samC = samples[3];
    samSL = samples[4];
    samSR = samples[6];

    break;
  case ACMOD_31:
    samL = samples[0];
    samC = samples[1];
    samR = samples[2];
    samS = samples[3];

    samSL = samples[4];
    samSR = samples[6];

    break;
  case ACMOD_22:
    samL = samples[0];
    samR = samples[1];
    samSL = samples[2];
    samSR = samples[3];

    samC = samples[4];
    samS = samples[6];

    break;
  case ACMOD_32:
    samL = samples[0];
    samC = samples[1];
    samR = samples[2];
    samSL = samples[3];
    samSR = samples[4];

    samS = samples[6];
    break;

  default:
    break;
  }
  samLFE = samples[5];

/*
 * Set up downmix parameters
 */
  infront = NFRONT[state->bsi.acmod];
  inrear = NREAR[state->bsi.acmod];
  outfront = NFRONT[state->out_acmod];
  outrear = NREAR[state->out_acmod];
  cmixgain = cmixlev_lut[state->bsi.cmixlev];
  smixgain = smixlev_lut[state->bsi.surmixlev];
  downmix = 0;

  if (inrear == 1) {
    karaokeSL = samS;
  } else {
    karaokeSL = samSL;
  }

  if (before_imdct) {
    if (state->bsi.acmod == ACMOD_10) {
      ippsZero_32f(samL, 256);
      ippsZero_32f(samR, 256);
    }

    if ((infront == 2) && (outfront != 2)) {
      ippsZero_32f(samC, 256);
    }

    if (inrear == 0) {
      if (outrear == 2) {
        ippsZero_32f(samSL, 256);
        ippsZero_32f(samSR, 256);
      } else if (outrear == 1) {
        ippsZero_32f(samS, 256);
      }
    } else if (inrear == 1) {
      if (outrear == 2) {
        ippsZero_32f(samSL, 256);
        ippsZero_32f(samSR, 256);
      }
    }

    if (state->bsi.acmod == ACMOD_0) {   /* 1+1 mode, dual independent mono channels present */
      gain = drc(state->bsi.compre, state->bsi.compr, dynrng, 0,
                state->bsi.dialnorm, state);
      ippsMulC_32f_I(gain, samL, 256);
      gain = drc(state->bsi.compr2e, state->bsi.compr2, dynrng2, 0,
                state->bsi.dialnorm2, state);
      ippsMulC_32f_I(gain, samR, 256);

      if (outfront == 1) {        /* 1 front loudspeaker (center) */
        if (state->dualmonomode == DUAL_LEFTMONO) {
          ippsCopy_32f(samL, samC, 256);
        } else if (state->dualmonomode == DUAL_RGHTMONO) {
          ippsCopy_32f(samR, samC, 256);
        } else {
          ippsAdd_32f(samL, samR, samC, 256);
          ippsMulC_32f_I(m6dB, samC, 256);        /* 0.501187233 = -6dB */
        }
      } else if (outfront == 2) {
        if (state->dualmonomode == DUAL_LEFTMONO) {
          ippsMulC_32f_I(m3dB, samL, 256);        /* 0.707945 = -3dB */
          ippsCopy_32f(samL, samR, 256);
        } else if (state->dualmonomode == DUAL_RGHTMONO) {
          ippsMulC_32f_I(m3dB, samR, 256);        /* 0.707945 = -3dB */
          ippsCopy_32f(samR, samL, 256);
        } else if (state->dualmonomode == DUAL_MIXMONO) {
          ippsAdd_32f_I(samR, samL, 256);
          ippsMulC_32f_I(m6dB, samL, 256);        /* 0.501187233 = -6dB */
          ippsCopy_32f(samL, samR, 256);
        }
      } else {
        if (state->dualmonomode == DUAL_LEFTMONO) {
          ippsCopy_32f(samL, samC, 256);
          ippsZero_32f(samL, 256);
          ippsZero_32f(samR, 256);
        } else if (state->dualmonomode == DUAL_RGHTMONO) {
          ippsCopy_32f(samR, samC, 256);

⌨️ 快捷键说明

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