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

📄 mp3dec_common.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.
//
*/

#include "mp3dec_own.h"

/*
//  Functions in this file.
//
//  Ipp32s mp3dec_SetAllocTable(MP3Dec *state)
//  Ipp32s mp3dec_GetSynch(sDecoderContext* DC)
//  Ipp32s main_data_slots(sDecoderContext* DC)
//  Ipp32s mp3dec_ReadMainData(sDecoderContext* DC)
*/

#define HDR_VERSION(x)       ((x & 0x80000) >> 19)
#define HDR_LAYER(x)         (4 - ((x & 0x60000) >> 17))
#define HDR_ERRPROTECTION(x) (1 - ((x & 0x10000) >> 16))
#define HDR_BITRADEINDEX(x)  ((x & 0x0f000) >> 12)
#define HDR_SAMPLINGFREQ(x)  ((x & 0x00c00) >> 10)
#define HDR_PADDING(x)       ((x & 0x00200) >> 9)
#define HDR_EXTENSION(x)     ((x & 0x00100) >> 8)
#define HDR_MODE(x)          ((x & 0x000c0) >> 6)
#define HDR_MODEEXT(x)       ((x & 0x00030) >> 4)
#define HDR_COPYRIGHT(x)     ((x & 0x00008) >> 3)
#define HDR_ORIGINAL(x)      ((x & 0x00004) >> 2)
#define HDR_EMPH(x)          ((x & 0x00003))

/* MPEG-1 12-bit code embedded in the audio bitstream that identifies
the start of a frame (p.20 ISO/IEC 11172-3) */
static Ipp32u SYNC_WORD = 0xffe;

#define MP3DEC_END_OF_BUFFER(BS)                            \
  ((((((BS)->pCurrent_dword) - ((BS)->pBuffer)) * 32 +      \
  (BS)->init_nBit_offset - ((BS)->nBit_offset)) <=          \
        (BS)->nDataLen * 8 - 8) ? 0 : 1)

#define MAX_FRAME_LEN 1800

/******************************************************************************
//  Name:
//    mp3dec_main_data_slots
//
//  Description:
//    calculate number of bytes beetween two successive frames minus length of
//    (header & side info)
//  Input Arguments:
//    DC - point to Decoder context
//
//  Returns:
//    number of bytes beetween two successive frames minus length of
//    (header & side info)
//
******************************************************************************/

static Ipp32s mp3dec_main_data_slots(Ipp32s stereo, Ipp32s header_id, Ipp32s header_protectionBit)
{
    Ipp32s  nSlots = 0;

    if (header_id == 1) {
        if (stereo == 1)
            nSlots -= 17;
        else
            nSlots -= 32;
    }

    if (header_id == 0) {
        if (stereo == 1)
            nSlots -= 9;
        else
            nSlots -= 17;
    }

    if (header_protectionBit)
        nSlots -= 2;

    return nSlots;
}

static Ipp32s mp3dec_SynchCheckCRC(MP3Dec_com *state, Ipp32s MP3Header)
{
  IppMP3FrameHeader *header = &(state->header);
  sBitsreamBuffer *BS = &state->m_StreamData;
  Ipp32s crc_nbits;
  Ipp32u crc, crc_check;

  if (header->layer == 3) {
    if (header->id == 1) {
      if (header->mode == 0x3)
        crc_nbits = 136;
      else
        crc_nbits = 256;
    } else {
      if (header->mode == 0x3)
        crc_nbits = 72;
      else
        crc_nbits = 136;
    }
  } else {
    Ipp32s jsbound, stereo;
    jsbound = 32;
    stereo = (header->mode == 0x3) ? 1 : 2;

    if (header->mode  == 0x01) {
      jsbound = (header->modeExt + 1) * 4;
    }

    crc_nbits = (jsbound << (stereo + 1)) + ((32 - jsbound) << 2);
  }

  bs_save(BS);

  GET_BITS(BS, crc_check, 16, Ipp32s);

  bs_CRC_reset(&crc);
  bs_CRC_update_imm(MP3Header, 16, &crc);
  bs_CRC_update_bs(BS, crc_nbits, &crc);
  bs_restore(BS);

  if (crc != crc_check)
    return 1;

  return 0;
}

/*****************************************************************************
//  Name:
//    mp3dec_GetSynch
//
//  Description:
//    check the MP3 frame header and get information if the header is valid
//
//  Input Arguments:
//    DC - point to sDecoderContext structure
//
//  Output Arguments:
//    DC - point to sDecoderContext structure
//
//  Returns:
//     1 - if the header is valid and supported
//    -1 - if synchronization is lost
//    -2 - if it is the end of stream
//    -4 - if the header is not supported
//
******************************************************************************/

MP3Status  mp3dec_GetSynch(MP3Dec_com *state)
{
    Ipp32s MP3Header;
    Ipp32u val, val_t;
    Ipp32s start_db = state->decodedBytes;
    IppMP3FrameHeader *header = &(state->header);
    IppMP3FrameHeader *header_good = &(state->header_good);
    sBitsreamBuffer *BS = &state->m_StreamData;
    Ipp8u *ptrStart = (Ipp8u *)BS->pCurrent_dword + ((32 - BS->nBit_offset) >> 3);
    Ipp32s buflen = BS->nDataLen;
    Ipp32s cont_flag;

    if (buflen <= (BS->pCurrent_dword - BS->pBuffer) * 4 || buflen < 4)
        return MP3_NOT_FIND_SYNCWORD;     // end of file

    GET_BITS(BS, val, 24, Ipp32s);
    state->decodedBytes += 3;

    do {
      cont_flag = 0;
      for(;;) {
        val <<= 8;
        GET_BITS(BS, val_t, 8, Ipp32s);
        val |= val_t;
        state->decodedBytes++;
        if (((val >> 20) & SYNC_WORD) == SYNC_WORD) {
          MP3Header = val;
          header->layer = HDR_LAYER(MP3Header);
          header->samplingFreq = HDR_SAMPLINGFREQ(MP3Header);
          header->bitRate = HDR_BITRADEINDEX(MP3Header);
          header->emphasis = HDR_EMPH(MP3Header);
          header->id = HDR_VERSION(MP3Header);
          state->mpg25 = ((val >> 20) & 1) ? 0 : 2;

          if (state->m_bInit) {
            if ((header->samplingFreq == header_good->samplingFreq) &&
              (header->samplingFreq != 3) &&
              (header->layer == header_good->layer) &&
              (header->id == header_good->id) &&
              (state->mpg25 == state->mpg25_good) &&
              (header->bitRate != 15) &&
              (header->emphasis != 2)) {
                break;
              }
          } else {
            if ((header->samplingFreq != 3) &&
              (header->layer != 4) &&
              (header->bitRate != 15) &&
              (header->emphasis != 2) &&
              (((val >> 19) & 3) != 1)) {
                break;
              }
          }
        }
        if (MP3DEC_END_OF_BUFFER(BS)) {
          state->decodedBytes -= 3;
          return MP3_NOT_FIND_SYNCWORD;
        }
      }

      header->mode = HDR_MODE(MP3Header);
      header->modeExt = HDR_MODEEXT(MP3Header);
      header->copyright = HDR_COPYRIGHT(MP3Header);
      header->originalCopy = HDR_ORIGINAL(MP3Header);
      header->paddingBit = HDR_PADDING(MP3Header);
      header->privateBit = HDR_EXTENSION(MP3Header);
      header->protectionBit = HDR_ERRPROTECTION(MP3Header);

      if (header->bitRate != 0) {
        Ipp32s size = 0;

        if (header->layer == 3) {
          size = 72000 * (header->id + 1);
        } else if (header->layer == 2) {
          size = 72000 * 2;
        } else if (header->layer == 1) {
          size = 12000;
        }

        state->MP3nSlots =
          size * mp3_bitrate[header->id][header->layer - 1][header->bitRate] /
          mp3_frequency[header->id + state->mpg25][header->samplingFreq] + header->paddingBit;

        if (header->layer == 1)
          state->MP3nSlots *= 4;

        state->MP3nSlots -= 4; /* header */
        state->decodedBytes += state->MP3nSlots;

        if (BS->nDataLen < state->decodedBytes - start_db +
          ((!state->m_bInit || state->synchro_mode) ? 3 : 0)) {
          state->decodedBytes -= state->MP3nSlots + 4;
          return MP3_NOT_ENOUGH_DATA;
        }
        if (!state->m_bInit || state->synchro_mode) {
            Ipp32s next_header =
              (ptrStart[state->decodedBytes - start_db + 0] << 16) |
              (ptrStart[state->decodedBytes - start_db + 1] << 8) |
              (ptrStart[state->decodedBytes - start_db + 2]);
           if ((next_header ^ (MP3Header >> 8)) & 0xfffe0c) {
             state->decodedBytes -= state->MP3nSlots;

            if (MP3DEC_END_OF_BUFFER(BS)) {
              state->decodedBytes -= 3;
              return MP3_NOT_FIND_SYNCWORD;
            }
            cont_flag = 1;
            continue;
          }
        }
        if (header->protectionBit && header->layer != 2) {
          if (mp3dec_SynchCheckCRC(state, MP3Header)) {
            state->decodedBytes -= state->MP3nSlots;
            cont_flag = 1;
            continue;
          }
        }
      } else {
        Ipp32u ubuf, usyncbuf, good;
        if (header->protectionBit && header->layer != 2) {
          if (mp3dec_SynchCheckCRC(state, MP3Header)) {
            cont_flag = 1;
            continue;
          }
        }

        bs_save(BS);

        if (state->m_nBitrate != header->bitRate) { /* VBR is forbidden */
          state->decodedBytes -= 3;
          return MP3_BAD_STREAM;
        }

        usyncbuf = 0xffe000 | ((2 - state->mpg25) << 11) | (header->id << 11) | ((4 - header->layer) << 9) |
          (header->samplingFreq << 2);

        state->MP3nSlots = -2;
        ubuf = 0;
        good = 0;

        while (MP3DEC_END_OF_BUFFER(BS) != 1) {
          GET_BITS(BS, val, 8, Ipp32s);
          ubuf = (ubuf << 8) | val;
          if ((ubuf & 0xfffefc) == usyncbuf)
          {
            good = 1;
            break;
          }
          state->MP3nSlots++;
        }

        bs_restore(BS);

        if (good == 0) {
          if (BS->nDataLen > (state->decodedBytes - start_db + MAX_FRAME_LEN)) {
            if (MP3DEC_END_OF_BUFFER(BS)) {
              state->decodedBytes -= 3;
              return MP3_NOT_FIND_SYNCWORD;
            }
            cont_flag = 1;
            continue;
          } else {
            state->decodedBytes -= 4;
            return MP3_NOT_ENOUGH_DATA;
          }
        }

        state->decodedBytes += (state->MP3nSlots);
      }
    } while (cont_flag);

    state->m_nBitrate = header->bitRate;

    state->stereo = (header->mode == 0x3) ? 1 : 2;

    if (header->mode == 0x01) {
        state->intensity = 0;
        state->ms_stereo = 0;

        if (header->modeExt & 0x1)
            state->intensity = 1;

        if (header->modeExt & 0x2)
            state->ms_stereo = 1;
    }

    state->start_ptr = BS->pCurrent_dword;
    state->start_offset = BS->nBit_offset;

    if (header->protectionBit) {
      bs_CRC_reset(&state->crc);
      bs_CRC_update_imm(MP3Header, 16, &state->crc);
      GET_BITS(BS, state->crc_check, 16, Ipp32s);
    }

    if (header->layer == 2) {
        mp3_SetAllocTable(state->header.id,
            state->mpg25,
            state->header.layer,
            state->header.bitRate,
            state->header.samplingFreq,
            state->stereo,

⌨️ 快捷键说明

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