📄 sbrdec_hf_adjust_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 "ipps.h"#include "ippsr.h"#include "sbrdec_element.h"#include "sbrdec_tables.h"#include "sbrdec_api_fp.h"#include <stdio.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 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 Ipp32f EPS0 = 1e-12f;/********************************************************************/static const Ipp32s SIN_FI_RE[4] = { 1, 0, -1, 0 };/********************************************************************/static const Ipp32s SIN_FI_IM[4] = { 0, 1, 0, -1 };/********************************************************************/static const Ipp32f TABLE_LIMIT_GAIN[4] = { 0.70795f, 1.f, 1.41254f, 1e10f };/********************************************************************/static const Ipp32f hSmoothFilter[] = { 0.03183050093751f, 0.11516383427084f, 0.21816949906249f, 0.30150283239582f, 0.33333333333333f};/********************************************************************/static void sbrAliasReduction(Ipp32f *degPatched, Ipp32f *bufECurr, Ipp32f *bufG, Ipp32s *s_mapped, Ipp32s kx, Ipp32s M){ Ipp32f denum, energ_total, new_gain, energ_total_new, alpha; Ipp32s grouping, i, n_group, k, m, i_start, i_end; Ipp32s f_group[64];/* -------------------------------- calculation gain groups ---------------------------- */ i = 0; grouping = 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 = (Ipp32s)(i / 2.0f);/* -------------------------------- aliasing reduction ---------------------------- */ for (k = 0; k < n_group; k++) { i_start = f_group[2 * k] - kx; i_end = f_group[2 * k + 1] - kx; denum = EPS0; energ_total = 0.0f; for (i = i_start; i < i_end; i++) { energ_total += bufG[i] * bufG[i] * bufECurr[i]; denum += bufECurr[i]; } new_gain = energ_total / (denum); energ_total_new = EPS0; for (m = f_group[2 * k]; m < f_group[2 * k + 1]; m++) { if (m < M + kx - 1) { alpha = UMC_MAX(degPatched[m], degPatched[m + 1]); } else { alpha = degPatched[m]; } bufG[m - kx] = alpha * new_gain + (1.0f - alpha) * bufG[m - kx] * bufG[m - kx]; } for (i = f_group[2 * k] - kx; i < f_group[2 * k + 1] - kx; i++) energ_total_new += bufG[i] * bufECurr[i]; energ_total_new = energ_total / energ_total_new; for (i = i_start; i < i_end; i++) { bufG[i] = (Ipp32f)(sqrt(energ_total_new * bufG[i])); } }}/********************************************************************/static Ipp32s sbrUpdate_lA(Ipp32s bs_pointer, Ipp32s bs_frame_class, Ipp32s L_E){ Ipp32s table_lA[3][3] = { {-1, -1, -1}, {-1, L_E + 1 - bs_pointer, -1}, {-1, L_E + 1 - bs_pointer, bs_pointer - 1} }; Ipp32s indx1, indx2; Ipp32s lA; if ((bs_pointer > 1) || (bs_pointer < 0)) indx1 = 2; else indx1 = bs_pointer; if (bs_frame_class == VARVAR) indx2 = 1; else indx2 = bs_frame_class; lA = table_lA[indx1][indx2]; return lA;}/********************************************************************/void sbrAdjustmentHF(Ipp32f **YBufRe, Ipp32f **YBufIm, Ipp32f* vecEnvOrig, Ipp32f* vecNoiseOrig, Ipp32f BufGain[][MAX_NUM_ENV_VAL], Ipp32f BufNoise[][MAX_NUM_ENV_VAL], sSbrDecCommon* sbr_com, Ipp32f *degPatched, Ipp8u *WorkBuffer, Ipp32s reset, Ipp32s ch, Ipp32s decode_mode){ /* VALUES */ Ipp32s k, m, n, pos, kl, kh, l, p, i, j, delta_step, delta; Ipp32f energ, sumEOrig, sumECurr, g_max_temp, gainMax, denum, boost_gain, gainFilt, noiseFilt; Ipp32s iStart, iEnd; Ipp32s nResolution; Ipp32f mulQ = 0.0f; Ipp32f *bufSM; Ipp32f *bufQM; Ipp32f *bufECurr; Ipp32f *bufEOrig; Ipp32f *bufG; Ipp32f bufQMapped[64]; Ipp32f sumEWoInterpol = 0.0f; Ipp32f LimiterGains = TABLE_LIMIT_GAIN[sbr_com->bs_limiter_gains]; Ipp32s interpolation = sbr_com->bs_interpol_freq; Ipp32s fIndexNoise = 0; Ipp32s fIndexSine = 0; Ipp32s fIndexSineMinus1 = 0; Ipp32s fIndexSinePlus1 = 0; Ipp32f ksi_middle = 0; Ipp32s num_sinusoids = 0; Ipp32s s_mapped[64]; Ipp32s hSmoothLen = (sbr_com->bs_smoothing_mode == 0) ? 4 : 0; Ipp32s hSmoothLenConst = hSmoothLen; Ipp32s kx = sbr_com->kx; Ipp32s M = sbr_com->M; Ipp32s LE = sbr_com->L_E[ch]; Ipp32s NQ = sbr_com->N_Q; Ipp32s lA = 0; Ipp32s offset_32f = 64 * sizeof(Ipp32f); Ipp32s *sineIndxMap; Ipp32s *sineIndxMapPrev; Ipp32s *pFreqTbl; Ipp32s* F[2]; Ipp32s resolution[2]; Ipp32f** YRe = YBufRe + SBR_TIME_HFADJ; Ipp32f** YIm = YBufIm + SBR_TIME_HFADJ; /* CODES */ F[0] = sbr_com->f_TableLow; F[1] = sbr_com->f_TableHigh; resolution[0] = sbr_com->N_low; resolution[1] = sbr_com->N_high;/* set memory */ bufSM = (Ipp32f *)(WorkBuffer + 0 * offset_32f); bufQM = (Ipp32f *)(WorkBuffer + 1 * offset_32f); bufECurr = (Ipp32f *)(WorkBuffer + 2 * offset_32f); bufEOrig = (Ipp32f *)(WorkBuffer + 3 * offset_32f); bufG = (Ipp32f *)(WorkBuffer + 4 * offset_32f); sineIndxMap = (Ipp32s *)(WorkBuffer + 5 * offset_32f); sineIndxMapPrev = sbr_com->S_index_mapped_prev[ch]; if (reset) { sbr_com->FlagUpdate[ch] = 1; sbr_com->indexNoise[ch] = 0; } ippsZero_8u((Ipp8u *)sineIndxMap, 64 * sizeof(Ipp32s)); for (i = 0; i < sbr_com->N_high; i++) { m = (sbr_com->f_TableHigh[i + 1] + sbr_com->f_TableHigh[i]) >> 1; sineIndxMap[m - kx] = sbr_com->bs_add_harmonic[ch][i]; } lA = sbrUpdate_lA(sbr_com->bs_pointer[ch], sbr_com->bs_frame_class[ch], sbr_com->L_E[ch]);/* main loop */ for (l = 0; l < LE; l++) { for (k = 0; k < sbr_com->L_Q[ch]; k++) { if (sbr_com->tE[ch][l] >= sbr_com->tQ[ch][k] && sbr_com->tE[ch][l + 1] <= sbr_com->tQ[ch][k + 1]) break; } for (i = 0; i < NQ; i++) { for (m = sbr_com->f_TableNoise[i]; m < sbr_com->f_TableNoise[i + 1]; m++) { bufQMapped[m - kx] = vecNoiseOrig[sbr_com->vSizeNoise[ch][k]+i]; } } delta = (l == lA || l == sbr_com->lA_prev[ch]) ? 1 : 0; if ( decode_mode == HEAAC_HQ_MODE) hSmoothLen = (delta ? 0 : hSmoothLenConst); else hSmoothLen = 0;/* -------------------------------- Estimation envelope ---------------------------- */ pos = 0; nResolution = resolution[sbr_com->r[ch][l]]; pFreqTbl = F[sbr_com->r[ch][l]]; iStart = RATE * sbr_com->tE[ch][l]; iEnd = RATE * sbr_com->tE[ch][1 + l]; for (p = 0; p < nResolution; p++) { kl = pFreqTbl[p]; kh = pFreqTbl[p + 1]; delta_step = 0; sumEWoInterpol = 0.0f; for (j = kl; j < kh; j++) { energ = 0.0f; for (i = iStart; i < iEnd; i++) { if (decode_mode == HEAAC_LP_MODE) energ += YRe[i][j] * YRe[i][j]; else energ += YRe[i][j] * YRe[i][j] + YIm[i][j] * YIm[i][j]; } delta_step = (sineIndxMap[pos] && (l >= lA || sineIndxMapPrev[pos + kx])) ? 1 : delta_step; bufECurr[pos] = energ / (iEnd - iStart); if (!interpolation) sumEWoInterpol += bufECurr[pos] / (kh - kl); pos++; } for (k = pos - (kh - kl); k < pos; k++) { bufSM[k] = 0; bufEOrig[k] = vecEnvOrig[sbr_com->vSizeEnv[ch][l]+p]; if (!interpolation) bufECurr[k] = sumEWoInterpol; mulQ = 1.0f / (1.0f + bufQMapped[k]); if (decode_mode == HEAAC_LP_MODE) { bufECurr[k] *= 2.0f; if (delta_step) s_mapped[k - pos + kh - kx] = 1; else s_mapped[k - pos + kh - kx] = 0; } if (delta_step) { bufG[k] = (Ipp32f)sqrt(bufEOrig[k] * mulQ * bufQMapped[k] / (bufECurr[k] + 1)); if (sineIndxMap[k] && (l >= lA || sineIndxMapPrev[k + kx])) bufSM[k] = (Ipp32f)sqrt(bufEOrig[k] * mulQ); } else if (delta) bufG[k] = (Ipp32f)sqrt(bufEOrig[k] / (bufECurr[k] + 1)); else bufG[k] = (Ipp32f)sqrt(bufEOrig[k] * mulQ / (bufECurr[k] + 1)); bufQM[k] = (Ipp32f)sqrt(bufEOrig[k] * mulQ * bufQMapped[k]); } }/* -------------------------------- Calculation of gain ---------------------------- */ for (k = 0; k < sbr_com->N_L; k++) { sumEOrig = sumECurr = EPS0; for (i = sbr_com->f_TableLim[k] - kx; i < sbr_com->f_TableLim[k + 1] - kx; i++) { sumEOrig += bufEOrig[i]; sumECurr += bufECurr[i]; } g_max_temp = (Ipp32f)sqrt(sumEOrig / sumECurr) * LimiterGains; gainMax = UMC_MIN(1.0e5f, g_max_temp); denum = EPS0; for (i = sbr_com->f_TableLim[k] - kx; i < sbr_com->f_TableLim[k + 1] - kx; i++) { if (gainMax <= bufG[i]) { bufQM[i] = bufQM[i] * (gainMax / bufG[i]); bufG[i] = gainMax; } denum += bufG[i] * bufG[i] * bufECurr[i] + bufSM[i] * bufSM[i]; if (!(bufSM[i] != 0.0f || delta)) denum += bufQM[i] * bufQM[i]; } boost_gain = (Ipp32f)sqrt(sumEOrig / denum); boost_gain = UMC_MIN(boost_gain, 1.584893192f); for (i = sbr_com->f_TableLim[k] - kx; i < sbr_com->f_TableLim[k + 1] - kx; i++) { bufG[i] *= boost_gain; bufQM[i] *= boost_gain; bufSM[i] *= boost_gain; } } if (decode_mode == HEAAC_LP_MODE) { sbrAliasReduction(degPatched, bufECurr, bufG, s_mapped, kx, M); }/* -------------------------------- Assembling ---------------------------- */ if (sbr_com->FlagUpdate[ch]) { for (n = 0; n < 4; n++) { ippsCopy_32f(bufG, BufGain[n], M); ippsCopy_32f(bufQM, BufNoise[n], M); } sbr_com->FlagUpdate[ch] = 0; } for (i = iStart; i < iEnd; i++) { for (m = 0; m < M; m++) { BufGain[4][m] = bufG[m]; BufNoise[4][m] = bufQM[m]; if (decode_mode == HEAAC_LP_MODE) { num_sinusoids = 0; } gainFilt = noiseFilt = 0.0f; if (hSmoothLen) { for (n = 0; n <= 4; n++) { gainFilt += BufGain[n][m] * hSmoothFilter[n]; noiseFilt += BufNoise[n][m] * hSmoothFilter[n]; } } else { gainFilt = BufGain[4][m]; noiseFilt = BufNoise[4][m]; } if (bufSM[m] != 0 || delta) noiseFilt = 0; fIndexNoise = (sbr_com->indexNoise[ch] + (i - RATE * sbr_com->tE[ch][0]) * M + m + 1) & 511; fIndexSine = (sbr_com->indexSine[ch] + i - RATE * sbr_com->tE[ch][0]) & 3; if (decode_mode == HEAAC_LP_MODE) { YRe[i][m + kx] = YRe[i][m + kx] * gainFilt + noiseFilt * SBR_TABLE_V[0][fIndexNoise] + bufSM[m] * SIN_FI_RE[fIndexSine]; } else { YRe[i][m + kx] = YRe[i][m + kx] * gainFilt + noiseFilt * SBR_TABLE_V[0][fIndexNoise] + bufSM[m] * SIN_FI_RE[fIndexSine]; YIm[i][m + kx] = YIm[i][m + kx] * gainFilt + noiseFilt * SBR_TABLE_V[1][fIndexNoise] + bufSM[m] * POW_MINUS_UNIT[m + kx] * SIN_FI_IM[fIndexSine]; } if (decode_mode == HEAAC_LP_MODE) { fIndexSineMinus1 = (sbr_com->indexSine[ch] + (i - 1) - RATE * sbr_com->tE[ch][0]) & 3; fIndexSinePlus1 = (sbr_com->indexSine[ch] + (i + 1) - RATE * sbr_com->tE[ch][0]) & 3; if (m == 0) { YRe[i][m + kx - 1] = -0.00815f * POW_MINUS_UNIT[kx - 1] * bufSM[0] * SIN_FI_RE[fIndexSinePlus1]; if (m < M - 1) { YRe[i][m + kx] += -0.00815f * POW_MINUS_UNIT[kx] * bufSM[1] * SIN_FI_RE[fIndexSinePlus1]; } } 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]; YRe[i][m + kx] += ksi_middle; } else if ((m == M - 1) && (num_sinusoids < 16)) { if (m > 0) { YRe[i][m + kx] += -0.00815f * POW_MINUS_UNIT[m + kx] * bufSM[m - 1] * SIN_FI_RE[fIndexSineMinus1]; } if (M + kx < 64) { YRe[i][m + kx + 1] = -0.00815f * POW_MINUS_UNIT[m + kx + 1] * bufSM[m] * SIN_FI_RE[fIndexSineMinus1]; } } if (bufSM[m]) num_sinusoids++; } // end if ( *(pSbr->ModeDecodeHEAAC) == HEAAC_LP_MODE ) } // end for ( m = 0; m < M; m++ ) for (n = 0; n < 4; n++) { ippsCopy_32f(BufGain[n + 1], BufGain[n], 64); ippsCopy_32f(BufNoise[n + 1], BufNoise[n], 64); } } // end for (i = iStart; i < iEnd; i++) // } /* end main loop *//* -------------------------------- update ---------------------------- */ ippsCopy_8u((const Ipp8u *)sineIndxMap, (Ipp8u *)&(sineIndxMapPrev[kx]), (64 - kx) * sizeof(Ipp32s)); if (lA == LE) sbr_com->lA_prev[ch] = 0; else sbr_com->lA_prev[ch] = -1; sbr_com->L_E_prev[ch] = sbr_com->L_E[ch]; sbr_com->L_Q_prev[ch] = sbr_com->L_Q[ch]; sbr_com->indexNoise[ch] = fIndexNoise; sbr_com->indexSine[ch] = (fIndexSine + 1) & 3;}/********************************************************************//* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -