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

📄 aac_dec_tns_fp.c

📁 audio-video-codecs.rar语音编解码器
💻 C
字号:
/*
//
//                  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-2006 Intel Corporation. All Rights Reserved.
//
//     Intel(R) Integrated Performance Primitives AAC Decode 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(R) 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(R) 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 "aac_dec_tns_fp.h"

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

static void tns_ar_filter_plus(Ipp32f *p_spectrum,
                               Ipp32s size,
                               Ipp32f *lpc_coef,
                               Ipp32s order);
static void tns_ar_filter_minus(Ipp32f *p_spectrum,
                                Ipp32s size,
                                Ipp32f *lpc_coef,
                                Ipp32s order);
static void tns_ma_filter(Ipp32f *p_spectrum,
                          Ipp32s size,
                          Ipp32s inc,
                          Ipp32f *lpc_coef,
                          Ipp32s order);

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

void ics_apply_tns_enc_I(s_tns_data *p_data,
                         Ipp32f *p_spectrum)
{
  Ipp32s  w;
  Ipp32s  f;

  for (w = 0; w < p_data->m_num_windows; w++) {
    for (f = 0; f < p_data->m_n_filt[w]; f++) {
      if (0 == p_data->m_order[w][f])
        continue;
      tns_ma_filter(&(p_spectrum[w * 128 + p_data->m_start[w][f]]),
                    p_data->m_size[w][f], p_data->m_inc[w][f],
                    p_data->m_lpc[w][f], p_data->m_order[w][f]);
    }
  }
}

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

void ics_apply_tns_dec_I(s_tns_data *p_data,
                         Ipp32f *p_spectrum)
{
  Ipp32s  w;
  Ipp32s  f;

  for (w = 0; w < p_data->m_num_windows; w++) {
    for (f = 0; f < p_data->m_n_filt[w]; f++) {
      if (0 == p_data->m_order[w][f])
        continue;

      if (p_data->m_inc[w][f] > 0) {
        tns_ar_filter_plus(&(p_spectrum[w * 128 + p_data->m_start[w][f]]),
                           p_data->m_size[w][f], p_data->m_lpc[w][f],
                           p_data->m_order[w][f]);
      } else {
        tns_ar_filter_minus(&(p_spectrum[w * 128 + p_data->m_start[w][f]]),
                            p_data->m_size[w][f], p_data->m_lpc[w][f],
                            p_data->m_order[w][f]);
      }
    }
  }
}

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

static void tns_decode_coef(Ipp32s order,
                            Ipp32s coef_res_bits,
                            Ipp32s coef_compress,
                            Ipp32s *coef,
                            Ipp32f *a);

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

void ics_calc_tns_data(s_SE_Individual_channel_stream *p_stream,
                       s_tns_data *p_data)
{
  Ipp32s  w;
  Ipp32s  f;
  Ipp32s  bottom;
  Ipp32s  top;
  Ipp32s  tns_order;
  Ipp32s  min_sfb;
  Ipp32s  tns_max_bands;
  Ipp32s  tns_max_order;
  Ipp32s  start;
  Ipp32s  end;
  Ipp32s *p_sfb_offset;
  Ipp32s  size;
  Ipp32s  num_swb;

  p_data->m_tns_data_present = p_stream->tns_data_present;

  if (0 == p_stream->tns_data_present)
    return;

  if (EIGHT_SHORT_SEQUENCE == p_stream->window_sequence) {
    tns_max_bands = p_stream->tns_max_bands_short;
    tns_max_order = p_stream->tns_max_order_short;
    p_sfb_offset = p_stream->sfb_offset_short_window;
    num_swb = p_stream->num_swb_short;
  } else {
    tns_max_bands = p_stream->tns_max_bands_long;
    tns_max_order = p_stream->tns_max_order_long;
    p_sfb_offset = p_stream->sfb_offset_long_window;
    num_swb = p_stream->num_swb_long;
  }

  for (w = 0; w < p_stream->num_windows; w++) {
    bottom = num_swb;

    for (f = 0; f < p_stream->n_filt[w]; f++) {
      p_data->m_order[w][f] = 0;
      top = bottom;
      bottom = MAX(top - p_stream->length[w][f], 0);
      tns_order = MIN(p_stream->order[w][f], tns_max_order);

      if (0 == tns_order)
        continue;

      tns_decode_coef(tns_order, p_stream->coef_res[w] + 3,
                      p_stream->coef_compress[w][f], p_stream->coef[w][f],
                      p_data->m_lpc[w][f]);

      min_sfb = MIN(tns_max_bands, p_stream->max_sfb);

      start = p_sfb_offset[MIN(bottom, min_sfb)];
      end = p_sfb_offset[MIN(top, min_sfb)];

      if ((size = end - start) <= 0)
        continue;

      p_data->m_order[w][f] = tns_order;
      p_data->m_size[w][f] = size;;

      if (p_stream->direction[w][f]) {
        p_data->m_inc[w][f] = -1;
        p_data->m_start[w][f] = end - 1;
      } else {
        p_data->m_inc[w][f] = 1;
        p_data->m_start[w][f] = start;
      }

    }
    p_data->m_n_filt[w] = p_stream->n_filt[w];
  }

  p_data->m_num_windows = p_stream->num_windows;
}

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

static const Ipp32f tnsTable[2][16] =
{
  { -0.342020143325f, -0.642787609686f, -0.866025403784f, -0.984807753012f,
    -0.984807753012f, -0.866025403784f, -0.642787609687f, -0.342020143326f,
     0.000000000000f,  0.433883739118f,  0.781831482468f,  0.974927912182f,
     0.974927912182f,  0.781831482468f,  0.433883739117f, -0.000000000000 },

  { -0.995734176295f, -0.961825643173f, -0.895163291355f, -0.798017227280f,
    -0.673695643647f, -0.526432162877f, -0.361241666187f, -0.183749517817f,
     0.000000000000f,  0.207911690818f,  0.406736643076f,  0.587785252293f,
     0.743144825477f,  0.866025403784f,  0.951056516295f,  0.994521895368f }
};

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

static void tns_decode_coef(Ipp32s order,
                            Ipp32s coef_res_bits,
                            Ipp32s coef_compress,
                            Ipp32s *coef,
                            Ipp32f *a)
{
  Ipp32s  i, m;
  Ipp32s  coef_res2;
  Ipp32f  tmp2[TNS_MAX_ORDER + 1];

  /* Inverse quantization */

  coef_res2 = coef_res_bits - coef_compress;
  for (i = 0; i < order; i++) {
    Ipp32s ind = ((coef[i] << (32 - coef_res2)) >> (32 - coef_res2)) + 8;
    tmp2[i] = tnsTable[coef_res_bits - 3][ind];
  }

 /* Conversion to LPC coefficients */
  a[0] = 1;
  for (m = 1; m <= order; m++) {
    Ipp32f tmp = tmp2[m - 1];
    a[m] = tmp;
    for (i = 1; i <= (m >> 1); i++) {
      Ipp32f tmp0 = a[i];
      Ipp32f tmp1 = a[m - i];

      a[i] = tmp0 + tmp * tmp1;
      a[m - i] = tmp1 + tmp * tmp0;
    }
  }
}

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

static void tns_ar_filter_plus(Ipp32f *p_spectrum,
                               Ipp32s size,
                               Ipp32f *lpc_coef,
                               Ipp32s order)
{
  Ipp32s  i, j;
  Ipp32f  y;
  Ipp32f  tmp;
  Ipp32s  size0;

  size0 = order;
  if (size < order) size0 = size;

  for (i = 0; i < size0; i++) {
    y = *p_spectrum;

    for (j = 0; j < i; j++) {
      tmp = lpc_coef[j + 1] * p_spectrum[-j-1];
      y -= tmp;
    }
    *p_spectrum = y;
    p_spectrum++;
  }

  for (i = order; i < size; i++) {
    y = *p_spectrum;

    for (j = 0; j < order; j++) {
      tmp = lpc_coef[j + 1] * p_spectrum[-j-1];
      y -= tmp;
    }
    *p_spectrum = y;
    p_spectrum++;
  }
}

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

static void tns_ar_filter_minus(Ipp32f *p_spectrum,
                                Ipp32s size,
                                Ipp32f *lpc_coef,
                                Ipp32s order)
{
  Ipp32s  i, j;
  Ipp32f  y;
  Ipp32f  tmp;
  Ipp32s  size0;

  size0 = order;
  if (size < order) size0 = size;

  for (i = 0; i < size0; i++) {
    y = *p_spectrum;

    for (j = 0; j < i; j++) {
      tmp = lpc_coef[j + 1] * p_spectrum[j + 1];
      y -= tmp;
    }
    *p_spectrum = y;
    p_spectrum--;
  }

  for (i = order; i < size; i++) {
    y = *p_spectrum;

    for (j = 0; j < order; j++) {
      tmp = lpc_coef[j + 1] * p_spectrum[j + 1];
      y -= tmp;
    }
    *p_spectrum = y;
    p_spectrum--;
  }
}

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

static void tns_ma_filter(Ipp32f *p_spectrum,
                          Ipp32s size,
                          Ipp32s inc,
                          Ipp32f *lpc_coef,
                          Ipp32s order)
{
  Ipp32s  i, j;
  Ipp32f  y;
  Ipp32f  flt_state[TNS_MAX_ORDER+1024];
  Ipp32f  *p_state = flt_state + size;
  Ipp32f  tmp;

  for (i = 0; i < order; i++)
    p_state[i] = 0;

  for (i = 0; i < size; i++) {
    y = *p_spectrum;

    for (j = 0; j < order; j++) {
      tmp = lpc_coef[j + 1] * p_state[j];
      y += tmp;
    }

    p_state--;
    p_state[0] = *p_spectrum;
    *p_spectrum = y;
    p_spectrum += inc;
  }
}

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

⌨️ 快捷键说明

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