📄 aac_enc_psychoacoustic_int.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) 2004-2006 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 <stdio.h>
#include <math.h>
#include "ipps.h"
#include "ippac.h"
#include "aac_enc_psychoacoustic_int.h"
#include "aac_sfb_tables.h"
#define FIND_NORM_SHIFT_16S(pSrc, len, shift) \
{ \
Ipp16s _min0, _max0; \
Ipp32s _min, _max; \
\
ippsMinMax_16s(pSrc, len, &_min0, &_max0); \
\
_min = -((Ipp32s)_min0); \
_max = _max0; \
\
if (_min > _max) { \
_max = _min - 1; \
} \
\
shift = 0; \
\
if (_max > 0) { \
while (_max <= 16383) { \
_max = _max << 1; \
shift++; \
} \
} \
}
/****************************************************************************/
static void aaciencPsy_long_window(sPsychoacousticBlock* pBlock,
sPsychoacousticBlockCom* pBlockCom,
Ipp32s* ms_pwr,
Ipp32s* ms_pwr_Scalef,
Ipp32s* PE,
Ipp32s ch,
Ipp32s ind)
{
__ALIGN Ipp32s rsqr_long[1024];
__ALIGN Ipp16s sw[N_LONG];
__ALIGN Ipp16s abs_sw[N_LONG];
__ALIGN Ipp16s fft_line[__ALIGNED(2*N_LONG+2)];
__ALIGN Ipp32s e_b[MAX_PPT_LONG];
__ALIGN Ipp32s c_b[MAX_PPT_LONG];
__ALIGN Ipp32s ecb[MAX_PPT_LONG];
__ALIGN Ipp32s ct[MAX_PPT_LONG];
__ALIGN Ipp32s tmp_ecb[MAX_PPT_LONG];
__ALIGN Ipp32s tmp_ct[MAX_PPT_LONG];
__ALIGN Ipp32s ecb_h_limit[MAX_PPT_LONG];
__ALIGN Ipp32s ecb_l_limit[MAX_PPT_LONG];
__ALIGN Ipp16s c_w[1024];
__ALIGN Ipp16s tmp_ln[MAX_PPT_LONG];
__ALIGN Ipp16s tmp_ln0[MAX_PPT_LONG];
__ALIGN Ipp16s tmp_ln1[MAX_PPT_LONG];
__ALIGN Ipp16s tmp[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s tmp0[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s tmp1[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s tmp2[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s tmp3[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s tmp4[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s tmp5[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s denum[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s r_pred[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s re_pred[NUM_UNPRED_LINES_LONG];
__ALIGN Ipp16s im_pred[NUM_UNPRED_LINES_LONG];
Ipp16s *r, *r_prev, *r_prev_prev;
Ipp16s *re, *re_prev, *re_prev_prev;
Ipp16s *im, *im_prev, *im_prev_prev;
Ipp16s *tmp_dst[2];
Ipp32s *nb,*nb_l;
Ipp32s b, scaleFactor;
Ipp32s sum;
Ipp32s shift0, shift1, shift;
Ipp32s rScaleFactor, r_prevScaleFactor;
Ipp32s r_prev_prevScaleFactor, r_predScaleFactor;
Ipp32s nb_ScaleFactor, nb_lScaleFactor;
Ipp32s num_ptt_long = pBlockCom->longWindow->num_ptt;
Ipp32s rsqr_longScale;
ippsMul_16s_Sfs((Ipp16s*)pBlockCom->input_data[ch][0], AACI_HANN_long,
sw, pBlockCom->iblen_long, 15);
ippsMul_16s_Sfs((Ipp16s*)pBlockCom->input_data[ch][1],
&AACI_HANN_long[pBlockCom->iblen_long],
&sw[1024], pBlockCom->iblen_long, 15);
ippsAbs_16s(sw, abs_sw, 2 * pBlockCom->iblen_long);
ippsSum_16s32s_Sfs(abs_sw, 2 * pBlockCom->iblen_long, &sum, 0);
scaleFactor = 0;
if (sum != 0) {
if (sum > 32768) {
while (sum > 32768) {
sum >>= 1;
scaleFactor++;
}
} else {
while (sum <= 16384) {
sum *= 2;
scaleFactor--;
}
}
}
ippsFFTFwd_RToCCS_16s_Sfs(sw, fft_line, pBlockCom->pFFTSpecLong,
scaleFactor, pBlockCom->pBuffer);
r = (Ipp16s*)pBlock->r[ind][pBlockCom->current_f_r_index];
re = (Ipp16s*)pBlock->re[ind][pBlockCom->current_f_r_index];
im = (Ipp16s*)pBlock->im[ind][pBlockCom->current_f_r_index];
ippsMagnitude_16sc_Sfs((Ipp16sc *)fft_line, r, pBlockCom->iblen_long, 1);
if (ind) {
ippsSum_16s32s_Sfs(r, 1024, ms_pwr, 0);
*ms_pwr_Scalef = scaleFactor + 1;
}
ippsThreshold_LT_16s_I(r, pBlockCom->iblen_long, 1);
tmp_dst[0] = re;
tmp_dst[1] = im;
ippsDeinterleave_16s(fft_line, 2, NUM_UNPRED_LINES_LONG, tmp_dst);
/* re and im in Q15 */
ippsDiv_16s_ISfs(r, re, NUM_UNPRED_LINES_LONG, -14);
ippsDiv_16s_ISfs(r, im, NUM_UNPRED_LINES_LONG, -14);
FIND_NORM_SHIFT_16S(r, pBlockCom->iblen_long, shift)
ippsLShiftC_16s_I(shift, r, pBlockCom->iblen_long);
rScaleFactor = scaleFactor + 1 - shift;
pBlock->rScaleFactor[ind][pBlockCom->current_f_r_index] = rScaleFactor;
r_prev = (Ipp16s*)pBlock->r[ind][pBlockCom->prev_f_r_index];
re_prev = (Ipp16s*)pBlock->re[ind][pBlockCom->prev_f_r_index];
im_prev = (Ipp16s*)pBlock->im[ind][pBlockCom->prev_f_r_index];
r_prevScaleFactor = pBlock->rScaleFactor[ind][pBlockCom->prev_f_r_index];
r_prev_prev = (Ipp16s*)pBlock->r[ind][pBlockCom->prev_prev_f_r_index];
re_prev_prev = (Ipp16s*)pBlock->re[ind][pBlockCom->prev_prev_f_r_index];
im_prev_prev = (Ipp16s*)pBlock->im[ind][pBlockCom->prev_prev_f_r_index];
r_prev_prevScaleFactor = pBlock->rScaleFactor[ind][pBlockCom->prev_prev_f_r_index];
/* Calculate the unpredictability measure c(w) */
/* Some transformations: */
/* re((2*r_prev-r_prev_prev)*exp(-j(2*f_prev-f_prev_prev))) = */
/* (2*r_prev-r_prev_prev)* */
/* (2*im_prev_prev*re_prev*im_prev + */
/* re_prev_prev*(re_prev*re_prev-im_prev*im_prev)) */
/* */
/* im((2*r_prev-r_prev_prev)*exp(-j(2*f_prev-f_prev_prev))) = */
/* (2*r_prev-r_prev_prev) * */
/* (2*re_prev_prev*re_prev*im_prev - */
/* im_prev_prev*(re_prev*re_prev-im_prev*im_prev)) */
/* */
/* where re_prev_prev = cos(prev_prev_f), */
/* im_prev_prev = sin(prev_prev_f), */
/* re_prev = cos(prev_prev_f), */
/* im_prev = sin(prev_prev_f) */
/* r_pred = (2*r_prev-r_prev_prev) */
r_predScaleFactor = r_prevScaleFactor + 1;
if (r_prev_prevScaleFactor > r_predScaleFactor) {
shift = r_prev_prevScaleFactor - r_predScaleFactor;
if (shift > 16) shift = 16;
ippsRShiftC_16s(r_prev, shift, tmp0, NUM_UNPRED_LINES_LONG);
ippsSub_16s_Sfs(r_prev_prev, tmp0, r_pred, NUM_UNPRED_LINES_LONG, 1);
r_predScaleFactor = r_prev_prevScaleFactor + 1;
} else if (r_prev_prevScaleFactor < r_predScaleFactor) {
shift = r_predScaleFactor - r_prev_prevScaleFactor;
if (shift > 16) shift = 16;
ippsRShiftC_16s(r_prev_prev, shift, tmp0,NUM_UNPRED_LINES_LONG);
ippsSub_16s_Sfs(tmp0, r_prev, r_pred, NUM_UNPRED_LINES_LONG, 1);
r_predScaleFactor++;
} else {
ippsSub_16s_Sfs(r_prev_prev, r_prev, r_pred, NUM_UNPRED_LINES_LONG, 1);
r_predScaleFactor++;
}
/* tmp1 = 2*re_prev*im_prev (in Q14) */
ippsMul_16s_Sfs(re_prev, im_prev, tmp1, NUM_UNPRED_LINES_LONG, 15);
/* tmp2 = re_prev*re_prev-im_prev*im_prev (in Q14)*/
ippsMul_16s_Sfs(re_prev, re_prev, tmp, NUM_UNPRED_LINES_LONG, 15);
ippsMul_16s_Sfs(im_prev, im_prev, tmp2, NUM_UNPRED_LINES_LONG, 15);
ippsSub_16s_ISfs(tmp, tmp2, NUM_UNPRED_LINES_LONG, 1);
/* im_prev_prev * tmp1 + re_prev_prev * tmp2 (in Q13)*/
ippsMul_16s_Sfs(im_prev_prev, tmp1, re_pred, NUM_UNPRED_LINES_LONG, 15);
ippsMul_16s_Sfs(re_prev_prev, tmp2, tmp, NUM_UNPRED_LINES_LONG, 15);
ippsAdd_16s_ISfs(tmp, re_pred, NUM_UNPRED_LINES_LONG, 1);
/* re_prev_prev * tmp1 - im_prev_prev * tmp2 (in Q13)*/
ippsMul_16s_Sfs(re_prev_prev, tmp1, im_pred, NUM_UNPRED_LINES_LONG, 15);
ippsMul_16s_Sfs(im_prev_prev, tmp2, tmp, NUM_UNPRED_LINES_LONG, 15);
ippsSub_16s_ISfs(tmp, im_pred, NUM_UNPRED_LINES_LONG, 1);
ippsAbs_16s(r_pred, denum, NUM_UNPRED_LINES_LONG);
/* denumScaleFactor = (shift0 == 0) ? r_predScaleFactor + 1 : rScaleFactor + 1 */
if (r_predScaleFactor > rScaleFactor) {
shift0 = 0;
shift1 = r_predScaleFactor - rScaleFactor;
if (shift1 > 16) shift1 = 16;
ippsRShiftC_16s(r, shift1, tmp0, NUM_UNPRED_LINES_LONG);
ippsAdd_16s_ISfs(tmp0, denum, NUM_UNPRED_LINES_LONG, 1);
} else if (r_predScaleFactor < rScaleFactor) {
shift0 = rScaleFactor - r_predScaleFactor;
shift1 = 0;
if (shift0 > 16) shift0 = 16;
ippsRShiftC_16s(denum, shift0, tmp0, NUM_UNPRED_LINES_LONG);
ippsAdd_16s_Sfs(r, tmp0, denum, NUM_UNPRED_LINES_LONG, 1);
} else {
shift0 = 0;
shift1 = 0;
ippsAdd_16s_ISfs(r, denum, NUM_UNPRED_LINES_LONG, 1);
}
/* tmp0 in Q15 */
ippsDiv_16s_Sfs(denum, r_pred, tmp0, NUM_UNPRED_LINES_LONG, -14 + shift0);
/* tmp1 in Q15 */
ippsDiv_16s_Sfs(denum, r, tmp1, NUM_UNPRED_LINES_LONG, -14 + shift1);
/* tmp2 in Q13 */
ippsMul_16s_Sfs(tmp0, re_pred, tmp2, NUM_UNPRED_LINES_LONG, 15);
/* tmp3 in Q13 */
ippsMul_16s_Sfs(tmp0, im_pred, tmp3, NUM_UNPRED_LINES_LONG, 15);
/* tmp4 in Q13 */
ippsMul_16s_Sfs(tmp1, re, tmp4, NUM_UNPRED_LINES_LONG, 17);
/* tmp5 in Q13 */
ippsMul_16s_Sfs(tmp1, im, tmp5, NUM_UNPRED_LINES_LONG, 17);
/* tmp0 in Q12 */
ippsSub_16s_Sfs(tmp2, tmp4, tmp0, NUM_UNPRED_LINES_LONG, 1);
/* tmp1 in Q12 */
ippsSub_16s_Sfs(tmp3, tmp5, tmp1, NUM_UNPRED_LINES_LONG, 1);
/* c_w in Q15 */
ippsMagnitude_16s_Sfs(tmp0, tmp1, c_w, NUM_UNPRED_LINES_LONG, -3);
ippsSet_16s(13107, &c_w[ NUM_UNPRED_LINES_LONG],
pBlockCom->iblen_long - NUM_UNPRED_LINES_LONG);
ippsMul_16s32s_Sfs((Ipp16s*)r, (Ipp16s*)r, rsqr_long, pBlockCom->iblen_long, 0);
rsqr_longScale = 2 * rScaleFactor;
for (b = 0; b < num_ptt_long; b++) {
Ipp32s *tmp_rsqr = &rsqr_long[pBlockCom->longWindow->w_low[b]];
Ipp16s *tmp_c_w = (Ipp16s*)&c_w[pBlockCom->longWindow->w_low[b]];
Ipp32s len = pBlockCom->longWindow->w_width[b];
ippsSum_32s_Sfs(tmp_rsqr, len, &e_b[b], pBlockCom->longScale - 1);
ippsDotProd_16s32s32s_Sfs(tmp_c_w, tmp_rsqr, len,
&c_b[b], pBlockCom->longScale + 14);
}
nb = (Ipp32s *)pBlock->nb_long[ind][pBlockCom->nb_curr_index];
nb_l = (Ipp32s *)pBlock->nb_long[ind][pBlockCom->nb_prev_index];
PE[0] = 0;
for (b = 0; b < num_ptt_long; b++) {
Ipp16s *tmp_ptr = (Ipp16s*)pBlockCom->sprdngf_long +
b * num_ptt_long;
ippsDotProd_16s32s32s_Sfs(tmp_ptr, e_b, num_ptt_long, &ecb[b], 15);
ippsDotProd_16s32s32s_Sfs(tmp_ptr, c_b, num_ptt_long, &ct[b], 15);
}
ippsMulC_32s_Sfs(ecb, 20219, tmp_ecb, num_ptt_long, 21);
ippsMulC_32s_Sfs(ct, 17131, tmp_ct, num_ptt_long, 15);
ippsAdd_32s_Sfs(tmp_ct, tmp_ecb, nb, num_ptt_long, 0);
ippsMulC_32s_Sfs(ecb, 16462, ecb_h_limit, num_ptt_long, 16);
ippsMulC_32s_Sfs(ecb, 16619, ecb_l_limit, num_ptt_long, 20);
ippsMaxEvery_32s_I(ecb_l_limit, nb, num_ptt_long);
ippsMinEvery_32s_I(ecb_h_limit, nb, num_ptt_long);
/* instead of tmp_nb = MAX( pow(10.0,pBlock->qsthr_long[b]/10.0)/32767.0, */
/* MIN(nb[b],2.0*nb_l[b])); */
/* we use only tmp_nb = MIN(nb[b],2.0*nb_l[b]) yet */
nb_ScaleFactor = rsqr_longScale + pBlockCom->longScale - 1;
nb_lScaleFactor = pBlock->nb_longScaleFactor[ind];
nb_lScaleFactor += 1;
if (nb_lScaleFactor > nb_ScaleFactor) {
shift = nb_lScaleFactor - nb_ScaleFactor;
/* I'm using MulC here because LShiftC doesn't provide saturation */
ippsMulC_32s_ISfs(1, nb_l, num_ptt_long, -shift);
} else if (nb_lScaleFactor < nb_ScaleFactor) {
shift = nb_ScaleFactor - nb_lScaleFactor;
if (shift > 31) shift = 31;
ippsRShiftC_32s_I(shift, nb_l, num_ptt_long);
}
ippsMinEvery_32s_I(nb, nb_l, num_ptt_long);
ippsLn_32s16s_Sfs(nb_l, tmp_ln0, num_ptt_long, -10);
pBlock->nb_longScaleFactor[ind] = nb_ScaleFactor;
ippsLn_32s16s_Sfs(e_b, tmp_ln1, num_ptt_long, -10);
ippsSub_16s_Sfs(tmp_ln0, tmp_ln1, tmp_ln, num_ptt_long, 1);
FIND_NORM_SHIFT_16S(tmp_ln, num_ptt_long, shift)
ippsMul_16s_ISfs(pBlockCom->longWindow->w_width, tmp_ln, num_ptt_long,
pBlockCom->longScale - shift);
ippsSum_16s32s_Sfs(tmp_ln, num_ptt_long, PE,
9 - pBlockCom->longScale + shift);
if (pBlockCom->ns_mode) {
Ipp32s epart[MAX_SFB];
Ipp32s npart[MAX_SFB];
Ipp32s *smr;
Ipp32s sb;
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;
epart[sb] = (Ipp32s)((((Ipp64s)pBlockCom->aacenc_p2sb_l[sb].w1 * e_b[start]) >> 32) +
(((Ipp64s)pBlockCom->aacenc_p2sb_l[sb].w2 * e_b[end]) >> 32));
npart[sb] = (Ipp32s)((((Ipp64s)pBlockCom->aacenc_p2sb_l[sb].w1 * nb[start]) >> 32) +
(((Ipp64s)pBlockCom->aacenc_p2sb_l[sb].w2 * nb[end]) >> 32));
for (b = start + 1; b < end; b++) {
epart[sb] += (e_b[b] >> 2);
npart[sb] += (nb[b] >> 2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -