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

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

#include "mp3enc_own_fp.h"

/******************************************************************************
//  Name:
//    mdct_init
//
//  Description:
//    Initialize coefficients of mdct windows
//
//  Input Arguments:
//     - pointer to encoder context
//
//  Output Arguments:
//
//  Returns:
//    -
//
******************************************************************************/

MP3Status mp3enc_mdctInit(MP3Enc *state, Ipp8u *mem, Ipp32s *size_all)
{
    Ipp32s i;
    Ipp32f c[8] =
      { -0.6f, -0.535f, -0.33f, -0.185f, -0.095f, -0.041f, -0.0142f, -0.0037f };
    Ipp32f tmp;
    Ipp32f *cs, *ca;
    Ipp32f (*mdct_win)[36];
    Ipp32s size, ts, ts1, size_buf, size_init, size_buf1, size_init1;
    Ipp8u *mem_init;

    size = 0;

    ippsMDCTFwdGetSize_32f(36, &ts, &size_init, &size_buf);
    ippsMDCTFwdGetSize_32f(12, &ts1, &size_init1, &size_buf1);
    if (size_buf < size_buf1) size_buf = size_buf1;
    if (size_init < size_init1) size_init = size_init1;

    size += ts + ts1 + size_buf;

    if (mem) {
      mem_init = 0;
      if (size_init) {
        mem_init = ippsMalloc_8u(size_init);
        if (!mem_init)
          return MP3_ALLOC;
      }

      ippsMDCTFwdInitAlloc_32f(&(state->pMDCTSpec36), 36/*, mem, mem_init*/);
//      ippsMDCTFwdInit_32f(&(state->pMDCTSpec36), 36, mem, mem_init);
      mem += ts;
      ippsMDCTFwdInitAlloc_32f(&(state->pMDCTSpec12), 12/*, mem, mem_init*/);
//      ippsMDCTFwdInit_32f(&(state->pMDCTSpec12), 12, mem, mem_init);
      mem += ts1;
      state->pMDCTbuf = mem;
      mem += size_buf;
      if(mem_init)
        ippsFree(mem_init);
    }

    if(state) {
      cs = state->cs;
      ca = state->ca;
      mdct_win = state->mdct_win;

      for (i = 0; i < 8; i++) {
        tmp = (Ipp32f)sqrt(1.0 + c[i] * c[i]);
        ca[i] = c[i] / tmp;
        cs[i] = 1.0f / tmp;
      }

  /*
  * type 0
  */
      for (i = 0; i < 36; i++)
        state->mdct_win[0][i] = (Ipp32f)sin(PI / 36 * (i + 0.5));
  /*
  * type 1
  */
      for (i = 0; i < 18; i++)
        mdct_win[1][i] = (Ipp32f)sin(PI / 36 * (i + 0.5));
      for (i = 18; i < 24; i++)
        mdct_win[1][i] = 1.0;
      for (i = 24; i < 30; i++)
        mdct_win[1][i] = (Ipp32f)sin(PI / 12 * (i + 0.5 - 18));
      for (i = 30; i < 36; i++)
        mdct_win[1][i] = 0.0;
  /*
  * type 3
  */
      for (i = 0; i < 6; i++)
        mdct_win[3][i] = 0.0;
      for (i = 6; i < 12; i++)
        mdct_win[3][i] = (Ipp32f)sin(PI / 12 * (i + 0.5 - 6));
      for (i = 12; i < 18; i++)
        mdct_win[3][i] = 1.0;
      for (i = 18; i < 36; i++)
        mdct_win[3][i] = (Ipp32f)sin(PI / 36 * (i + 0.5));
  /*
  * type 2
  */
      for (i = 0; i < 12; i++)
        mdct_win[2][i] = (Ipp32f)sin(PI / 12 * (i + 0.5));
      for (i = 12; i < 36; i++)
        mdct_win[2][i] = 0.0;

      ippsZero_32f(&state->fbout_data[0][0][0][0],2*3*18*32);
    }

    if(size_all)
      *size_all = size;

    return MP3_OK;
}

/******************************************************************************
//  Name:
//    mdct
//
//  Description:
//    Perform windowing and appling of mdct.
//
//  Input Arguments:
//             - pointer to encoder context
//    in         - input samples
//   block_type  - type of block
//
//  Output Arguments:
//    out        - samples in frequency domain
//
//  Returns:
//    1 - all ok
******************************************************************************/

Ipp32s mp3enc_mdctInSubband(MP3Enc *state,
                            Ipp32f *in,
                            Ipp32f *out,
                            Ipp32s block_type)
{
    Ipp32s i, j;
    Ipp32f *tout = out;

    if (block_type == 2) {
      Ipp32f tmp_in[36];
      Ipp32f tmp_out[36];
      Ipp32f *tmp_out2[3];
      Ipp32f **tmp_out3;

      tmp_out2[0] = tmp_out;
      tmp_out2[1] = tmp_out + 6;
      tmp_out2[2] = tmp_out + 12;

      tmp_out3 = &(tmp_out2[0]);

      for (i = 0; i < state->com.lowpass_maxline; i++) {
        ippsMul_32f(in + 6, state->mdct_win[block_type], tmp_in, 12);
        ippsMul_32f(in + 12, state->mdct_win[block_type], tmp_in + 12, 12);
        ippsMul_32f(in + 18, state->mdct_win[block_type], tmp_in + 24, 12);

        ippsMDCTFwd_32f(tmp_in, tmp_out, state->pMDCTSpec12, state->pMDCTbuf);
        ippsMDCTFwd_32f(tmp_in + 12, tmp_out + 6, state->pMDCTSpec12, state->pMDCTbuf);
        ippsMDCTFwd_32f(tmp_in + 24, tmp_out + 12, state->pMDCTSpec12, state->pMDCTbuf);

        ippsMulC_32f_I(2.f / 12, tmp_out, 18);
        ippsInterleave_32f((const Ipp32f **)tmp_out3, 3, 6, out);
        in += 36;
        out += 18;
      }
    } else {
      Ipp32f  *ptr_out = out;

      for (i = 0; i < state->com.lowpass_maxline; i++) {

        for (j = 0; j < 36; j++)
          in[j] *= state->mdct_win[block_type][j];

        ippsMDCTFwd_32f(in, out, state->pMDCTSpec36, state->pMDCTbuf);

        in += 36;
        out += 18;
      }
      ippsMulC_32f_I(2.f / 36, ptr_out, 18 * state->com.lowpass_maxline);
    }

    if (state->com.lowpass_maxline < 32) {
        ippsZero_32f(tout + state->com.lowpass_maxline * 18, 18 * (32 - state->com.lowpass_maxline));
    }

    return 1;
}

/******************************************************************************
//  Name:
//    mdctBlock
//
//  Description:
//    The output of the filterbank is the input to the subdivision using the MDCT.
//    18 consecutive output values of one granule and 18 output values of the granule before
//    are assembled to one block of 36 samples for each subbands.
//
//  Input Arguments:
//             - pointer to encoder context
//
//  Output Arguments:
//    -
//
//  Returns:
//    1 - all ok.
******************************************************************************/

Ipp32s mp3enc_mdctBlock(MP3Enc *state)
{
    VM_ALIGN16_DECL(Ipp32f) in[1152];
    Ipp32s ch, gr, bnd, k, j;
    Ipp32f bu, bd;

    Ipp32f *ptr_fbout;
    Ipp32f *cs, *ca;
    Ipp32s stereo;
    Ipp32s grnum;

    stereo = state->com.stereo;
    grnum = state->com.grnum;
    cs = state->cs;
    ca = state->ca;

    for (gr = 1; gr <= grnum; gr++) {
      for (ch = 0; ch < stereo; ch++) {
        ptr_fbout = &((*(state->fbout[gr]))[ch][0][0]);
        for (k = 33; k < 576; k += 32)
            for (j = 0; j < 32; j += 2, k += 2)
                ptr_fbout[k] = -ptr_fbout[k];
        }
    }

    for (gr = 0; gr < grnum; gr++) {
      for (ch = 0; ch < stereo; ch++) {
        for (bnd = 0, j = 0; bnd < 32; bnd++) {
          for (k = 0; k < 18; k++) {
            in[j + k] = (*(state->fbout[gr]))[ch][k][bnd];
            in[j + k + 18] = (*(state->fbout[gr + 1]))[ch][k][bnd];
          }
          j += 36;
        }

        mp3enc_mdctInSubband(state, in, state->mdct_out[gr][ch], state->com.si_blockType[gr][ch]);

      }
      for (ch = 0; ch < stereo; ch++) {
        if (state->com.si_blockType[gr][ch] != 2) {
          Ipp32s  idx1, idx2;

          j = 0;
          for (bnd = 0; bnd < 31; bnd++) {
            for (k = 0; k < 8; k++) {
              idx1 = j + 17 - k;
              idx2 = j + 18 + k;
              bu =
                state->mdct_out[gr][ch][idx1] * cs[k] + state->mdct_out[gr][ch][idx2] * ca[k];
              bd =
                state->mdct_out[gr][ch][idx2] * cs[k] - state->mdct_out[gr][ch][idx1] * ca[k];
              state->mdct_out[gr][ch][idx1] = bu;
              state->mdct_out[gr][ch][idx2] = bd;
            }
            j += 18;
          }
        } else {
          Ipp32s i, sfb, start, end, line, window;
          Ipp32u *sfb_short = mp3enc_sfBandIndex[state->com.header.id][state->com.header.samplingFreq].s;
          Ipp32f *mdct_out = state->mdct_out[gr][ch];

          i = 0;
          for (sfb = 0; sfb < 13; sfb++) {
            start = sfb_short[sfb];
            end = sfb_short[sfb + 1];

            for (window = 0; window < 3; window++) {
              for (line = start; line < end; line += 2) {
                in[i++] = mdct_out[line*3  +window];
                in[i++] = mdct_out[line*3+3+window];
              }
            }
          }
          ippsCopy_32f(in, mdct_out, 576);
        }
      }
      if (state->com.stereo_mode == MPA_MS_STEREO) {
        const Ipp32f mult = 0.7071067811865475244f;
        Ipp32f *ptrL = &(state->mdct_out[gr][0][0]);
        Ipp32f *ptrR = &(state->mdct_out[gr][1][0]);
        Ipp32f li, ri;
        for (k = 0; k < 576; k++) {
          li = mult * (ptrL[0] + ptrR[0]);
          ri = mult * (ptrL[0] - ptrR[0]);
          ptrL[0] = li;
          ptrR[0] = ri;
          ptrL++; ptrR++;
        }
      }
    }

    state->fbout_prev += grnum;
    if (state->fbout_prev > 2)
        state->fbout_prev -= 3;

    for (j = 0; j < 3; j++) {
        Ipp32s ind;
        ind = state->fbout_prev + j;
        if (ind > 2) ind -= 3;
        state->fbout[j] = &state->fbout_data[ind];
    }

    return 1;
}

⌨️ 快捷键说明

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