📄 sbr_dec_decoder_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-2007 Intel Corporation. All Rights Reserved.
//
*/
#include <ipps.h>
#include <ippac.h>
#include <math.h>
#include "sbr_settings.h"
#include "sbr_dec_struct.h"
#include "sbr_dec_api_int.h"
#include "sbr_dec_tabs_int.h"
#include "sbr_dec_own_int.h"
/********************************************************************/
#ifndef ID_SCE
#define ID_SCE 0x0
#endif
#ifndef ID_CPE
#define ID_CPE 0x1
#endif
/********************************************************************/
static Ipp32s sbrPassiveUpsampling(Ipp32s* XBuf,
Ipp32s* iZBuf,
Ipp32s mode);
/********************************************************************/
static Ipp32s sbrActiveUpsampling(Ipp32s* XBuf,
Ipp32s* iYBuf,
Ipp32s xoverBand,
Ipp32s* iZBuf,
Ipp32s mode);
/********************************************************************/
/* Set HF subbands to zero */
Ipp32s sbriCleanHFBand(Ipp32s** pYBuf, Ipp32s startBand, Ipp32s stopBand, Ipp32s mode);
/********************************************************************/
static Ipp32s sbrUpDateBands(Ipp32s** ppSrc );
/********************************************************************/
static Ipp32s sbrUpdateAmpRes(Ipp32s bs_frame_class, Ipp32s L_E, Ipp32s bs_amp_res)
{
if ((bs_frame_class == FIXFIX) && (L_E == 1))
bs_amp_res = 0;
return bs_amp_res;
}
/********************************************************************/
Ipp32s sbridecReset(sSBRBlock* pSbr)
{
IppStatus status;
sbrdecResetCommon( &(pSbr->comState) );
// FIXED-POINT
status = ippsZero_32s(pSbr->wsState.iBufGain[0][0], 2*MAX_NUM_ENV*MAX_NUM_ENV_VAL);
status = ippsZero_32s(pSbr->wsState.iBufNoise[0][0], 2*MAX_NUM_ENV*MAX_NUM_ENV_VAL);
status = ippsZero_32s(pSbr->wsState.bwArray[0], 2*MAX_NUM_NOISE_VAL);
return 0;//OK
}
/********************************************************************/
void sbriDecoderGetSize(Ipp32s *pSize)
{
Ipp32s Size32 = (32) * (NUM_TIME_SLOTS * RATE + SBR_TIME_HFGEN);
Ipp32s Size64 = (64) * (NUM_TIME_SLOTS * RATE + SBR_TIME_HFGEN);
pSize[0] = (((Size32 + Size64) * 2) * sizeof(Ipp32s) * 2) * CH_MAX;
}
/********************************************************************/
void sbriInitDecoder(sSBRBlock* pState[CH_MAX], void* pMem)
{
Ipp32s ch, i, j;
sSBRBlock *pBlock;
Ipp32s *pData = (Ipp32s *)pMem;
Ipp32s bufLen;
Ipp32s Size32 = (32) * (NUM_TIME_SLOTS * RATE + SBR_TIME_HFGEN);
Ipp32s Size64 = (64) * (NUM_TIME_SLOTS * RATE + SBR_TIME_HFGEN);
bufLen = (Size32 + Size64) * 2; /* in floats */
/* --------------------- set memory for matrix --------------------- */
for (i = 0; i < CH_MAX; i++) {
pBlock = pState[i];
ippsZero_8u((Ipp8u*)pBlock, sizeof(sSBRBlock));
for (ch = 0; ch < 2; ch++) {
pBlock->wsState.iXBuf[ch][0] = pData;
ippsZero_32s(pBlock->wsState.iXBuf[ch][0], bufLen);
/* process need because mixing memory will be done */
pBlock->wsState._dcMemoryMatrix[ch] = 0;
pBlock->wsState._dcMemoryMatrix[ch] = pBlock->wsState.iXBuf[ch][0];
for (j = 0; j < (NUM_TIME_SLOTS * RATE + SBR_TIME_HFGEN); j++) {
pBlock->wsState.iXBuf[ch][j] = pBlock->wsState.iXBuf[ch][0] + j * (2*32);
pBlock->wsState.iYBuf[ch][j] = pBlock->wsState.iXBuf[ch][0] + (2*Size32 + 0 * Size64)+ j * (2*64);
}
pData += bufLen;
}
/* -- set default values -- */
sbridecReset(pBlock);
pBlock->comState.sbrHeaderFlagPresent = 0;
}
}
/********************************************************************/
Ipp32s sbriFreeDecoder(sSBRBlock * pSbr)
{
Ipp32s ch;
if( pSbr == 0 )
return 0;
for (ch = 0; ch < 2; ch++) {
if( pSbr->wsState._dcMemoryMatrix[ch] )
ippsFree( (Ipp32s*)(pSbr->wsState._dcMemoryMatrix[ch]) );
}
ippsFree(pSbr);
return 0; // OK
}
/********************************************************************/
Ipp32s sbriGetFrame(Ipp32s *pSrc, Ipp32s *pDst,
sSBRBlock * pSbr, sSbrDecFilter* sbr_filter,
Ipp32s ch, Ipp32s decode_mode, Ipp32s dwnsmpl_mode,
Ipp8u* pWorkBuffer, Ipp32s* scaleFactor )
{
sSBRDecComState* com = &(pSbr->comState);
sSBRDecWorkState* ws = &(pSbr->wsState);
Ipp32s startBand = RATE * com->sbrFIState[ch].bordersEnv[0];
Ipp32s stopBand = 0;
Ipp32s transitionBand = pSbr->comState.transitionBand[ch];
Ipp32s l;
Ipp32s bs_amp_res;
Ipp32s my_ch;
Ipp32s degPatchedCoefs[64];
Ipp32s bufZ[2*64];
Ipp32s xScale = (dwnsmpl_mode == HEAAC_DWNSMPL_OFF) ? 64 : 32;
/* -------------------------------- SCALE DATA ------------------------ */
{
Ipp32s shift = (SCALE_FACTOR_QMFA_IN - *scaleFactor - 2);
ippsLShiftC_32s_I(shift, pSrc, 1024);
}
/* -------------------------------- Analysis ---------------------------- */
if (HEAAC_HQ_MODE == decode_mode) {
sbri_ownAnalysisFilter_SBRHQ_32s_D2L(pSrc,
(Ipp32sc**)(ws->iXBuf[ch]) + SBR_TIME_HFGEN,
32,
com->kx,
(IppsFilterSpec_SBR_C_32sc*)(sbr_filter->pMemSpecQMFA[ch]));
}else{ //if (HEAAC_LP_MODE == decode_mode)
for(l=0; l<NUM_TIME_SLOTS * RATE; l++) {
/*********************************************************************
* NOTE:
* (1) matrix idea is better than 1D
* but if you can use this function for non-matrix,
* you must use such consrtuctions
* (2) you can use non-standard function of window and get better
* result (speech codec or other area)
*********************************************************************/
sbri_ownAnalysisFilter_SBRLP_32s_D2L(pSrc + l*32,
ws->iXBuf[ch] + SBR_TIME_HFGEN + l,
1, com->kx,
(IppsFilterSpec_SBR_R_32s*)(sbr_filter->pMemSpecQMFA[ch]));
}
}
/* -------------------------------- <SBR process> ---------------------------- */
if ((com->sbrHeaderFlagPresent != 0) && (com->sbrFlagError == 0) &&
((com->id_aac == ID_SCE) || (com->id_aac == ID_CPE))) {
stopBand = RATE * com->sbrFIState[ch].bordersEnv[ com->sbrFIState[ch].nEnv ];
/* skip couple channel for ch == R == 1 */
if ( !ch || !com->bs_coupling )
{
bs_amp_res = sbrUpdateAmpRes( com->bs_frame_class[ch], com->sbrFIState[ch].nEnv, com->sbrHeader.bs_amp_res);
sbriDequantization( com, ws, ws->sfsEOrig[ch], ch, bs_amp_res );
}
/* Set HF subbands to zero */
sbriCleanHFBand(ws->iYBuf[ch], startBand, stopBand, decode_mode);
sbriGenerationHF(ws->iXBuf[ch],
ws->iYBuf[ch],
&(pSbr->comState), ws->bwArray[ch],
degPatchedCoefs, ch, decode_mode);
if (HEAAC_LP_MODE == decode_mode) {
for (l = startBand; l < stopBand; l++) {
ippsZero_32s(ws->iYBuf[ch][SBR_TIME_HFADJ + l], com->kx);
}
}
my_ch = (com->bs_coupling == 1) ? 0 : ch;
sbriAdjustmentHF(ws->iYBuf[ch],
ws->bufEnvOrig[ch], ws->bufNoiseOrig[ch],
ws->sfsEOrig[my_ch],
ws->iBufGain[ch], ws->iBufNoise[ch],
&(pSbr->comState), degPatchedCoefs, pWorkBuffer,
com->sbrHeader.Reset, ch, decode_mode );
for (l = 0; l < NUM_TIME_SLOTS * RATE; l++) {
Ipp32s xoverBand = ( l < transitionBand ) ? com->kx_prev : com->kx;
sbrActiveUpsampling(ws->iXBuf[ch][l + SBR_TIME_HFADJ],
ws->iYBuf[ch][l + SBR_TIME_HFADJ],
xoverBand,
bufZ, decode_mode);
/* may be is used pointer to fuction instead CASE */
sbriSynthesisFilter_32s(bufZ, pDst + xScale*l,
sbr_filter->pMemSpecQMFS[ch],
scaleFactor,
decode_mode | dwnsmpl_mode );
}
/* UpDate High Band */
sbrUpDateBands(ws->iYBuf[ch]);
// store ch independ
com->transitionBand[ch] = stopBand - NUM_TIME_SLOTS * RATE;
} else {
//--------------
for (l = 0; l < NUM_TIME_SLOTS * RATE; l++) {
sbrPassiveUpsampling(ws->iXBuf[ch][l + SBR_TIME_HFADJ],
bufZ, decode_mode);
/* may be is use pointer to fuction instead CASE */
sbriSynthesisFilter_32s(bufZ, pDst + xScale*l,
sbr_filter->pMemSpecQMFS[ch],
scaleFactor,
decode_mode | dwnsmpl_mode );
}
//--------------
}
/* UpDate Low Band */
sbrUpDateBands( ws->iXBuf[ch] );
/* ---------------------------- <store ch depend> ---------------------------- */
if ((com->id_aac == ID_SCE) || ((com->id_aac == ID_CPE) && (ch == 1))) {
com->kx_prev = com->kx;
com->M_prev = com->M;
com->sbrHeader.Reset = 0;
}
return 0; // OK
}
/********************************************************************/
static Ipp32s sbrPassiveUpsampling(Ipp32s* iXBuf,
Ipp32s* iZBuf,
Ipp32s mode)
{
Ipp32s xScale = (HEAAC_LP_MODE == mode) ? 1 : 2;
ippsCopy_32s(iXBuf, iZBuf, NUM_TIME_SLOTS * RATE * xScale);
ippsZero_32s( iZBuf + 32 * xScale, NUM_TIME_SLOTS * RATE * xScale);
return 0; // OK
}
/********************************************************************/
static Ipp32s sbrActiveUpsampling(Ipp32s* iXBuf,
Ipp32s* iYBuf,
Ipp32s xoverBand,
Ipp32s* iZBuf,
Ipp32s mode)
{
Ipp32s k;
Ipp32s xScale = (HEAAC_LP_MODE == mode) ? 1 : 2;
for (k = 0; k < xoverBand * xScale; k++) {
iZBuf[k] = iXBuf[k];
}
if (mode == HEAAC_LP_MODE) {
iZBuf[xoverBand - 1] += iYBuf[xoverBand - 1];
}
for (k = xoverBand * xScale; k < 64 * xScale; k++) {
iZBuf[k] = iYBuf[k];
}
return 0; // OK
}
/********************************************************************/
/* Set HF subbands to zero */
Ipp32s sbriCleanHFBand(Ipp32s** pYBuf, Ipp32s startBand, Ipp32s stopBand, Ipp32s mode)
{
Ipp32s i;
Ipp32s xScale = (HEAAC_LP_MODE == mode) ? 1 : 2;
for (i = startBand; i < stopBand; i++) {
ippsZero_32s(pYBuf[i + SBR_TIME_HFADJ], 64 * xScale);
}
return 0; //OK
}
/********************************************************************/
static Ipp32s sbrUpDateBands(Ipp32s** ppSrc )
{
Ipp32s l;
Ipp32s* pBufTmp;
for (l = 0; l < SBR_TIME_HFGEN; l++) {
// Re part
pBufTmp = ppSrc[l];
ppSrc[l] = ppSrc[NUM_TIME_SLOTS * RATE + l];
ppSrc[NUM_TIME_SLOTS * RATE + l] = pBufTmp;
}
return 0;
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -