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

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

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

#define AC3_FRAME_SIZE 1920 * 2

#define AC3_UPDATE_PTR(type, ptr, inc)    \
  if (ptr) {                              \
  ptr = (type*)((Ipp8u*)(ptr) + inc);     \
}

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

void ac3decUpdateMemMap(AC3Dec *state,
                        Ipp32s shift)
{
  Ipp32s i;

  for (i = 0; i < 2; i++) {
    AC3_UPDATE_PTR(Ipp32f, state->ShortBuff[i], shift)
  }

  for (i = 0; i < 6; i++) {
    AC3_UPDATE_PTR(Ipp32f, state->temp[i], shift)
  }

  //AC3_UPDATE_PTR(IppsMDCTInvSpec_32f, state->allocation_imdct.pMDCTSpecLong, shift)
  //AC3_UPDATE_PTR(IppsMDCTInvSpec_32f, state->allocation_imdct.pMDCTSpecShort, shift)
  //AC3_UPDATE_PTR(Ipp8u, state->state->allocation_imdct.pBufferShort, shift)
}

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

AC3Status ac3decInit(AC3Dec *state,
                     Ipp32s *sizeAll)
{
  Ipp8u  *ptr, *ptrWork, *ptrInit;
  Ipp32s i, size, sizeOfAC3Dec;
  Ipp32s sizeInit = 0;
  Ipp32s sizeWork = 0;
  Ipp32s sizeSpecInvLong = 0;
  Ipp32s sizeSpecInvShort = 0;
  Ipp32s sizeInitTmp = 0;
  Ipp32s sizeWorkTmp = 0;

  sizeOfAC3Dec = (sizeof(AC3Dec) + 15) & (~15);
  size = sizeOfAC3Dec + 256 * sizeof(Ipp32f);

  if (ippsMDCTInvGetSize_32f(512, &sizeSpecInvLong, &sizeInitTmp, &sizeWorkTmp) != ippStsOk) {
    return AC3_ALLOC;
  }

  if (sizeInit < sizeInitTmp) sizeInit = sizeInitTmp;
  if (sizeWork < sizeWorkTmp) sizeWork = sizeWorkTmp;

  if (ippsMDCTInvGetSize_32f(256, &sizeSpecInvLong, &sizeInitTmp, &sizeWorkTmp) != ippStsOk) {
    return AC3_ALLOC;
  }

  if (sizeInit < sizeInitTmp) sizeInit = sizeInitTmp;
  if (sizeWork < sizeWorkTmp) sizeWork = sizeWorkTmp;

  size += sizeSpecInvLong + sizeSpecInvShort + sizeWork + sizeInit;
  *sizeAll = size;

  if (state) {
    ippsZero_8u((Ipp8u*)state, size);
    state->ShortBuff[0] = (Ipp32f*)((Ipp8u*)state + sizeOfAC3Dec);
    state->ShortBuff[1] = state->ShortBuff[0] + 128;
    ptr = (Ipp8u*)state->ShortBuff[1];

    state->allocation_imdct.pMDCTSpecLong = NULL;
    state->allocation_imdct.pMDCTSpecShort = NULL;
    state->allocation_imdct.pBufferLong = NULL;
    state->allocation_imdct.pBufferShort = NULL;

    ptrWork = ptr + sizeSpecInvLong + sizeSpecInvShort;
    ptrInit = ptrWork + sizeWork;

#if 0
    if (ippsMDCTInvInit_32f(&(state->allocation_imdct.pMDCTSpecLong), 512,
                            ptr, ptrInit) != ippStsOk)
      return AC3_ALLOC;

    if (ippsMDCTInvInit_32f(&(state->allocation_imdct.pMDCTSpecShort), 256,
                            ptr + sizeSpecInvLong, ptrInit) != ippStsOk)
      return AC3_ALLOC;
#else
    if (ippsMDCTInvInitAlloc_32f(&(state->allocation_imdct.pMDCTSpecLong), 512) != ippStsOk)
      return AC3_ALLOC;
    if (ippsMDCTInvInitAlloc_32f(&(state->allocation_imdct.pMDCTSpecShort), 256) != ippStsOk)
      return AC3_ALLOC;

    ptrWork = (Ipp8u*)ippsMalloc_8u(size);
    if (ptrWork == NULL)
      return AC3_ALLOC;
#endif

    state->allocation_imdct.pBufferLong =
    state->allocation_imdct.pBufferShort = ptrWork;

    state->out_acmod      = 0;
    state->outlfeon       = 0;
    state->dualmonomode   = 0;
    state->drc_scaleLow   = 1;
    state->drc_scaleHigh  = 1;
    state->out_compmod    = 0;
    state->karaokeCapable = 3;
    state->crc_mute       = 0;
    state->as_input       = 0;
    state->nChannelOut    = 2;
    state->gainScale      = 1;

    for (i = 0; i < 7; i++) {
      state->lfedeltba[i] = 0;
    }

    ac3decReset(state);
  }

  return AC3_OK;
}

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

AC3Status ac3decReset(AC3Dec *state)
{
  Ipp32s i;

  if (!state)
    return AC3_NULL_PTR;

  state->m_frame_number = 0;
  state->syncinfo.frame_size = AC3_FRAME_SIZE;

  for (i = 0; i < 6; i++) {
    ippsZero_32f(state->coeffs[i], 256);
    ippsZero_32f(state->delay[i], 256);
    state->temp[i] = state->coeffs[i];
  }

  state->mants_tabls.dithtemp = 1;

  state->m_frame_number = 0;
  state->nChannelOut = NFCHANS[state->out_acmod] +
                               state->outlfeon;

  for (i = 0; i < 5; i++) {
    state->audblk.chexpstr[i] = 0;
  }
  return AC3_OK;
}

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

AC3Status ac3decClose(AC3Dec *state)
{
  if (state == NULL)
    return AC3_OK;

  if (state->allocation_imdct.pMDCTSpecLong) {
    ippsMDCTInvFree_32f(state->allocation_imdct.pMDCTSpecLong);
    state->allocation_imdct.pMDCTSpecLong = NULL;
  }
  if (state->allocation_imdct.pMDCTSpecShort) {
    ippsMDCTInvFree_32f(state->allocation_imdct.pMDCTSpecShort);
    state->allocation_imdct.pMDCTSpecShort = NULL;
  }

  if (state->allocation_imdct.pBufferLong) {
    ippsFree(state->allocation_imdct.pBufferLong);
    state->allocation_imdct.pBufferLong = NULL;
    state->allocation_imdct.pBufferShort = NULL;
  }

  return AC3_OK;
}

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

AC3Status ac3decGetFrame(Ipp8u *inPointer,
                         Ipp32s inDataSize,
                         Ipp32s *decodedBytes,
                         Ipp16s *outPointer,
                         Ipp32s outBufferSize,
                         AC3Dec *state)
{
  AC3Status result;
  Ipp32s cbErrors = 0;
  Ipp32s unused_bits_sync, unused_bits;
  Ipp32s nChannelOut;
  Ipp32s nblk;
  Ipp32s cbMantErrors = 0, cbExpErrors = 0;
  Ipp32s sizeCrc1, firstBadBlock;
  Ipp32s start_bits;
  Ipp32s crc1, crc2;
  Ipp32s goodFrame;
  sBitsreamBuffer BS;
  sBitsreamBuffer *pBS = &BS;
  Ipp8u *ptrCrc;

  if (!inPointer || !outPointer || !state)
    return AC3_NULL_PTR;

  GET_INIT_BITSTREAM(pBS, inPointer)

  result = GetSynch(pBS, inDataSize);

  GET_BITS_COUNT(pBS, unused_bits_sync)
  start_bits = unused_bits_sync - 16;
  unused_bits_sync = inDataSize * 8 - unused_bits_sync;

  if (result != AC3_OK) {
    *decodedBytes = inDataSize - ((unused_bits_sync + 16 + 7) >> 3);
    if (*decodedBytes < 0) *decodedBytes = 0;
    return AC3_NOT_FIND_SYNCWORD;
  }

  if (unused_bits_sync < 24) {
    *decodedBytes = inDataSize - ((unused_bits_sync + 16 + 7) >> 3);
    if (*decodedBytes < 0) *decodedBytes = 0;
    return AC3_NOT_ENOUGH_DATA;
  }

  ptrCrc = (Ipp8u*)(pBS->pCurrent_dword) - (pBS->nBit_offset >> 3) + 4;
  cbErrors = ParseSyncInfo(state, pBS);

  GET_BITS_COUNT(pBS, unused_bits)
  unused_bits = inDataSize * 8 - unused_bits;

  if (cbErrors != 0) {
    *decodedBytes = inDataSize - ((unused_bits + 7) >> 3);
    if (*decodedBytes < 0) *decodedBytes = 0;
    return AC3_BAD_STREAM;
  }

  if (unused_bits < state->syncinfo.frame_size * 16 - 16 - 24) {
    *decodedBytes = inDataSize - ((unused_bits_sync + 16 + 7) >> 3);
    if (*decodedBytes < 0) *decodedBytes = 0;
    return AC3_NOT_ENOUGH_DATA;
  }

  sizeCrc1 = (state->syncinfo.frame_size >> 1) + (state->syncinfo.frame_size >> 3);
  crc1 = crcCheck(2 * (sizeCrc1 - 1), ptrCrc);

  ptrCrc += 2 * (sizeCrc1 - 1);
  crc2 = crcCheck(2 * (state->syncinfo.frame_size - sizeCrc1), ptrCrc);
  crc2 += crc1;

  if (crc1 == 0) {
    ippsZero_8u((Ipp8u*)&(state->bsi), sizeof(_BSI));
    cbErrors = ParseBsi(state, pBS);

    GET_BITS_COUNT(pBS, unused_bits)
    unused_bits = inDataSize * 8 - unused_bits;

    if (cbErrors != 0) {
      *decodedBytes = inDataSize - ((unused_bits + 7) >> 3);
      if (*decodedBytes < 0) *decodedBytes = 0;
      return AC3_BAD_STREAM;
    }
  }

  nChannelOut = state->nChannelOut;

  if (outBufferSize < nChannelOut*256*6*sizeof(Ipp16s)) {
    *decodedBytes = 0;
    return AC3_NOT_ENOUGH_BUFFER;
  }

  firstBadBlock = 1;
  goodFrame = 1;

  for (nblk = 0; nblk < 6; nblk++) {
    if (((nblk <= 1) && (crc1 != 0)) ||
        ((nblk > 1) && (crc2 != 0))) {
      goodFrame = 0;
    }

    if (goodFrame) {
      if (ParseAudblk(nblk, state, pBS) < 1) {
        goodFrame = 0;
      }
    }

    if (goodFrame) {
      cbExpErrors += DecodeExponents(state);
      BitAllocation(state);
      cbMantErrors += UnpackMantissas(state, pBS);

      if (state->bsi.acmod == 0x2)
        Rematrix(state);

      if (((state->audblk.blksw == 0) ||
           (state->audblk.blksw == ((1 << state->bsi.nfchans) - 1))) &&
          ((state->nChannelOut - state->bsi.lfeon) < state->bsi.nfchans)) {
          Downmix(state->audblk.dynrng, state->audblk.dynrng2,
                  1, state);
          InverseTransform(0, state);
      } else {
        InverseTransform(1, state);
        Downmix(state->audblk.dynrng, state->audblk.dynrng2,
               0, state);

      }
      WindowingOverlap(outPointer, state);
    } else {
      if (state->crc_mute) {
        if (firstBadBlock) {
          Ipp32s i;
          firstBadBlock = 0;

          for (i = 0; i < nChannelOut; i++) {
            ippsZero_32f(state->temp[i], 512);
          }

          WindowingOverlap(outPointer, state);

        }   else {
          ippsZero_8u((Ipp8u*)outPointer, nChannelOut*256*2);
        }
      } else {
        Ipp32s i;
        Ipp32f *pDataTemp[6];

        for (i = 0; i < state->nChannelOut; i++) {
          ippsAddProduct_32f(WindowTable, state->temp[i], state->delay[i], 256);
          pDataTemp[i] = state->delay[i];
        }

        if (state->gainScale != 1) {
          for (i = 0; i < state->nChannelOut; i++) {
            ippsMulC_32f_I(state->gainScale, state->delay[i], 256);
          }
        }

        ippsJoin_32f16s_D2L((const Ipp32f **)pDataTemp, nChannelOut,
                            256, (Ipp16s*)outPointer);

        for (i = 0; i < state->nChannelOut; i++) {
          ippsMul_32f(WindowTable + 256, state->temp[i] + 256,
                      state->delay[i], 256);
        }
      }
    }

    outPointer += nChannelOut*256;
  }

  if (goodFrame)  {
    ParseAuxdata(state, pBS, start_bits);
    GET_BITS_COUNT(pBS, (*decodedBytes))

⌨️ 快捷键说明

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