📄 sbr_dec_hf_adjust_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) 2005-2006 Intel Corporation. All Rights Reserved.
//
*/
#include <math.h>
#include "ipps.h"
#include "sbr_settings.h"
#include "sbr_struct.h"
#include "sbr_dec_tabs_int.h"
#include "sbr_dec_api_int.h"
#include "sbr_dec_own_int.h"
/********************************************************************/
/* (1.584893192)^2 * Q28 */
static const Ipp32s THRESHOLD_GAIN_BOOST = 0x2830AFD3;
/********************************************************************/
static const Ipp32s POW_MINUS_UNIT[] =
{ 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1,
1, -1, 1, -1, 1, -1, 1, -1, 1, -1,
1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1,
1, -1, 1, -1, 1, -1, 1, -1, 1, -1
};
/********************************************************************/
static const Ipp32s SIN_FI_RE[4] = { 1, 0, -1, 0 };
/********************************************************************/
static const Ipp32s SIN_FI_IM[4] = { 0, 1, 0, -1 };
/********************************************************************/
/* Q30 */
static const Ipp32s TABLE_LIMIT_GAIN_INT_Q30[4] =
{ 0x20138CA7, 0x40000000, 0x7FB27DCE, THRESHOLD_GAIN };
/********************************************************************/
/* Q31 */
static const Ipp32s ihSmoothFilter[] = {
0x04130598, 0x0EBDB043, 0x1BECFA68, 0x2697A512, 0x2AAAAAAB
};
/****************************************************
*
* SBR_TABLE_INVERT[i] = 2^0 / (i + 1), Q31
* see <sbrdec_math_int.c> && <sbrdec_own_int.h>
*
****************************************************/
static Ipp32s sbrCalcGainGroups(Ipp32s* s_mapped, Ipp32s* degPatched, Ipp32s* f_group, Ipp32s kx, Ipp32s M )
{
Ipp32s grouping = 0, i = 0, n_group = 0, k = 0;
for (k = kx; k < kx + M - 1; k++) {
if (degPatched[k + 1] && (s_mapped[k - kx] == 0)) {
if (grouping == 0) {
f_group[i] = k;
grouping = 1;
i++;
}
} else {
if (grouping == 1) {
if (s_mapped[k - kx] == 0)
f_group[i] = k + 1;
else
f_group[i] = k;
grouping = 0;
i++;
}
}
}
if (grouping == 1) {
f_group[i] = M + kx;
i++;
}
n_group = (i >> 1);
return n_group;
}
/********************************************************************/
Ipp32s sbriScale_64s32s(Ipp64s InData, Ipp32s *scaleFactor)
{
Ipp32s OutData;
#if 1
Ipp32s nGB;
Ipp32s shift = 0;
if (InData >> 32) {
nGB = sbri_CLZ((Ipp32s)(InData >> 32)) - 1; //remove "sign" bit
shift = 32 - nGB;
OutData = (Ipp32s)(InData >> shift);
} else if (InData > (Ipp64s)IPP_MAX_32S ) {//(InData >> 31) {
shift = 1;
OutData = (Ipp32s)(InData >> shift);
} else {
OutData = (Ipp32s)InData;
}
*scaleFactor = -shift;
#endif
return OutData;
}
/********************************************************************/
static Ipp32s sbrPreProcAliasReduction(Ipp32s* pSrc, Ipp32s* pDst, Ipp32s len, Ipp32s minGB)
{
Ipp32s absMax;
Ipp32s nGB;
Ipp32s offset;
Ipp32s n;
//---------------------------------------------------------
ippsMaxAbs_32s(pSrc, len, &absMax);
if (absMax == 0) {
ippsCopy_32s(pSrc, pDst, len);
return 0; // OK
}
/* step 2: calculate num Guard bit */
nGB = sbri_CLZ(absMax);
nGB -= 1; // remove "sign"
/* step 3: check nGuardBit >= 3 (!!!) */
offset = 0;
if (nGB < minGB)
offset = minGB - nGB;
/* step 4: scale */
//if (offset) {
for (n = 0; n < 64; n++) {
pDst[n] = pSrc[n] >> offset;
}
return offset;
//}
//------------------------------------------------------------------
}
/********************************************************************/
static void sbrAliasReduction_32s(Ipp32s *degPatched,
Ipp32s *inBufE, Ipp32s sfBufE,
Ipp32s *inBufG, Ipp32s sfBufG,
Ipp32s *inBufG2, Ipp32s sfBufG2,
Ipp32s *s_mapped, Ipp32s kx, Ipp32s M)
{
Ipp64s denum_64s, energ_total_new_64s, energ_total_64s;
const Ipp32s oneQ29 = 0x20000000;
Ipp32s new_gain, energ_total_new, alpha;
Ipp32s i, n_group, k, m, iStart, iEnd;
Ipp32s f_group[64];
Ipp32s bufE[64];
Ipp32s bufG[64];
Ipp32s bufG2[64];
Ipp32s sfTmp, sfE, sfG, sfG2, sfNewGain;
Ipp32s sfETN;
/* E */
sfTmp = sbrPreProcAliasReduction(inBufE, bufE, 64, 3);
sfE = sfBufE - sfTmp;
/* G */
sfTmp = sbrPreProcAliasReduction(inBufG, bufG, 64, 3);
sfG = sfBufG - sfTmp;
/* G2 */
sfTmp = sbrPreProcAliasReduction(inBufG2, bufG2, 64, 3);
sfG2 = sfBufG2 - sfTmp;
n_group = sbrCalcGainGroups( s_mapped, degPatched, f_group, kx, M );
for (k = 0; k < n_group; k++) {
iStart = f_group[2 * k] - kx;
iEnd = f_group[2 * k + 1] - kx;
denum_64s = 0;
energ_total_64s = 0;
for (i = iStart; i < iEnd; i++) {
energ_total_64s += MUL64_SBR_64S(bufG2[i], bufE[i]);
denum_64s += (Ipp64s)bufE[i];
}
new_gain = 0;
sfNewGain = 0;
if( denum_64s )
{
Ipp32s num_32s, denum_32s;
Ipp32s outSf;
Ipp32s sfNum, sfDenum;
//------------------------
num_32s = sbriScale_64s32s(energ_total_64s, &sfNum);
denum_32s = sbriScale_64s32s(denum_64s, &sfDenum);
denum_32s = sbriInvWrap_32s_Sf(denum_32s, &outSf);
new_gain = MUL32_SBR_32S(num_32s, denum_32s);
sfNewGain = 60 - (sfE + sfDenum + outSf) + (sfG2+sfE + sfNum) - 32;
new_gain = sbriChangeScaleFactor(new_gain, sfNewGain, sfG2);
sfNewGain = sfG2;
//------------------------
}
for (m = iStart + kx; m < iEnd + kx; m++) {
if (m < M + kx - 1) {
alpha = IPP_MAX(degPatched[m], degPatched[m + 1]);
} else {
alpha = degPatched[m];
}
//bufG2[m - kx] = alpha * new_gain + (1.0f - alpha) * bufG2[m - kx];
bufG2[m - kx] = (MUL32_SBR_32S( alpha, new_gain ) << 3) +
(MUL32_SBR_32S((oneQ29 - alpha), bufG2[m - kx])<<3);
}
energ_total_new_64s = 0L;
for (i = iStart; i < iEnd; i++)
energ_total_new_64s += MUL64_SBR_64S(bufG2[i], bufE[i]);
sfETN = 0;
energ_total_new = 0;
if( energ_total_new_64s ) {
Ipp32s energ_total_new_32s, energ_total_32s;
Ipp32s outSf;
Ipp32s sfTmpNew, sfTmpOld;
energ_total_new_32s = sbriScale_64s32s(energ_total_new_64s, &sfTmpNew);
energ_total_32s = sbriScale_64s32s(energ_total_64s, &sfTmpOld);
energ_total_new_32s = sbriInvWrap_32s_Sf(energ_total_new_32s, &outSf);
energ_total_new = MUL32_SBR_32S(energ_total_32s, energ_total_new_32s);
sfETN = 60 - (sfG2+sfE + sfTmpNew + outSf) + (sfG2+sfE + sfTmpOld) - 32;
}
/* Ipp32f-point oeration */
for (i = iStart; i < iEnd; i++) {
#if 0
Ipp32f etn_32f = energ_total_new * pow(2, -sfETN );
Ipp32f buf_g2_i_32f = bufG2[i] * pow(2, -sfG2 );
Ipp32f bug_g_32f = (Ipp32f)(sqrt(etn_32f * buf_g2_i_32f));
bufG[i] = (Ipp32s)(bug_g_32f * pow(2,sfG) );
#else
Ipp32s inSf, outSf;// = sfETN + sfG2;
Ipp64s varG_64s = MUL64_SBR_64S(energ_total_new, bufG2[i]);
Ipp32s varG_32s = sbriScale_64s32s(varG_64s, &outSf);
inSf = sfETN + sfG2 + outSf;
varG_32s = sbriSqrtWrap_64s_Sfs(varG_32s, inSf, &outSf);
//bufG[i] = sbrChangeScaleFactor(varG_32s, outSf, sfG);
inBufG[i] = sbriChangeScaleFactor(varG_32s, outSf, sfBufG);
#endif
}
}
#if 0
/* convert */
for(i=0; i<64; i++){
inBufG[i] = sbrChangeScaleFactor(bufG[i], sfG, sfBufG);
}
#endif
return;
}
/********************************************************************/
static Ipp32s sbrSinAdd_LP_32s(Ipp32s* YRe, Ipp32s indxSine, Ipp32s tE0, Ipp32s m, Ipp32s kx, Ipp32s i,
Ipp32s* bufSM, Ipp32s M, Ipp32s* numSin)
{
Ipp32s fIndexSineMinus1 = 0;
Ipp32s fIndexSinePlus1 = 0;
Ipp32s num_sinusoids = *numSin;
Ipp32s ksi_middle = 0;
Ipp32s xScale = 0xFDE9E1B1;//(Ipp32s)(-0.00815f * pow(2, 32));
Ipp64s sumY_64s = 0L;
fIndexSineMinus1 = (indxSine + (i - 1) - RATE * tE0) & 3;
fIndexSinePlus1 = (indxSine + (i + 1) - RATE * tE0) & 3;
if (m == 0) {
//YRe[m + kx - 1] = -0.00815f * POW_MINUS_UNIT[kx - 1] * bufSM[0] * SIN_FI_RE[fIndexSinePlus1];
YRe[m + kx - 1] = MUL32_SBR_32S(xScale, bufSM[0]) * POW_MINUS_UNIT[kx - 1] * SIN_FI_RE[fIndexSinePlus1];
if (m < M - 1) {
//YRe[m + kx] += -0.00815f * POW_MINUS_UNIT[kx] * bufSM[1] * SIN_FI_RE[fIndexSinePlus1];
sumY_64s = YRe[m + kx] + MUL32_SBR_32S(xScale, bufSM[1]) * POW_MINUS_UNIT[kx] * SIN_FI_RE[fIndexSinePlus1];
if (sumY_64s >= (Ipp64s)IPP_MAX_32S )
YRe[m + kx] = IPP_MAX_32S;
else if( sumY_64s <= (Ipp64s)IPP_MIN_32S )
YRe[m + kx] = IPP_MIN_32S;
else
YRe[m + kx] = (Ipp32s)(sumY_64s);
}
} else if ((0 < m) && (m < M - 1) && (num_sinusoids < 16)) {
ksi_middle = (bufSM[m - 1] * SIN_FI_RE[fIndexSineMinus1] + bufSM[m + 1] * SIN_FI_RE[fIndexSinePlus1]);
//ksi_middle *= -0.00815f * POW_MINUS_UNIT[m + kx];
ksi_middle = MUL32_SBR_32S(xScale, ksi_middle) * POW_MINUS_UNIT[m + kx];
sumY_64s = YRe[m + kx] + ksi_middle;
if (sumY_64s >= (Ipp64s)IPP_MAX_32S )
YRe[m + kx] = IPP_MAX_32S;
else if( sumY_64s <= (Ipp64s)IPP_MIN_32S )
YRe[m + kx] = IPP_MIN_32S;
else
YRe[m + kx] = (Ipp32s)(sumY_64s);
//YRe[m + kx] += ksi_middle;
} else if ((m == M - 1) && (num_sinusoids < 16)) {
if (m > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -