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

📄 aac_enc_api_int.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) 2004-2007 Intel Corporation. All Rights Reserved.
//
//
//
//
*/

#include <stdlib.h>
#include <stdio.h>
#include "aac_enc_own_int.h"
#include "aac_enc_own.h"
#include "aac_enc_int.h"
#include "aac_sfb_tables.h"
#include "aac_enc_huff_tables.h"
#include "aaccmn_const.h"
#include "aac_enc_psychoacoustic_int.h"
#include "aac_enc_filterbank_int.h"
#include "aac_enc_quantization_int.h"
#include "aac_enc_ltp_int.h"
#include "ipps.h"

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

void aaciencUpdateMemMap(AACEnc *state,
                         Ipp32s shift)
{
  Ipp32s i;
  Ipp32s chNum = state->com.m_channel_number;

  for (i = 0; i < 12; i++) {
    AAC_UPDATE_PTR(IppsVLCEncodeSpec_32s, state->com.huffman_tables[i], shift)
  }

  AAC_UPDATE_PTR(sOneChannelInfo, state->com.chInfo, shift)
  AAC_UPDATE_PTR(sCrcSaveTable, state->com.crcSaveTable, shift)

  AAC_UPDATE_PTR(Ipp16s*, state->com.buff, shift)
  for (i = 0; i < chNum; i++) {
    AAC_UPDATE_PTR(Ipp16s, state->com.buff[i], shift)
  }

  AAC_UPDATE_PTR(Ipp16s*, state->m_buff_pointers, shift)
  for (i = 0; i < 3*chNum; i++) {
    AAC_UPDATE_PTR(Ipp16s, state->m_buff_pointers[i], shift)
  }

  AAC_UPDATE_PTR(Ipp16s*, state->ltp_buff, shift)
  AAC_UPDATE_PTR(Ipp32s*, state->ltp_overlap, shift)

  AAC_UPDATE_PTR(sPsychoacousticBlock, state->psychoacoustic_block, shift)
  AAC_UPDATE_PTR(IppsFFTSpec_R_16s, state->psychoacoustic_block_com.pFFTSpecShort, shift)
  AAC_UPDATE_PTR(IppsFFTSpec_R_16s, state->psychoacoustic_block_com.pFFTSpecLong, shift)
  AAC_UPDATE_PTR(Ipp8u, state->psychoacoustic_block_com.pBuffer, shift)

  AAC_UPDATE_PTR(IppsMDCTFwdSpec_16s, state->filterbank_enc.p_mdct_fwd_long, shift)
  AAC_UPDATE_PTR(IppsMDCTFwdSpec_16s, state->filterbank_enc.p_mdct_fwd_short, shift)
  AAC_UPDATE_PTR(Ipp8u, state->filterbank_enc.p_buffer_fwd, shift)

  if (state->com.audioObjectType == AOT_AAC_LTP) {
    for (i = 0; i < chNum; i++) {
      AAC_UPDATE_PTR(Ipp16s, state->ltp_buff[i], shift)
    }
    for (i = 0; i < chNum; i++) {
      AAC_UPDATE_PTR(Ipp32s, state->ltp_overlap[i], shift)
    }
    AAC_UPDATE_PTR(IppsFFTSpec_R_32s, state->corrFft, shift)
    AAC_UPDATE_PTR(Ipp8u, state->corrBuff, shift)
  }
}

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

AACStatus aaciencInit(AACEnc *state,
                      Ipp32s sampling_frequency,
                      Ipp32s chNum,
                      Ipp32s bit_rate,
                      enum AudioObjectType audioObjectType,
                      Ipp32s stereo_mode,
                      Ipp32s ns_mode,
                      Ipp32s *size_all)
{
  AACEnc_com *state_com;
  Ipp8u *ptr;
  Ipp32s **ltp_overlap;
  Ipp16s **m_buff_pointers;
  Ipp16s **ltp_buff;
  Ipp16s **buff;
  Ipp32s sf_index;
  Ipp32s ch;
  Ipp32s i, k, w;
  Ipp32s sizeOfAACenc, sizeOfOneChannelInfo, sizeOfsCrcSaveTable;
  Ipp32s sizeOfPsychoacousticBlock, sizeOfPointers;
  Ipp32s size, tmpSize;
  Ipp32s num_sfb_for_long;
  Ipp32s num_sfb_for_short;
  Ipp32s* sfb_offset_for_long;
  Ipp32s* sfb_offset_for_short;
  Ipp32s cutoff_frequency;
  Ipp32s bits_per_frame;
  Ipp32s bits_for_lfe = 0;
  Ipp32s lfe_channel_present;
  Ipp32s max_line, max_sfb;
  Ipp32s bit_rate_per_ch, inScaleFactor;
  Ipp16s short_tmp, short_cutoff_frequency;
  Ipp32s sce_tag;
  Ipp32s cpe_tag;
  Ipp32s lfe_tag;
  Ipp32s num_channel;
  AACStatus aacStatus = AAC_OK;
  IppStatus ippStatus = ippStsNoErr;

  if (chNum < 1) {
    return AAC_BAD_PARAMETER;
  }

  sf_index = 12;
  for (i = 0; i < 12; i ++) {
    if (sfb_tables[i].samp_rate == sampling_frequency) {
      sf_index = i;
      break;
    }
  }

  if (sf_index == 12)
    return AAC_BAD_PARAMETER;

  sizeOfAACenc = (sizeof(AACEnc) + 31) & (~31);
  sizeOfsCrcSaveTable = (sizeof(sCrcSaveTable) + 31) & (~31);
  sizeOfOneChannelInfo = (sizeof(sOneChannelInfo) + 31) & (~31);
  sizeOfPsychoacousticBlock = (sizeof(sPsychoacousticBlock) + 31) & (~31);
  sizeOfPointers = (chNum * (5 * sizeof(Ipp16s*) + sizeof(Ipp32s*)) + 31) & (~31);

  size = sizeOfAACenc + sizeOfPointers + chNum * (sizeOfsCrcSaveTable +
         sizeOfOneChannelInfo + sizeOfPsychoacousticBlock +
         3 * 1024 * sizeof(Ipp16s)) + 32;

  if (audioObjectType == AOT_AAC_LTP) {
    size += chNum * (3072 * sizeof(Ipp16s) + 1024 * sizeof(Ipp32s));
  }

  ptr = (Ipp8u *)state;
  if (state) {
    ippsZero_8u(ptr, size);

    state_com = &(state->com);
    ptr = (Ipp8u *)state + sizeOfAACenc;

    state_com->chInfo = (sOneChannelInfo *)ptr;
    ptr += chNum * sizeOfOneChannelInfo;

    state_com->crcSaveTable = (sCrcSaveTable *)ptr;
    ptr += chNum * sizeOfsCrcSaveTable;

    state_com->m_channel_number = chNum;
    state_com->sampling_frequency_index = sf_index;
    state_com->m_sampling_frequency = sampling_frequency;
    state_com->m_bitrate = bit_rate;

    ltp_overlap = (Ipp32s**)ptr;
    m_buff_pointers = (Ipp16s**)(ltp_overlap + chNum);
    ltp_buff = m_buff_pointers + 3 * chNum;
    buff = ltp_buff + chNum;

    ptr += sizeOfPointers;

    state->psychoacoustic_block = (sPsychoacousticBlock *)ptr;
    ptr += chNum * sizeOfPsychoacousticBlock;

    if (audioObjectType == AOT_AAC_LTP) {
      for (i = 0; i < chNum; i++) {
        ltp_overlap[i] = (Ipp32s*)ptr;
        ptr += 1024 * sizeof(Ipp32s);
      }

      for (i = 0; i < chNum; i++) {
        ltp_buff[i] = (Ipp16s*)ptr;
        ptr += 3072 * sizeof(Ipp16s);
      }
    }

    for (i = 0; i < 3 * chNum; i++) {
      m_buff_pointers[i] = (Ipp16s*)ptr;
      ptr += 1024 * sizeof(Ipp16s);
    }

    state->m_buff_pointers = m_buff_pointers;
    state->ltp_buff = ltp_buff;
    state->ltp_overlap = ltp_overlap;
    state_com->buff = buff;

    state_com->m_buff_prev_index = 0;
    state_com->m_buff_curr_index = 1;
    state_com->m_buff_next_index = 2;

    num_sfb_for_long = sfb_tables[sf_index].num_sfb_long_window;
    num_sfb_for_short = sfb_tables[sf_index].num_sfb_short_window;

    sfb_offset_for_short = sfb_tables[sf_index].sfb_offset_short_window;

    state_com->sfb_offset_for_short_window[0] = 0;
    k = 1;
    for (w = 0; w < 8; w ++) {
      for ( i = 0; i < num_sfb_for_short; i++) {
        state_com->sfb_offset_for_short_window[k] = state_com->sfb_offset_for_short_window[k-1] +
          (sfb_offset_for_short[i + 1] - sfb_offset_for_short[i]);
        k++;
      }
    }

    state_com->sfb_offset[0] = state_com->sfb_offset[1] = state_com->sfb_offset[3] =
      sfb_tables[sf_index].sfb_offset_long_window;
    state_com->sfb_offset[2] = state_com->sfb_offset_for_short_window;

    state_com->huffman_tables[0] = (IppsVLCEncodeSpec_32s*)ptr;
    aacStatus = BuildHuffmanTables((IppsVLCEncodeSpec_32s**)(&state_com->huffman_tables),
                                    &tmpSize);
    if (aacStatus != AAC_OK) return aacStatus;

    size += tmpSize;
    ptr = (Ipp8u*)state_com->huffman_tables[0] + tmpSize;

    if (bit_rate <= 0) {
      return AAC_BAD_PARAMETER;
    }

    lfe_channel_present = 0;
    if ((chNum > 4) && ((chNum & 1) == 0))
      lfe_channel_present = 1;

    /* ********************************************************************* */
    /*                     CONFIG CHANNEL ELEMENT                            */
    /* ********************************************************************* */

    i = 0;

    if (chNum != 2) {
      state_com->chInfo[0].element_id = ID_SCE;
      i += 1;
    }

    for (ch = i ; ch < chNum - lfe_channel_present; ch++) {
      state_com->chInfo[ch].element_id = ID_CPE;
    }

    if (lfe_channel_present) {
      state_com->chInfo[chNum-1].element_id = ID_LFE;
    }

    if (chNum == 4) {
      state_com->chInfo[chNum-1].element_id = ID_SCE;
    }

    bits_per_frame = (bit_rate * 1024)/(sfb_tables[sf_index].samp_rate);
    if (bits_per_frame > 768 * 8 * chNum)
      bits_per_frame = 768 * 8 * chNum;

    bits_per_frame &= ~7;
    bits_per_frame -= 3; /* for ID_END */
    bit_rate_per_ch = bit_rate / chNum;

    state->ms_mul = ((100 - (bit_rate_per_ch >> 10)) * 1638) >> 4; /* 1638 ~ 0.05 * 32768 */
    if (state->ms_mul < 0) state->ms_mul = 0; /* ms_mul in Q11 */

    state->ms_thr = (bit_rate_per_ch >> 14); /* in Q4 */

    sfb_offset_for_long = sfb_tables[sf_index].sfb_offset_long_window;

    inScaleFactor = 0;
    while (bit_rate_per_ch >= 32768) {
      inScaleFactor += 1;
      bit_rate_per_ch >>= 1;
    }

    short_tmp = (Ipp16s)bit_rate_per_ch;
    ippsPow34_16s_Sfs(&short_tmp, inScaleFactor, &short_cutoff_frequency, 0, 1);
    cutoff_frequency = short_cutoff_frequency * 4;

    max_line = (2048 * cutoff_frequency) / sampling_frequency;

    max_sfb = num_sfb_for_long;

    for (i = 0; i < num_sfb_for_long; i++) {
      if (sfb_offset_for_long[i] > max_line) {
        max_sfb = i;
        break;
      }
    }

    state_com->real_max_sfb[0] = state_com->real_max_sfb[1] =
    state_com->real_max_sfb[3] = max_sfb;

    state_com->real_max_line[0] = state_com->real_max_line[1] =
    state_com->real_max_line[3] = sfb_offset_for_long[max_sfb];

    max_line = (256 * cutoff_frequency) / sampling_frequency;
    max_sfb = num_sfb_for_short;

    for (i = 0; i < num_sfb_for_short; i++) {
      if (sfb_offset_for_short[i] > max_line) {
        max_sfb = i;
        break;
      }
    }

    state_com->real_max_sfb[2] = max_sfb;
    state_com->real_max_line[2] = sfb_offset_for_short[max_sfb] * 8;

    /* High AHT boundary - 15000 Hz */

    max_line = (2048 * 15000 / sampling_frequency);

    max_sfb = num_sfb_for_long;

    for (i = 0; i < num_sfb_for_long; i++) {
      if (sfb_offset_for_long[i] > max_line) {
        max_sfb = i;
        break;
      }
    }

    if (max_sfb > state_com->real_max_sfb[0])
      max_sfb = state_com->real_max_sfb[0];

    state_com->ath_max_sfb[0] = state_com->ath_max_sfb[1] =
      state_com->ath_max_sfb[3] = max_sfb;

    max_line = (256 * 15000 / sampling_frequency);
    max_sfb = num_sfb_for_short;

    for (i = 0; i < num_sfb_for_short; i++) {
      if (sfb_offset_for_short[i] > max_line) {
        max_sfb = i;
        break;
      }
    }

    if (max_sfb > state_com->real_max_sfb[2])
      max_sfb = state_com->real_max_sfb[2];

    state_com->ath_max_sfb[2] = max_sfb;

    /* max_sfb for LFE channel calculating */

    if (cutoff_frequency > MAX_LFE_FREQUENCY) {
      cutoff_frequency = MAX_LFE_FREQUENCY;

      max_line = (2048 * cutoff_frequency) / sampling_frequency;
      max_sfb = num_sfb_for_long;

      for (i = 0; i < num_sfb_for_long; i++) {
        if (sfb_offset_for_long[i] > max_line) {
          max_sfb = i;
          break;
        }
      }

      state_com->real_max_sfb_lfe[0] = state_com->real_max_sfb_lfe[1] =
        state_com->real_max_sfb_lfe[3] = max_sfb;

      state_com->real_max_line_lfe[0] = state_com->real_max_line_lfe[1] =
        state_com->real_max_line_lfe[3] = sfb_offset_for_long[max_sfb];

      max_line = (256 * cutoff_frequency) / sampling_frequency;
      max_sfb = num_sfb_for_short;

      for (i = 0; i < num_sfb_for_short; i++) {
        if (sfb_offset_for_short[i] > max_line) {
          max_sfb = i;
          break;
        }
      }

      state_com->real_max_sfb_lfe[2] = max_sfb;
      state_com->real_max_line_lfe[2] = sfb_offset_for_short[max_sfb] * 8;

    } else {

⌨️ 快捷键说明

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