📄 mp3enc_layer3_fp.cpp
字号:
/*////////////////////////////////////////////////////////////////////////////////// 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-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_mp3_encoder.h"namespace UMC { const float mp3enc_scale = 1. / 32768.0f; // 0.000030517578125f; const float mp3enc_sqrtN = 5.65685424949238f; const float mp3enc_sqrtN2 = 4.0f;/******************************************************************************// Name:// mdct_init//// Description:// Initialize coefficients of mdct windows//// Input Arguments:// - pointer to encoder context//// Output Arguments://// Returns:// -//******************************************************************************/ void MP3Encoder::mdctInit() { int i; float c[8] = { -0.6f, -0.535f, -0.33f, -0.185f, -0.095f, -0.041f, -0.0142f, -0.0037f }; float tmp; for (i = 0; i < 8; i++) { tmp = (float)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++) mdct_win[0][i] = (float)sin(PI / 36 * (i + 0.5));/* * type 1 */ for (i = 0; i < 18; i++) mdct_win[1][i] = (float)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] = (float)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] = (float)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] = (float)sin(PI / 36 * (i + 0.5));/* * type 2 */ for (i = 0; i < 12; i++) mdct_win[2][i] = (float)sin(PI / 12 * (i + 0.5)); for (i = 12; i < 36; i++) mdct_win[2][i] = 0.0; assert(pMDCTSpec12 == 0); ippsMDCTFwdInitAlloc_32f(&(pMDCTSpec12), 12); assert(pMDCTSpec36 == 0); ippsMDCTFwdInitAlloc_32f(&(pMDCTSpec36), 36); ippsZero_32f(&fbout_data[0][0][0][0],2*3*18*32); }/******************************************************************************// Name:// windowSubBand//// Description:// The filterbank does a time to frequency mapping.// Filterbank provide the primary frequency separation.//// Input Arguments:// - pointer to encoder context// input - input samples in time domain// ch - number of channel//// Output Arguments:// output - samples in frequency domain//// Returns:// 1 - all ok// 0 - bad argument. null pointer******************************************************************************/ int MP3Encoder::windowSubBand(float *input, float *output, int ch) { IppStatus sts; int k, i, idx, shft, j, l; VM_ALIGN16_DECL(float) tmp32[32]; Ipp8u DCTBuffer[272]; for (l = 0; l < 18; l++) { m_even[ch] = (++m_even[ch] & 0x1); if (m_line[ch][m_even[ch]]) m_line[ch][m_even[ch]]--; else m_line[ch][m_even[ch]] = 7; idx = m_line[ch][m_even[ch]]; j = 8 - idx; for (i = 0; i < 32; i++) { shft = ((31 - i) + (m_even[ch] << 5)) & 0x3f; filter_bfr[ch][shft][idx] = input[i] * mp3enc_scale; } for (i = 0; i <= 16; i++) { shft = (i + (m_even[ch] << 5)) & 0x3f; tmp32[16 - i] = 0; for (k = 0; k < 8; k++) { tmp32[16 - i] += mp3enc_Ccoef[i][j + k] * filter_bfr[ch][shft][k]; } } for (i = 17; i < 32; i++) { shft = (i + (m_even[ch] << 5)) & 0x3f; idx = i - 16; for (k = 0; k < 8; k++) { tmp32[idx] += mp3enc_Ccoef[i][j + k] * filter_bfr[ch][shft][k]; } } j = (8 - m_line[ch][((m_even[ch] + 1) & 0x1)]) & 0x7; shft = (32 + (m_even[ch] << 5)) & 0x3f; for (k = 0; k < 8; k++) { tmp32[16] += mp3enc_Ccoef[32][j + k] * filter_bfr[ch][shft][k]; } for (i = 33; i <= 47; i++) { shft = (i + (m_even[ch] << 5)) & 0x3f; idx = i - 16; tmp32[idx] = 0; for (k = 0; k < 8; k++) { tmp32[idx] += mp3enc_Ccoef[i][j + k] * filter_bfr[ch][shft][k]; } } for (i = 49; i < 64; i++) { shft = (i + (m_even[ch] << 5)) & 0x3f; idx = 80 - i; for (k = 0; k < 8; k++) { tmp32[idx] -= mp3enc_Ccoef[i][j + k] * filter_bfr[ch][shft][k]; } } tmp32[0] *= mp3enc_sqrtN; for (i = 1; i < 32; i++) tmp32[i] *= mp3enc_sqrtN2; sts = ippsDCTInv_32f(tmp32, output, pDCTSpec, DCTBuffer); input += 32; output += 32; } return 1; } void MP3Encoder::windowSubBandInit() { IppStatus sts; assert(pDCTSpec == 0); sts = ippsDCTInvInitAlloc_32f(&(pDCTSpec), 32, ippAlgHintFast); m_even[0] = 0; m_even[1] = 0; m_line[0][0] = 0; m_line[0][1] = 0; m_line[1][0] = 0; m_line[1][1] = 0; ippsZero_32f(&filter_bfr[0][0][0], 2 * 64 * 8); }/******************************************************************************// 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******************************************************************************/ int MP3Encoder::mdctInSubband(float *in, float *out, int block_type) { VM_ALIGN16_DECL(Ipp8u) mdct_bfr[512]; int i, j; float *tout = out; if (block_type == 2) { float tmp_in[36]; float tmp_out[36]; float *tmp_out2[3]; float **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 < lowpass_maxline; i++) { ippsMul_32f(in + 6, mdct_win[block_type], tmp_in, 12); ippsMul_32f(in + 12, mdct_win[block_type], tmp_in + 12, 12); ippsMul_32f(in + 18, mdct_win[block_type], tmp_in + 24, 12); ippsMDCTFwd_32f(tmp_in, tmp_out, pMDCTSpec12, mdct_bfr); ippsMDCTFwd_32f(tmp_in + 12, tmp_out + 6, pMDCTSpec12, mdct_bfr); ippsMDCTFwd_32f(tmp_in + 24, tmp_out + 12, pMDCTSpec12, mdct_bfr); ippsMulC_32f_I(2.f / 12, tmp_out, 18); ippsInterleave_32f((const float **)tmp_out3, 3, 6, out); in += 36; out += 18; } } else { float *ptr_out = out; for (i = 0; i < lowpass_maxline; i++) { for (j = 0; j < 36; j++) in[j] *= mdct_win[block_type][j]; ippsMDCTFwd_32f(in, out, pMDCTSpec36, mdct_bfr); in += 36; out += 18; } ippsMulC_32f_I(2.f / 36, ptr_out, 18 * lowpass_maxline); } if (lowpass_maxline < 32) { ippsZero_32f(tout + lowpass_maxline * 18, 18 * (32 - 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.******************************************************************************/ int MP3Encoder::mdctBlock() { VM_ALIGN16_DECL(float) in[1152]; int ch, gr, bnd, k, j; float bu, bd; float *ptr_fbout; for (gr = 1; gr <= 2; gr++) { for (ch = 0; ch < stereo; ch++) { ptr_fbout = &((*(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 < 2; gr++) { for (ch = 0; ch < stereo; ch++) { for (bnd = 0, j = 0; bnd < 32; bnd++) { for (k = 0; k < 18; k++) { in[j + k] = (*(fbout[gr]))[ch][k][bnd]; in[j + k + 18] = (*(fbout[gr + 1]))[ch][k][bnd]; } j += 36; } mdctInSubband(in, mdct_out[gr][ch], si_blockType[gr][ch]); if (si_blockType[gr][ch] != 2) { int 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 = mdct_out[gr][ch][idx1] * cs[k] + mdct_out[gr][ch][idx2] * ca[k]; bd = mdct_out[gr][ch][idx2] * cs[k] - mdct_out[gr][ch][idx1] * ca[k]; mdct_out[gr][ch][idx1] = bu; mdct_out[gr][ch][idx2] = bd; } j += 18; } } } } fbout_prev += 2; if (fbout_prev > 2) fbout_prev -= 3; for (j = 0; j < 3; j++) { int ind; ind = fbout_prev + j; if (ind > 2) ind -= 3; fbout[j] = &fbout_data[ind]; } return 1; }}; // namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -