📄 aac_enc_psychoacoustic_fp.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) 2003-2007 Intel Corporation. All Rights Reserved.
//
// Intel Integrated Performance Primitives AAC Encode Sample for Windows*
//
// By downloading and installing this sample, you hereby agree that the
// accompanying Materials are being provided to you under the terms and
// conditions of the End User License Agreement for the Intel Integrated
// Performance Primitives product previously accepted by you. Please refer
// to the file ippEULA.rtf or ippEULA.txt located in the root directory of your Intel IPP
// product installation for more information.
//
// MPEG-4 and AAC are international standards promoted by ISO, IEC, ITU, ETSI
// and other organizations. Implementations of these standards, or the standard
// enabled platforms may require licenses from various entities, including
// Intel Corporation.
//
*/
#include <stdlib.h>
#include <math.h>
#include "ipps.h"
#include "ippac.h"
#include "aac_enc_psychoacoustic_fp.h"
#include "aac_sfb_tables.h"
#include "align.h"
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX_TRH_SHORT 100000
/****************************************************************************/
/*x*/ /*y*/
static const float hiPassCoeff[] = {0.43409411784051444f, 0.13181176431897129f};
//static const float hiPassCoeff[] = {-0.4142f, 0.7071f};
//static const float hiPassCoeff[] = {-0.6128f, 0.8064f};
/****************************************************************************/
void BlockSwitching(sPsychoacousticBlock* pBlock,
sPsychoacousticBlockCom* pBlockCom,
Ipp32s ch)
{
Ipp32f tmpDst[1024];
Ipp32f winEnergy[8];
Ipp32f max;
Ipp32s w, attack;
pBlock->attackIndex = pBlock->lastAttackIndex;
for (w = 0; w < 3; w++) {
ippsIIR_32f(pBlockCom->input_data[ch][1] + 128 * w + 576,
tmpDst, 128, pBlock->IIRfilterState);
ippsDotProd_32f(tmpDst, tmpDst, 128, &winEnergy[w]);
}
ippsIIR_32f(pBlockCom->input_data[ch][1] + 128 * 3 + 576,
tmpDst, 64, pBlock->IIRfilterState);
ippsIIR_32f(pBlockCom->input_data[ch][2],
tmpDst+64, 64, pBlock->IIRfilterState);
ippsDotProd_32f(tmpDst, tmpDst, 128, &winEnergy[3]);
for (w = 4; w < 8; w++) {
ippsIIR_32f(pBlockCom->input_data[ch][2] + 128 * (w - 4) + 64,
tmpDst, 128, pBlock->IIRfilterState);
ippsDotProd_32f(tmpDst, tmpDst, 128, &winEnergy[w]);
}
attack = 0;
max = 0;
pBlock->lastAttackIndex = -1;
for (w = 0; w < 8; w++) {
if (winEnergy[w] > pBlock->avWinEnergy * pBlockCom->attackThreshold) {
attack = 1;
pBlock->lastAttackIndex = w;
}
pBlock->avWinEnergy = (0.7f * pBlock->avWinEnergy) + (0.3f * winEnergy[w]);
if (max < winEnergy[w]) max = winEnergy[w];
}
if (max < 1000000) {
attack = 0;
}
if (attack) {
pBlock->next_desired_block_type = EIGHT_SHORT_SEQUENCE;
} else{
pBlock->next_desired_block_type = ONLY_LONG_SEQUENCE;
}
}
/****************************************************************************/
Ipp32f sprdngf(Ipp32f b1,
Ipp32f b2)
{
Ipp32f tmpx,tmpy,tmpz;
tmpx = (b2 >= b1) ? 3*(b2-b1) : 1.5f*(b2-b1);
tmpz = 8 * MIN((tmpx-0.5f)*(tmpx-0.5f) - 2*(tmpx-0.5f), 0);
tmpy = 15.811389f + 7.5f*(tmpx + 0.474f)-
17.5f*(Ipp32f)sqrt(1 + (tmpx+0.474f)*(tmpx+0.474f));
return (tmpy < -100 ? 0 : (Ipp32f)pow(10,(Ipp32f)(tmpz + tmpy)/10));
}
/****************************************************************************/
void psy_long_window(sPsychoacousticBlock* pBlock,
sPsychoacousticBlockCom* pBlockCom,
Ipp32s ch)
{
__ALIGN Ipp32f rsqr_long[1024];
Ipp32f e_b[MAX_PPT_LONG];
Ipp32f ecb[MAX_PPT_LONG];
Ipp32f *r;
Ipp32f *nb,*nb_l;
Ipp32f *noiseThr;
Ipp32s b, num_ptt, sb;
r = (Ipp32f*)pBlock->r[0];
ippsZero_32f(r + pBlockCom->non_zero_line_long, 1024 - pBlockCom->non_zero_line_long);
ippsSqr_32f((Ipp32f*)r, rsqr_long, 1024);
num_ptt = pBlockCom->longWindow->num_ptt;
for (b = 0; b < num_ptt; b++) {
Ipp32s w_high = pBlockCom->longWindow->w_high[b];
Ipp32s w_low = pBlockCom->longWindow->w_low[b];
Ipp32f *tmp_rsqr = &rsqr_long[w_low];
Ipp32s len = w_high - w_low + 1;
ippsSum_32f(tmp_rsqr, len, &e_b[b], ippAlgHintNone);
}
for (b = 0; b < num_ptt; b++) {
Ipp32f *tmp_ptr = (Ipp32f*)pBlockCom->sprdngf_long + b * num_ptt;
ippsDotProd_32f(e_b, tmp_ptr, num_ptt, &ecb[b]);
}
nb = pBlock->nb_long[pBlockCom->nb_curr_index];
nb_l = pBlock->nb_long[pBlockCom->nb_prev_index];
ippsMulC_32f_I(ATTENUATION, ecb, num_ptt);
ippsMul_32f((Ipp32f*)pBlockCom->rnorm_long, ecb, (Ipp32f*)nb, num_ptt);
if (pBlock->block_type != LONG_STOP_SEQUENCE) {
ippsMulC_32f(nb_l, 0.01f, ecb, num_ptt);
ippsMaxEvery_32f_I(nb, ecb, num_ptt);
ippsMulC_32f_I(2, nb_l, num_ptt);
ippsMinEvery_32f_I(ecb, nb_l, num_ptt);
} else {
ippsCopy_32f(nb, nb_l, num_ptt);
}
ippsMaxEvery_32f_I(pBlockCom->longWindow->qsthr, nb, num_ptt);
ippsMaxEvery_32f_I(pBlockCom->longWindow->qsthr, nb_l, num_ptt >> 1);
noiseThr = &pBlockCom->noiseThr[ch][0];
for (sb = 0; sb < pBlockCom->num_sfb_long; sb++) {
Ipp32s start = pBlockCom->aacenc_p2sb_l[sb].bu;
Ipp32s end = pBlockCom->aacenc_p2sb_l[sb].bo;
noiseThr[sb] = pBlockCom->aacenc_p2sb_l[sb].w1 * nb_l[start] +
pBlockCom->aacenc_p2sb_l[sb].w2 * nb_l[end];
for (b = start + 1; b < end; b++) {
noiseThr[sb] += nb_l[b];
}
if ((noiseThr[sb] > 1.0e9f) && (sb < 11)) {
noiseThr[sb] = 1.0e9f;
}
}
}
/****************************************************************************/
void psy_short_window(sPsychoacousticBlock* pBlock,
sPsychoacousticBlockCom* pBlockCom,
Ipp32s ch,
Ipp32s lastBlockType)
{
__ALIGN Ipp32f rsqr_short[128];
Ipp32f *r;
Ipp32s win_counter;
Ipp32f e_b[MAX_PPT_SHORT];
Ipp32f ecb[MAX_PPT_SHORT];
Ipp32f *nb, *nb_s;
Ipp32f *noiseThr;
Ipp32s b, num_ptt, sb;
for (win_counter = 0; win_counter < 8; win_counter++) {
r = &pBlock->r[0][win_counter*128];
ippsZero_32f(r + pBlockCom->non_zero_line_short, 128 - pBlockCom->non_zero_line_short);
ippsSqr_32f(r, rsqr_short, 128);
num_ptt = pBlockCom->shortWindow->num_ptt;
for (b = 0; b < num_ptt; b++) {
Ipp32s w_high = pBlockCom->shortWindow->w_high[b];
Ipp32s w_low = pBlockCom->shortWindow->w_low[b];
Ipp32f *tmp_rsqr = &rsqr_short[w_low];
Ipp32s len = w_high - w_low + 1;
ippsSum_32f(tmp_rsqr, len, &e_b[b], ippAlgHintNone);
}
for (b = 0; b < num_ptt; b++) {
Ipp32f *tmp_ptr = (Ipp32f*)pBlockCom->sprdngf_short + b * num_ptt;
ippsDotProd_32f(e_b, tmp_ptr, num_ptt, &ecb[b]);
}
nb = pBlock->nb_short[0][win_counter];
if (win_counter == 0) {
nb_s = pBlock->nb_short[0][7];
} else {
nb_s = pBlock->nb_short[0][win_counter - 1];
}
ippsMulC_32f_I(ATTENUATION, ecb, num_ptt);
ippsMul_32f(pBlockCom->rnorm_short, ecb, nb, num_ptt);
if ((lastBlockType != LONG_START_SEQUENCE) || (win_counter != 0)) {
ippsMulC_32f(nb_s, 0.01f, ecb, num_ptt);
ippsMaxEvery_32f_I(nb, ecb, num_ptt);
ippsMulC_32f_I(2, nb_s, num_ptt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -