📄 sbrdec_hf_gen_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) 2005 Intel Corporation. All Rights Reserved.//*//********************************************************************/#include<math.h>#include<string.h>#include "ipps.h"#include "ippac.h"#include "sbrdec_element.h"/********************************************************************/#ifndef UMC_MIN#define UMC_MIN(a,b) (((a) < (b)) ? (a) : (b))#endif#ifndef UMC_MAX#define UMC_MAX(a,b) (((a) > (b)) ? (a) : (b))#endif/********************************************************************/static Ipp32f SBR_TABLE_NEW_BW[4][4] = { {0.f, 0.6f, 0.9f, 0.98f}, {0.6f, 0.75f, 0.9f, 0.98f}, {0.f, 0.75f, 0.9f, 0.98f}, {0.f, 0.75f, 0.9f, 0.98f}};/********************************************************************/static IppStatus ownPredictCoef_SBR_R_32f_D2L(Ipp32f **pSrc, Ipp32f *pAlpha0, Ipp32f *pAlpha1, Ipp32f *pReflectCoef, Ipp32s k0, Ipp32s len);/********************************************************************/static Ipp32s sbrCalcAliasDegree(Ipp32f *ref, Ipp32f *deg, Ipp32s k0){ Ipp32s sign = 0; Ipp32s k; ippsZero_32f(deg, k0); ref[0] = 0.0f; deg[1] = 0.0f; for (k = 2; k < k0; k++) { if ((k % 2 == 0) && (ref[k] < 0.0f)) { sign = 1; } else if ((k % 2 == 1) && (ref[k] > 0.0f)) { sign = -1; } else { sign = 0; continue; } if (sign * ref[k - 1] < 0) { deg[k] = 1.0f; if (sign * ref[k - 2] > 0.0f) { deg[k - 1] = 1 - ref[k - 1] * ref[k - 1]; } } else { if (sign * ref[k - 2] > 0.0f) { deg[k] = 1 - ref[k - 1] * ref[k - 1]; } } } return 0; // OK}/********************************************************************/static Ipp32s sbrCalcChirpFactors(Ipp32s N_Q, Ipp32s *bs_invf_mode_prev, Ipp32s *bs_invf_mode, float *bwArray){ Ipp32s i; float tmpBw, newBw; for (i = 0; i < N_Q; i++) { newBw = SBR_TABLE_NEW_BW[bs_invf_mode_prev[i]][bs_invf_mode[i]]; if (newBw < bwArray[i]) tmpBw = 0.75f * newBw + 0.25f * bwArray[i]; else tmpBw = 0.90625f * newBw + 0.09375f * bwArray[i]; if (tmpBw < 0.015625f) bwArray[i] = 0.f; else bwArray[i] = tmpBw; bs_invf_mode_prev[i] = bs_invf_mode[i]; } return 0;}/********************************************************************/static Ipp32s sbrHFGenerator( /* * in data */ Ipp32f **XBufRe, Ipp32f **XBufIm, Ipp32f *vbwArray, Ipp32f *alpha_0Re, Ipp32f *alpha_0Im, Ipp32f *alpha_1Re, Ipp32f *alpha_1Im, sSbrDecCommon* pSbr, int ch, Ipp32f *deg, Ipp32f *degPatched, /* * out data */ Ipp32f **YBufRe, Ipp32f **YBufIm, Ipp32s mode){ Ipp32s i, x, q, k_0, k, p, g, l; Ipp32s l_start = RATE * pSbr->tE[ch][0]; Ipp32s l_end = RATE * pSbr->tE[ch][pSbr->L_E[ch]]; Ipp32f accYRe, accYIm; Ipp32f bwArr, bwArr2; Ipp32f cA0Re, cA0Im, cA1Re, cA1Im; if (mode == HEAAC_LP_MODE) { ippsZero_32f(degPatched, MAX_NUM_ENV_VAL); ippsCopy_32f(deg, degPatched, MAX_NUM_ENV_VAL); } for (i = 0; i < pSbr->numPatches; i++) { k_0 = 0; for (q = 0; q < i; q++) { k_0 += pSbr->patchNumSubbands[q]; } k_0 += pSbr->kx; for (x = 0; x < pSbr->patchNumSubbands[i]; x++) { k = k_0 + x; p = pSbr->patchStartSubband[i] + x; for (g = 0; g < pSbr->N_Q; g++) { if ((k >= pSbr->f_TableNoise[g]) && (k < pSbr->f_TableNoise[g + 1])) break; } if (mode == HEAAC_LP_MODE) { if (x == 0) degPatched[k] = 0.0f; else degPatched[k] = deg[p]; } bwArr = vbwArray[g]; /****************************************** * code may be optimized because: * if ( 0 == bwArr ) * pY[ l ][ k ] = pX[ l ][ p ] ONLY!!! * else * ippsPredictCoef_SBR_C_32f_D2L(...) * and code is written below, * but it is impossible because * ipp function works only k = [0, k0) * ******************************************/ bwArr2 = bwArr * bwArr; cA0Re = bwArr * alpha_0Re[p] ; cA0Im = bwArr * alpha_0Im[p] ; cA1Re = bwArr2 * alpha_1Re[p]; cA1Im = bwArr2 * alpha_1Im[p]; for (l = l_start; l < l_end; l++) { /* bw * Alpha0 * XLow[l-1] */ accYRe = XBufRe[l - 1 + 0][p] * cA0Re - XBufIm[l - 1 + 0][p] * cA0Im ; accYIm = XBufRe[l - 1 + 0][p] * cA0Im + XBufIm[l - 1 + 0][p] * cA0Re; /* bw^2 * Alpha1 * XLow[l-2] */ accYRe += XBufRe[l - 2 + 0][p] * cA1Re - XBufIm[l - 2 + 0][p] * cA1Im; accYIm += XBufRe[l - 2 + 0][p] * cA1Im + XBufIm[l - 2 + 0][p] * cA1Re; YBufRe[l + 0][k] = XBufRe[l - 0 + 0][p] + accYRe; YBufIm[l + 0][k] = XBufIm[l - 0 + 0][p] + accYIm; } } } if (mode == HEAAC_LP_MODE) { k_0 = 0; for (q = 0; q < pSbr->numPatches; q++) k_0 += pSbr->patchNumSubbands[q]; for (k = pSbr->kx + k_0; k < MAX_NUM_ENV_VAL; k++) degPatched[k] = 0; } return 0; // OK}/********************************************************************/Ipp32s sbrGenerationHF(Ipp32f **XBufRe, Ipp32f **XBufIm, Ipp32f **YBufRe, Ipp32f **XhighIm, sSbrDecCommon* sbr_com, Ipp32f* bwArray, Ipp32f* degPatched, Ipp32s ch, int decode_mode, Ipp32f* pWorkBuffer){ Ipp32f* alpha_0Re = pWorkBuffer; Ipp32f* alpha_1Re = pWorkBuffer + 1*MAX_NUM_ENV_VAL; Ipp32f* alpha_0Im = 0; Ipp32f* alpha_1Im = 0; Ipp32f* ref_coef = 0; Ipp32f* alias_degree = 0;/* if (decode_mode == HEAAC_LP_MODE) { ref_coef = pWorkBuffer + 2*MAX_NUM_ENV_VAL; alias_degree = pWorkBuffer + 3*MAX_NUM_ENV_VAL; }else{ alpha_0Im = pWorkBuffer + 2*MAX_NUM_ENV_VAL; alpha_1Im = pWorkBuffer + 3*MAX_NUM_ENV_VAL; }*/ /* it is correct because (ref_coef & alias_degree) OR (alpha_0Im & alpha_1Im) is used only */ alpha_0Im = ref_coef = pWorkBuffer + 2*MAX_NUM_ENV_VAL; alpha_1Im = alias_degree = pWorkBuffer + 3*MAX_NUM_ENV_VAL; ippsZero_32f(pWorkBuffer, 4*MAX_NUM_ENV_VAL); sbrCalcChirpFactors(sbr_com->N_Q, &(sbr_com->bs_invf_mode_prev[ch][0]), &(sbr_com->bs_invf_mode[ch][0]), bwArray); if (decode_mode == HEAAC_LP_MODE) { ownPredictCoef_SBR_R_32f_D2L(XBufRe, alpha_0Re, alpha_1Re, ref_coef, sbr_com->k0, NUM_TIME_SLOTS * RATE + 6); sbrCalcAliasDegree(ref_coef, alias_degree, sbr_com->k0); } else { ippsPredictCoef_SBR_C_32f_D2L(XBufRe, XBufIm, alpha_0Re, alpha_0Im, alpha_1Re, alpha_1Im, sbr_com->k0, NUM_TIME_SLOTS * RATE + 6); } sbrHFGenerator(XBufRe+SBR_TIME_HFADJ, XBufIm+SBR_TIME_HFADJ, bwArray, alpha_0Re, alpha_0Im, alpha_1Re, alpha_1Im, sbr_com, ch, alias_degree, degPatched, YBufRe+SBR_TIME_HFADJ, XhighIm+SBR_TIME_HFADJ, decode_mode); return 0; // OK}/********************************************************************/IppStatus ownPredictCoef_SBR_R_32f_D2L(Ipp32f **pSrc, Ipp32f *pAlpha0, Ipp32f *pAlpha1, Ipp32f *pReflectCoef, Ipp32s k0, Ipp32s len) { const Ipp32s TIME_HF_ADJ = 2; Ipp32s i, j, k, n; const Ipp32f rel = 1.f / (1.f + 1e-6f); Ipp32f fi[3][3]; Ipp32f d; Ipp32f** ppX = pSrc + TIME_HF_ADJ; for (k = 0; k < k0; k++) { fi[0][0] = fi[0][1] = fi[0][2] = fi[1][0] = fi[1][1] = fi[1][2] = fi[2][0] = fi[2][1] = fi[2][2] = 0.f;/* * auto correlation */ for (n = 0; n < len; n++) { i = 0; j = 1; fi[0][1] += ppX[n - i][k] * ppX[n - j][k]; i = 0; j = 2; fi[0][2] += ppX[n - i][k] * ppX[n - j][k]; i = 1; j = 1; fi[1][1] += ppX[n - i][k] * ppX[n - j][k]; i = 1; j = 2; fi[1][2] += ppX[n - i][k] * ppX[n - j][k]; i = 2; j = 2; fi[2][2] += ppX[n - i][k] * ppX[n - j][k]; } d = fi[1][1] * fi[2][2] - rel * fi[1][2] * fi[1][2];/* * pAlpha1 */ if ((Ipp64f)d * d > 0.f) { /* if (d != 0) */ pAlpha1[k] = (fi[0][1] * fi[1][2] - fi[0][2] * fi[1][1]) * (1.f / d); } else { pAlpha1[k] = 0.f; }/* * pAlpha0 */ if (fi[1][1] > 0.f) { /* if (fi[1][1] != 0) */ pAlpha0[k] = -(fi[0][1] + pAlpha1[k] * fi[1][2]) * (1.f / fi[1][1]); } else { pAlpha0[k] = 0.f; } if (((pAlpha1[k] * pAlpha1[k]) >= 16.f) || ((pAlpha0[k] * pAlpha0[k]) >= 16.f)) { pAlpha1[k] = pAlpha0[k] = 0.f; } if (fi[1][1] == 0.0f) { pReflectCoef[k] = 0.0f; } else { pReflectCoef[k] = UMC_MIN(UMC_MAX(-fi[0][1] / fi[1][1], -1), 1); } } return ippStsNoErr;}/********************************************************************//* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -