📄 sbr_dec_hf_gen_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<string.h>
#include "ipps.h"
#include "ippac.h"
#include "sbr_settings.h"
#include "sbr_dec_struct.h"
#include "sbr_dec_settings_int.h"
#include "sbr_dec_own_int.h"
/********************************************************************/
/* Q(31) */
static Ipp32s SBR_TABLE_NEW_BW_INT_Q31[4][4] = {
{0x00000000, 0x4ccccccd, 0x73333333, 0x7d70a3d7},
{0x4ccccccd, 0x60000000, 0x73333333, 0x7d70a3d7},
{0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
{0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
};
/********************************************************************
*
* OutPut data: iBwArray, Q(14)
********************************************************************/
static Ipp32s sbrCalcChirpFactors(Ipp32s N_Q, Ipp32s *bs_invf_mode_prev,
Ipp32s *bs_invf_mode, Ipp32s *iBwArray )
{
Ipp32s i;
Ipp32s iNewBw, iTmpBw;
for (i = 0; i < N_Q; i++) {
iNewBw = SBR_TABLE_NEW_BW_INT_Q31[bs_invf_mode_prev[i]][bs_invf_mode[i]];
if (iNewBw < iBwArray[i])
iTmpBw =
MUL32_SBR_32S(0x60000000, iNewBw) +
MUL32_SBR_32S(0x20000000, iBwArray[i]);
else
iTmpBw =
MUL32_SBR_32S(0x74000000, iNewBw) +
MUL32_SBR_32S(0x0C000000, iBwArray[i]);
iTmpBw = iTmpBw << 1;
iBwArray[i] = iTmpBw;
if (iTmpBw < 0x02000000)
iBwArray[i] = 0;
bs_invf_mode_prev[i] = bs_invf_mode[i];
}
return 0;
}
/********************************************************************/
static Ipp32s sbrCalcAliasDegree(Ipp32s *ref, Ipp32s *deg, Ipp32s k0)
{
Ipp32s sign = 0;
Ipp32s k;
ippsZero_32s(deg, k0);
ref[0] = 0;
deg[1] = 0;
for (k = 2; k < k0; k++) {
if ((k % 2 == 0) && (ref[k] < 0)) {
sign = 1;
} else if ((k % 2 == 1) && (ref[k] > 0)) {
sign = -1;
} else {
sign = 0;
continue;
}
if (sign * ref[k - 1] < 0) {
deg[k] = 1 << 29;
if (sign * ref[k - 2] > 0) {
deg[k - 1] = (1 << 29) - (MUL32_SBR_32S( ref[k - 1] << 1, ref[k - 1] << 1) <<1 );
}
} else {
if (sign * ref[k - 2] > 0) {
//deg[k] = 1 - ref[k - 1] * ref[k - 1];
deg[k] = (1 << 29) - (MUL32_SBR_32S( ref[k - 1] << 1, ref[k - 1] << 1) <<1 );
}
}
}
return 0; // OK
}
/********************************************************************/
static Ipp32s sbrHFGeneratorHQ(
/*
* in data
*/
Ipp32sc** iXBuf,
Ipp32s *vbwArray, sSBRDecComState * pSbr,
Ipp32s l_start, Ipp32s l_end,
/*
* out data
*/
Ipp32sc** iYBuf)
{
/* values */
Ipp32s i, x, q, k_0, k, p, g, l;
Ipp32s iBwAr, iBwAr2;
Ipp32sc sumY;//sumYRe, sumYIm;
Ipp32s icA0Re, icA0Im, icA1Re, icA1Im;
Ipp32sc** pX = iXBuf + SBR_TIME_HFADJ;
Ipp32sc** pY = iYBuf + SBR_TIME_HFADJ;
Ipp8u isNonCalcPredictCoef[64];
Ipp32sc a0Coefs[64], a1Coefs[64];
/* reset values */
ippsSet_8u(1, isNonCalcPredictCoef, 64);
/* code */
for (i = 0; i < pSbr->sbrFreqTabsState.numPatches; i++) {
k_0 = 0;
for (q = 0; q < i; q++) {
k_0 += pSbr->sbrFreqTabsState.patchNumSubbandsTab[q];
}
k_0 += pSbr->kx;
for (x = 0; x < pSbr->sbrFreqTabsState.patchNumSubbandsTab[i]; x++) {
k = k_0 + x;
p = pSbr->sbrFreqTabsState.patchStartSubbandTab[i] + x;
for (g = 0; g < pSbr->sbrFreqTabsState.nNoiseBand; g++) {
if ((k >= pSbr->sbrFreqTabsState.fNoiseBandTab[g]) && (k < pSbr->sbrFreqTabsState.fNoiseBandTab[g + 1]))
break;
}
iBwAr = vbwArray[g];// Q(31)
if ( iBwAr > 0) {
/* Predict */
if ( isNonCalcPredictCoef[p] ) {
ippsPredictOneCoef_SBRHQ_32sc_D2L(iXBuf, &a0Coefs[p], &a1Coefs[p], p, 38);
isNonCalcPredictCoef[p] = 0;
}
// Q(31) * Q(31) * Q(-32) = Q(30)
iBwAr2 = MUL32_SBR_32S(vbwArray[g], vbwArray[g]);
iBwAr2 <<= 1; // Q(31)
// BwArray
// Q(31) * Q(29) * Q(-32) = Q(28)
icA0Re = MUL32_SBR_32S(iBwAr, a0Coefs[p].re);
// Q(31) * Q(29) * Q(-32) = Q(28)
icA0Im = MUL32_SBR_32S(iBwAr, a0Coefs[p].im);
// Q(31) * Q(29) * Q(-32) = Q(28)
icA1Re = MUL32_SBR_32S(iBwAr2, a1Coefs[p].re);
// Q(31) * Q(29) * Q(-32) = Q(28)
icA1Im = MUL32_SBR_32S(iBwAr2, a1Coefs[p].im);
for (l = l_start; l < l_end; l++) {
/*
* bw * Alpha0 * XLow[l-1] = Q(28) * Q(5) * Q(-32) = Q(1)
*/
sumY.re =
MUL32_SBR_32S(pX[l - 1][p].re,icA0Re) -
MUL32_SBR_32S(pX[l - 1][p].im, icA0Im);
sumY.im =
MUL32_SBR_32S(pX[l - 1][p].re,icA0Im) +
MUL32_SBR_32S(pX[l - 1][p].im, icA0Re);
/*
* bw^2 * Alpha1 * XLow[l-2] = Q(28) * Q(5) * Q(-32) = Q(1)
*/
sumY.re +=
MUL32_SBR_32S(pX[l - 2][p].re,icA1Re) -
MUL32_SBR_32S(pX[l - 2][p].im, icA1Im);
sumY.im +=
MUL32_SBR_32S(pX[l - 2][p].re, icA1Im) +
MUL32_SBR_32S(pX[l - 2][p].im, icA1Re);
/*
* this check may be improved in the future
*/
if (abs(sumY.re) < (((1 << 30) - 1) >> 4) &&
abs(sumY.im) < (((1 << 30) - 1) >> 4)) {
sumY.re <<= 4;
sumY.im <<= 4;
} else {
sumY.re = (sumY.re > 0) ? (1 << 30) - 1 : -(1 << 30);
sumY.im = (sumY.im > 0) ? (1 << 30) - 1 : -(1 << 30);
}
pY[l][k].re = pX[l - 0][p].re + sumY.re;
pY[l][k].im = pX[l - 0][p].im + sumY.im;
}// for (l = l_start
} else { //if (iBwAr == 0)
for (l = l_start; l < l_end; l++) {
pY[l][k].re = pX[l - 0][p].re;
pY[l][k].im = pX[l - 0][p].im;
}
}// endif(bwArr > 0) ?
}//for (x = 0
}// for (i = 0;
return 0; // OK
}
/********************************************************************/
static Ipp32s sbrHFGeneratorLP(
/* in data */
Ipp32s** piXBufRe,
/* out data */
Ipp32s** piYBufRe,
Ipp32s* iBwArray,
sSBRDecComState* pSbr,
Ipp32s l_start,
Ipp32s l_end,
Ipp32s *deg,
Ipp32s *degPatched)
{
Ipp32s i, x, q, k_0, k, p, g, l;
Ipp32s iBwAr, iBwAr2;
Ipp32s sumYRe;
Ipp32s icA0Re, icA1Re;
Ipp32s coefA0Re, coefA1Re, iRefCoef;
Ipp32s** pXRe = piXBufRe + SBR_TIME_HFADJ;
Ipp32s** pYRe = piYBufRe + SBR_TIME_HFADJ;
sSBRFeqTabsState* pFTState = &(pSbr->sbrFreqTabsState);
// ippsZero_32f(degPatched, MAX_NUM_ENV_VAL);
for (i = 0; i < pFTState->numPatches; i++) {
k_0 = 0;
for (q = 0; q < i; q++) {
k_0 += pFTState->patchNumSubbandsTab[q];
}
k_0 += pSbr->kx;
for (x = 0; x < pFTState->patchNumSubbandsTab[i]; x++) {
k = k_0 + x;
p = pFTState->patchStartSubbandTab[i] + x;
for (g = 0; g < pFTState->nNoiseBand; g++) {
if ((k >= pFTState->fNoiseBandTab[g]) && (k < pFTState->fNoiseBandTab[g + 1]))
break;
}
iBwAr = iBwArray[g];// Q(31)
if ( iBwAr > 0 ) {
// if( ! isPredict[p] )
{
//ownPredictOneCoef_SBR_R_32s_D2L(piXBufRe, &coefA0Re, &coefA1Re, &iRefCoef, p, 38);
ippsPredictOneCoef_SBRLP_32s_D2L(piXBufRe, &coefA0Re, &coefA1Re, &iRefCoef, p, 38, 1);
}
// Q(31) * Q(31) * Q(-32) = Q(30)
iBwAr2 = MUL32_SBR_32S(iBwAr, iBwAr);
iBwAr2 <<= 1; // Q(31)
// BwArray
// Q(31) * Q(29) * Q(-32) = Q(28)
icA0Re = MUL32_SBR_32S(iBwAr, coefA0Re);
// Q(31) * Q(29) * Q(-32) = Q(28)
icA1Re = MUL32_SBR_32S(iBwAr2, coefA1Re);
for (l = l_start; l < l_end; l++) {
/*
* bw * Alpha0 * XLow[l-1] = Q(28) * Q(5) * Q(-32) = Q(1)
*/
sumYRe = MUL32_SBR_32S(pXRe[l - 1][p],icA0Re);
/*
* bw^2 * Alpha1 * XLow[l-2] = Q(28) * Q(5) * Q(-32) = Q(1)
*/
sumYRe += MUL32_SBR_32S(pXRe[l - 2][p],icA1Re);
/*
* this check may be improved in the future
*/
if ( abs(sumYRe) < (((1 << 30) - 1) >> 4) ) {
sumYRe <<= 4;
} else {
sumYRe = (sumYRe > 0) ? (1 << 30) - 1 : -(1 << 30);
}
pYRe[l][k] = pXRe[l - 0][p] + sumYRe;
//pYBufRe[l+2][k] = pYRe[l][k] / 32.f ;
}// for (l = l_start
}else{ //if( bwArr == 0)
for (l = l_start; l < l_end; l++) {
pYRe[l][k] = pXRe[l - 0][p];
//pYBufRe[l+2][k] = pYRe[l][k] / 32.f ;
}
}
/*-------------------------------------------------------------*/
//if (mode == HEAAC_LP_MODE) {
if (x == 0)
degPatched[k] = 0;
else
degPatched[k] = deg[p];
// }
/*-------------------------------------------------------------*/
}
}
//if (mode == HEAAC_LP_MODE) {
k_0 = 0;
for (q = 0; q < pFTState->numPatches; q++)
k_0 += pFTState->patchNumSubbandsTab[q];
for (k = pSbr->kx + k_0; k < 64; k++)
degPatched[k] = 0;
//}
return 0; // OK
}
/********************************************************************/
Ipp32s sbriGenerationHF(Ipp32s** iXBuf,
Ipp32s** iYBuf,
sSBRDecComState * comState, Ipp32s *bwArray,
Ipp32s *degPatchedCoefs, Ipp32s ch, Ipp32s decode_mode)
{
Ipp32s refCoefs[64];
Ipp32s a0Coefs[64];
Ipp32s a1Coefs[64];
Ipp32s degCoefs[64];
Ipp32s l_start = RATE * comState->sbrFIState[ch].bordersEnv[0];
Ipp32s l_end = RATE * comState->sbrFIState[ch].bordersEnv[comState->sbrFIState[ch].nEnv];
sbrCalcChirpFactors(comState->sbrFreqTabsState.nNoiseBand, &(comState->bs_invf_mode_prev[ch][0]),
&(comState->bs_invf_mode[ch][0]), bwArray);
if (HEAAC_HQ_MODE == decode_mode)
sbrHFGeneratorHQ( (Ipp32sc**)iXBuf, bwArray, comState, l_start, l_end, (Ipp32sc**)iYBuf);
else { //if (HEAAC_LP_MODE == decode_mode)
ippsZero_32s(degPatchedCoefs, 64);
{
Ipp32s k;
for(k=0; k<comState->k0; k++)
{
ippsPredictOneCoef_SBRLP_32s_D2L(iXBuf, &a0Coefs[k], &a1Coefs[k], &refCoefs[k], k, 38, 0);
}
}
sbrCalcAliasDegree(refCoefs, degCoefs, comState->k0);
sbrHFGeneratorLP(iXBuf, iYBuf, bwArray, comState, l_start, l_end,
degCoefs, degPatchedCoefs);
}
return 0; // OK
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -