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

📄 mp3enc_psychoacoustic_fp.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 2 页
字号:
        sum2 = mp3enc_p2sb_s[freq_ind][sb].w1 * thr[mp3enc_p2sb_s[freq_ind][sb].bu]
          + mp3enc_p2sb_s[freq_ind][sb].w2 * thr[mp3enc_p2sb_s[freq_ind][sb].bo];
        for ( b = mp3enc_p2sb_s[freq_ind][sb].bu+1; b < mp3enc_p2sb_s[freq_ind][sb].bo; b++ ) {
          sum1 += eb[b];
          sum2 += thr[b];
        }

      if (sum1 > 0)
        state->pa_ratio_s_next[ch][win_counter][sb] = sum2/sum1;
      else
        state->pa_ratio_s_next[ch][win_counter][sb] = 0;
      }
    }
  }
}

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

MP3Status mp3enc_psychoacousticInit(MP3Enc *state, Ipp8u *mem, Ipp32s *size_all)
{
  Ipp32s i, j, gr, ch;
  Ipp32s num_ptt, b, bb;
  const Ipp32s num_ptt_long_tbl[3] = {63,62,59};
  const Ipp32s num_ptt_short_tbl[3] = {39,38,42};
  const Ipp32s num_ptt_l12[3] = {57, 58, 49};
  Ipp32s freq_ind, layer;
  Ipp32s size, ts, ts1, size_buf, size_init, size_buf1, size_init1;
  Ipp8u *mem_init;

  size = 0;

  ippsFFTGetSize_R_32f(10, IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, &ts, &size_init, &size_buf);
  ippsFFTGetSize_R_32f(8, IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, &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;
    }

    ippsFFTInit_R_32f(&(state->pa_pFFTSpecLong), 10, IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, mem, mem_init);
    mem += ts;
    ippsFFTInit_R_32f(&(state->pa_pFFTSpecShort), 8, IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, mem, mem_init);
    mem += ts1;
    state->pa_pBuffer = mem;
    mem += size_buf;
    if(mem_init)
      ippsFree(mem_init);
  }

  if(state) {
    freq_ind = state->com.header.samplingFreq;
    layer = state->com.header.layer;

    state->ms_coef[0] = state->ms_coef[1] = state->ms_coef_next = 0;
    state->pa_iblen_long  = 512;
    state->pa_iblen_short = 128;

    for (ch = 0; ch < NUM_CHANNELS; ch++)
      state->pa_current_f_r_index[ch] = 2;

    for (ch = 0; ch < 4; ch++) {
      state->pa_desired_block_type[ch] = NORM_TYPE;
      for (gr = 0; gr < 2; gr++)
      state->pa_next_desired_block_type[gr][ch] = NORM_TYPE;
    }

    if (layer == 3) {
      state->pa_num_ptt_long = num_ptt = num_ptt_long_tbl[freq_ind];
    } else {
      state->pa_num_ptt_long = num_ptt = num_ptt_l12[freq_ind];
    }

    for (b = 0; b < num_ptt; b++) {
      Ipp32f *tmp_ptr = state->pa_sprdngf_long + b * num_ptt;
      Ipp32f tmp = 0;

      if (layer == 3) {
        for (bb = 0; bb < num_ptt; bb++) {
          tmp_ptr[bb] = sprdngf(mp3enc_ptbl_l[freq_ind][bb].bval,
            mp3enc_ptbl_l[freq_ind][b].bval, layer);
          tmp += tmp_ptr[bb];
        }
      } else {
        for (bb = 0; bb < num_ptt; bb++) {
          tmp_ptr[bb] = sprdngf(mp3enc_ptbl_bval_l12[freq_ind][bb],
            mp3enc_ptbl_bval_l12[freq_ind][b], layer);
          tmp += tmp_ptr[bb];
        }
      }

      if (layer == 3)
        state->pa_rnorm_long[b] = 1/tmp;
      else {
        Ipp32s len = mp3enc_ptbl_numlines_l12[freq_ind][b];
        state->pa_rnorm_long[b] = 1/(tmp * len);
      }
    }

    if (layer == 3) {
      state->pa_num_ptt_short = num_ptt = num_ptt_short_tbl[freq_ind];

      for (b = 0; b < num_ptt; b++) {
        Ipp32f *tmp_ptr = state->pa_sprdngf_short + b * num_ptt;
        Ipp32f tmp = 0;

        for (bb = 0; bb < num_ptt; bb++) {
          tmp_ptr[bb] = sprdngf(mp3enc_ptbl_s[freq_ind][bb].bval,
              mp3enc_ptbl_s[freq_ind][b].bval, layer);
          tmp += tmp_ptr[bb];
        }
        state->pa_rnorm_short[b] = 1/tmp;
      }
    }

    /* filling Hann windows */
    for (i = 0; i < state->pa_iblen_long * 2; i++)
      state->pa_hann_window_long[i] =
      (Ipp32f)(0.5f * (1 - cos(PI * (i + 0.5f) / state->pa_iblen_long)));

    if (layer == 3) {
      for (i = 0; i < state->pa_iblen_short * 2; i++)
        state->pa_hann_window_short[i] =
          (Ipp32f)(0.5f * (1 - cos(PI * (i + 0.5f) / state->pa_iblen_short)));
    }

    for (ch = 0; ch < NUM_CHANNELS; ch++) {
      state->pa_nb_curr_index[ch] = 1;
      state->pa_nb_prev_index[ch] = 0;
    }

    for (ch = 0; ch < NUM_CHANNELS; ch++)
    for (i = 0; i < MAX_PPT_LONG; i++) {
      for (j = 0; j < 3; j++)
      state->pa_nb_long[ch][j][i] = (Ipp32f)1.0e30;
    }

    for (ch = 0; ch < NUM_CHANNELS; ch++)
    for (i = 0; i < 512; i++) {
      state->pa_r[ch][0][i] = state->pa_r[ch][1][i] = state->pa_r[ch][2][i] = 1;
      state->pa_re[ch][0][i] = state->pa_re[ch][1][i] = state->pa_re[ch][2][i] = 1;
      state->pa_im[ch][0][i] = state->pa_im[ch][1][i] = state->pa_im[ch][2][i] = 0;
    }

    for (ch = 0; ch < 4; ch++)
    for (j = 0; j < 3; j++) {
      for (i = 0; i < 128; i++) {
        state->pa_r_short[ch][0][j][i] = state->pa_r_short[ch][1][j][i] =
        state->pa_r_short[ch][2][j][i] = 1;

        state->pa_re_short[ch][0][j][i] = state->pa_re_short[ch][1][j][i] =
        state->pa_re_short[ch][2][j][i] = 1;

        state->pa_im_short[ch][0][j][i] = state->pa_im_short[ch][1][j][i] =
        state->pa_im_short[ch][2][j][i] = 0;
      }
    }

    for (ch = 0; ch < 4; ch++)
      state->pa_next_frame_PE[ch] = 0;
  }

  if(size_all)
    *size_all = size;

  return MP3_OK;
}

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

static void mp3enc_psychoacoustic_stage1(MP3Enc *state, Ipp32f *pa_buffer, Ipp32s gr, Ipp32s ch)
{
  VM_ALIGN16_DECL(Ipp32f)  rsqr_long[1024];
  Ipp32f s_en[3];
  Ipp32f min, max;
  Ipp32s i, j;

  state->pa_curr_frame_PE_st[gr][ch] =
  state->pa_curr_frame_PE[ch] = state->pa_next_frame_PE[ch];

  for (i = 0; i < SBBND_L; i++)
    state->pa_ratio_l[gr][ch][i] = state->pa_ratio_l_next[ch][i];

  for (j = 0; j < 3; j++)
    for (i = 0; i < SBBND_S; i++)
      state->pa_ratio_s[gr][ch][j][i] = state->pa_ratio_s_next[ch][j][i];

  mp3enc_psychoacousticLongWindow(state, pa_buffer, rsqr_long, ch);
  mp3enc_psychoacousticShortWindow(state, pa_buffer, s_en, ch);

  ippsMinMax_32f(s_en, 3, &min, &max);

  /* part 1 */

  if (state->pa_next_frame_PE[ch] > 2900) {
    state->pa_next_desired_block_type[gr][ch] = SHORT_TYPE;
  } else if (max > 20 * min) {
    state->pa_next_desired_block_type[gr][ch] = SHORT_TYPE;
  } else if ((max > 10 * min) && (state->pa_next_frame_PE[ch] > 1500)) {
    state->pa_next_desired_block_type[gr][ch] = SHORT_TYPE;
  } else {
    state->pa_next_desired_block_type[gr][ch] = NORM_TYPE;
  }

  state->pa_current_f_r_index[ch]++;
  if (state->pa_current_f_r_index[ch] >= 3)
    state->pa_current_f_r_index[ch] = 0;

  state->pa_nb_curr_index[ch] ^= 1;
  state->pa_nb_prev_index[ch] ^= 1;
}

void mp3enc_psychoacoustic_l1(MP3Enc *state, Ipp32f **pa_buffer)
{
  Ipp32s ch, stereo;
  VM_ALIGN16_DECL(Ipp32f) rsqr_long[1024];

  stereo = state->com.stereo;

  for (ch = 0; ch < stereo; ch++) {
    state->snr = state->pa_snr[ch];
    mp3enc_psychoacousticLongWindow(state, pa_buffer[ch], rsqr_long, ch);

    ippsLn_32f_I(state->snr, state->com.sblimit_real);
    ippsMulC_32f_I(4.342944819f, state->snr, state->com.sblimit_real);

    state->pa_current_f_r_index[ch]++;
    if (state->pa_current_f_r_index[ch] >= 3)
      state->pa_current_f_r_index[ch] = 0;
  }
}

void mp3enc_psychoacoustic_l2(MP3Enc *state, Ipp32f **pa_buffer)
{
  Ipp32s gr, ch, stereo, sblimit;
  VM_ALIGN16_DECL(Ipp32f)  rsqr_long[1024];

  stereo = state->com.stereo;
  sblimit = state->com.sblimit_real;

  for (ch = 0; ch < stereo + state->com.mc_channel; ch++) {
    for (gr = 0; gr < 2; gr++) {
      state->snr = state->pa_snr[ch + gr];
      mp3enc_psychoacousticLongWindow(state, pa_buffer[ch] + gr * 576, rsqr_long, ch);

      state->pa_current_f_r_index[ch]++;
      if (state->pa_current_f_r_index[ch] >= 3)
        state->pa_current_f_r_index[ch] = 0;
    }

    ippsMaxEvery_32f_I(state->pa_snr[ch+1], state->pa_snr[ch], sblimit);
    ippsLn_32f_I(state->pa_snr[ch], sblimit);
    ippsMulC_32f_I(4.342944819f, state->pa_snr[ch], sblimit);
    for(gr = sblimit; gr < 32; gr++)
      state->pa_snr[ch][gr] = -1e37f;
  }
}

void mp3enc_psychoacoustic_l3(MP3Enc *state, Ipp32f **pa_buffer)
{
  Ipp32s gr, ch, ms, stereo;
  Ipp32f coef;
  Ipp32s k, w;
  Ipp32f *ptrL;
  Ipp32f *ptrR;
  Ipp32f li, ri;
  const Ipp32f mult = 0.707106781f;
  Ipp32s grnum = state->com.grnum;

  stereo = state->com.stereo;

  for (gr = 0; gr < grnum; gr++) {
    for (ch = 0; ch < stereo; ch++)
      mp3enc_psychoacoustic_stage1(state, pa_buffer[ch] + gr * 576, gr, ch);

    if (state->com.stereo_mode_param == MPA_MS_STEREO ||
      state->com.stereo_mode_param == MPA_JOINT_STEREO) {
        ptrL = state->fft_line_long[0];
        ptrR = state->fft_line_long[1];

        for (k = 0; k < 1024; k++) {
          li = mult * (ptrL[0] + ptrR[0]);
          ri = mult * (ptrL[0] - ptrR[0]);
          ptrL[0] = li;
          ptrR[0] = ri;
          ptrL++; ptrR++;
        }

        for (w = 0; w < 3; w++) {
          ptrL = state->fft_line_short[0][w];
          ptrR = state->fft_line_short[1][w];

          for (k = 0; k < 256; k++) {
            li = mult * (ptrL[0] + ptrR[0]);
            ri = mult * (ptrL[0] - ptrR[0]);
            ptrL[0] = li;
            ptrR[0] = ri;
            ptrL++; ptrR++;
          }
        }

        for (ch = 2; ch < 4; ch++)
          mp3enc_psychoacoustic_stage1(state, pa_buffer[ch & 1] + gr * 576, gr, ch);

        state->ms_coef[gr] = state->ms_coef_next;
        coef = state->ms_pwr[0] + state->ms_pwr[1];
        if (coef > 0)
          coef = state->ms_pwr[0] / coef;
        state->ms_coef_next = coef;

      }
  }

  state->com.stereo_mode = state->com.stereo_mode_param;

  if (state->com.stereo_mode_param == MPA_JOINT_STEREO) {
    if (state->com.header.id) {
      if (state->pa_curr_frame_PE_st[0][2] + state->pa_curr_frame_PE_st[0][3] +
        state->pa_curr_frame_PE_st[1][2] + state->pa_curr_frame_PE_st[1][3] <
        0.7 * (state->pa_curr_frame_PE_st[0][0] + state->pa_curr_frame_PE_st[0][1] +
        state->pa_curr_frame_PE_st[1][0] + state->pa_curr_frame_PE_st[1][1]) ||
        (state->ms_coef[0] > 0.75 && state->ms_coef[1] > 0.75))
        state->com.stereo_mode = MPA_MS_STEREO;
      else
        state->com.stereo_mode = MPA_LR_STEREO;
    } else {
      if (state->pa_curr_frame_PE_st[0][2] + state->pa_curr_frame_PE_st[0][3] <
        0.7 * (state->pa_curr_frame_PE_st[0][0] + state->pa_curr_frame_PE_st[0][1]) ||
        (state->ms_coef[0] > 0.75 && state->ms_coef[1] > 0.75))
        state->com.stereo_mode = MPA_MS_STEREO;
      else
        state->com.stereo_mode = MPA_LR_STEREO;
    }
  }

  if(state->com.stereo_mode_param == MPA_JOINT_STEREO ||
    state->com.stereo_mode_param == MPA_MS_STEREO) {
      for(ch = 0; ch <= 2; ch += 2) {
        for (gr = 0; gr < grnum; gr++) {
          if ( state->pa_next_desired_block_type[gr][ch] != state->pa_next_desired_block_type[gr][ch+1])
            state->pa_next_desired_block_type[gr][ch] =
            state->pa_next_desired_block_type[gr][ch+1] = SHORT_TYPE;
        }
      }
    }

    ms = state->com.stereo_mode == MPA_MS_STEREO ? 2 : 0;

    for (gr = 0; gr < grnum; gr++) {
      for (ch = 0; ch < state->com.stereo; ch++) {
        Ipp32s next_desired_block_type = state->pa_next_desired_block_type[gr][ch+ms];

        if (next_desired_block_type == NORM_TYPE) {
          if (state->pa_desired_block_type[ch] == SHORT_TYPE)
            next_desired_block_type = STOP_TYPE;
        } else {
          if (state->pa_desired_block_type[ch] == NORM_TYPE )
            state->pa_desired_block_type[ch] = START_TYPE;
          if ( state->pa_desired_block_type[ch] == STOP_TYPE ) {
            state->pa_desired_block_type[ch] = SHORT_TYPE;
          }
        }

        state->com.si_blockType[gr][ch] = state->pa_desired_block_type[ch];
        state->pa_desired_block_type[ch] = next_desired_block_type;

        if ((mp3_bitrate[state->com.header.id][state->com.header.layer-1]
              [state->com.header.bitRate] >> (state->com.stereo - 1)) <= 40)
          state->com.si_blockType[gr][ch] = NORM_TYPE;

        if (state->com.si_blockType[gr][ch] == NORM_TYPE)
          state->com.si_winSwitch[gr][ch] = 0;
        else
          state->com.si_winSwitch[gr][ch] = 1;

        state->com.si_mixedBlock[gr][ch] = 0;
      }
    }
}

⌨️ 快捷键说明

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