📄 aac_dec_ps_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) 2007 Intel Corporation. All Rights Reserved.
//
*/
/* SYSTEM */
#include <math.h>
/* IPP */
#include "ipps.h"
#include "ippac.h"
/* SBR/PS */
#include "sbr_huff_tabs.h"
#include "sbr_dec_tabs_fp.h"
#include "ps_dec_parser.h"
/* AAC */
#include "aac_dec_ps_fp.h"
/* debug */
#include "vm_debug.h"
/********************************************************************/
#define PS_EPS_0 (1e-12f)
/********************************************************************/
#define OWN_MULC(inData, outData, coef) \
outData.re = inData.re; \
outData.im = inData.im * coef;
/********************************************************************/
#define IPDOPD_SF ( (Ipp32f)IPP_PI / 4.f)
/* corrigendum contains only one factor */
static const Ipp32f DECAY_SLOPE = 0.05f;
static const Ipp32s tabNumSampleDelayMem[3] = {3, 4, 5};
/********************************************************************/
#define PSDEC_UPDATE_PTR(type, ptr,inc) \
if (ptr) { \
ptr = (type *)((Ipp8u *)(ptr) + inc); \
}
/********************************************************************/
void psdecUpdateMemMap(sPSDecState_32f* pPSState, Ipp32s mShift)
{
Ipp32s m, k;
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppDelaySubQMF[0], mShift)
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppDelayQMF[0], mShift)
for(k = 0; k < 14; k++){
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppDelaySubQMF[k], mShift)
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppDelayQMF[k], mShift)
}
/* problem code for update memory allocator, due to 3d matrix, will be fixed later */
for(m=0; m < 3; m++){
PSDEC_UPDATE_PTR(Ipp32fc*, pPSState->pppAllPassFilterMemSubQMF[m], mShift)
for( k = 0; k < 5; k++){
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->pppAllPassFilterMemSubQMF[m][k], mShift)
}
}
/* problem code for update memory allocator, due to 3d matrix */
for(m=0; m < 3; m++){
PSDEC_UPDATE_PTR(Ipp32fc*, pPSState->pppAllPassFilterMemQMF[m], mShift)
for( k = 0; k < 5; k++){
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->pppAllPassFilterMemQMF[m][k], mShift)
}
}
for(k = 0; k < 12; k++){
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppFracDelayLenTab1020[k], mShift)
}
for(k = 0; k < 32; k++){
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppFracDelayLenTab34[k], mShift)
}
for(k = 0; k < 64; k++){
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppFracDelayLenTabQMF[k], mShift)
}
for( k = 0; k < 32; k++ ){
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppHybridL[k], mShift)
PSDEC_UPDATE_PTR(Ipp32fc, pPSState->ppHybridR[k] , mShift)
}
return;//OK
}
/********************************************************************/
void psDecoderGetSize(Ipp32s *pSize)
{
Ipp32s sum_size = 14*32 + 14*64 + 3*5*32 + (5*3) + 3*5*64 + (5*3) + (12+32+64)*3 + (32*32) + (32*32);
*pSize = sum_size * sizeof(Ipp32fc);
return;//OK
}
/********************************************************************/
Ipp32s psInitDecoder_32f(sPSDecState_32f* pState, void* pMem)
{
Ipp32f tabHCenterFreq20[12] = {0.5/4, 1.5/4, 2.5/4, 3.5/4,
4.5/4*0, 5.5/4*0, -1.5/4, -0.5/4,
3.5/2, 2.5/2, 4.5/2, 5.5/2};
Ipp32f tabHCenterFreq34[32] = { 1.0f/12, 3.0f/12, 5.0f/12, 7.0f/12,
9.0f/12, 11.0f/12, 13.0f/12, 15.0f/12,
17.0f/12, -5.0f/12, -3.0f/12, -1.0f/12,
17.0f/8, 19.0f/8, 5.0f/8, 7.0f/8,
9.0f/8, 11.0f/8, 13.0f/8, 15.0f/8,
9.0f/4, 11.0f/4, 13.0f/4, 7.0f/4,
17.0f/4, 11.0f/4, 13.0f/4, 15.0f/4,
17.0f/4, 19.0f/4, 21.0f/4, 15.0f/4};
Ipp32f tabFracDelayLen[] = {0.43f, 0.75f, 0.347f};
Ipp32s k = 0, m = 0;
Ipp32f arg = 0.f;
Ipp32f fracParam = 0.39f;
Ipp32s i;
Ipp32s offset = 0;
Ipp32fc* ptr = NULL;
ps_header_fill_default( &(pState->comState) );
/* ----------------------------------------------------- */
// memory allocator
ptr = (Ipp32fc*)pMem;
pState->ppDelaySubQMF[0] = (Ipp32fc*)ptr;
offset = 14*32;
pState->ppDelayQMF[0] = (Ipp32fc*)(ptr + offset);
for(k = 0; k < 14; k++){
pState->ppDelaySubQMF[k] = ptr + k * 32;
pState->ppDelayQMF[k] = ptr + offset + k*64;
}
offset += 14*64;
for(m=0; m < 3; m++){
pState->pppAllPassFilterMemSubQMF[m] = (Ipp32fc**)(ptr + offset);
offset += 5;
for( k = 0; k < 5; k++){
pState->pppAllPassFilterMemSubQMF[m][k] = (Ipp32fc*)(ptr + offset + k*32);
}
offset += 5*32;
}
for(m=0; m < 3; m++){
pState->pppAllPassFilterMemQMF[m] = (Ipp32fc**)(ptr + offset);
offset += 5;
for( k = 0; k < 5; k++){
pState->pppAllPassFilterMemQMF[m][k] = ptr + offset + k*64;
}
offset += 5*64;
}
for(k = 0; k < 12; k++){
pState->ppFracDelayLenTab1020[k] = ptr + offset + 3*k;
}
offset += 3*12;
for(k = 0; k < 32; k++){
pState->ppFracDelayLenTab34[k] = ptr + offset + 3*k;
}
offset += 3*32;
for(k = 0; k < 64; k++){
pState->ppFracDelayLenTabQMF[k] = ptr + offset + 3*k;
}
offset += 3*64;
for( k = 0; k < 32; k++ ){
pState->ppHybridL[k] = ptr + offset + 32*k;
pState->ppHybridR[k] = ptr + offset + 32*32 + 32*k;
}
/* ----------------------------------------------------- */
/* TUNING TABLES */
/* [tab1] - fractional delay vector 1020 */
for( k = 0; k < 12; k++ ){
arg = (Ipp32f)(- IPP_PI * tabHCenterFreq20[k] * fracParam);
pState->pFracDelayLenTab1020[k].re = (Ipp32f)cos( arg );
pState->pFracDelayLenTab1020[k].im = (Ipp32f)sin( arg );
}
/* [tab2] - fractional delay vector 34 */
for( k = 0; k < 32; k++ ){
arg = (Ipp32f)(- IPP_PI * tabHCenterFreq34[k] * fracParam);
pState->pFracDelayLenTab34[k].re = (Ipp32f)cos( arg );
pState->pFracDelayLenTab34[k].im = (Ipp32f)sin( arg );
}
/* [tab3] - fractional delay vector. QMF domain */
for( k = 0; k < 64; k++ ){
arg = (Ipp32f)(-IPP_PI * ( k + 0.5f ) * fracParam);
pState->pFracDelayLenTabQMF[k].re = (Ipp32f)cos(arg);
pState->pFracDelayLenTabQMF[k].im = (Ipp32f)sin(arg);
}
/* [tab4] - fractional delay matrix */
for(m = 0; m < 3; m++){
/* 1020 */
for( k = 0; k < 12; k++){
arg = (Ipp32f)(-IPP_PI * tabHCenterFreq20[k] * tabFracDelayLen[m]);
pState->ppFracDelayLenTab1020[k][m].re = (Ipp32f)cos( arg );
pState->ppFracDelayLenTab1020[k][m].im = (Ipp32f)sin( arg );
}
/* 34 */
for( k = 0; k < 32; k++ ){
arg = (Ipp32f)(-IPP_PI * tabHCenterFreq34[k] * tabFracDelayLen[m]);
pState->ppFracDelayLenTab34[k][m].re = (Ipp32f)cos( arg );
pState->ppFracDelayLenTab34[k][m].im = (Ipp32f)sin( arg );
}
/* QMF domain */
for( k = 0; k < 64; k++ ){
arg = (Ipp32f)(-IPP_PI * ( k + 0.5f ) * tabFracDelayLen[m]);
pState->ppFracDelayLenTabQMF[k][m].re = (Ipp32f)cos( arg );
pState->ppFracDelayLenTabQMF[k][m].im = (Ipp32f)sin( arg );
}
}
/* init tables */
ippsSet_32s(14, pState->bufNumSampleDelayQMF, 35);
ippsSet_32s(1, pState->bufNumSampleDelayQMF + 35, 64 - 35);
/* common part */
pState->comState.delayLenIndx = 0;
/************************************************************************/
/* mapping index */
/************************************************************************/
for( i = 0; i < 34; i++ ){
pState->h11Prev[i].re = 1.f;
pState->h11Prev[i].im = 0.f;
pState->h12Prev[i].re = 1.f;
pState->h12Prev[i].im = 0.f;
pState->h21Prev[i].re = 0.f;
pState->h21Prev[i].im = 0.f;
pState->h22Prev[i].re = 0.f;
pState->h22Prev[i].im = 0.f;
}
return 0;//OK
}
/********************************************************************/
Ipp32s psFreeDecoder_32f(sPSDecState_32f* pState)
{
#if 0
if( NULL != pState->ppDelaySubQMF ){
ippsFree( pState->ppDelaySubQMF );
}
if( NULL != pState->comState.psHuffTables[0] ){
ippsFree( pState->comState.psHuffTables[0] );
}
#endif
return 0;//OK
}
/********************************************************************/
static
Ipp32s ownAnalysisFilter_PSDec_Kernel_32fc(const Ipp32fc* pSrc,
Ipp32fc ppDst[32][12],
const Ipp32f* pTab,
Ipp32s nSubBands)
{
Ipp32s band, n, q;
Ipp32f arg = 0.f;
Ipp32fc hRes;
for(band = 0; band < NUM_SBR_BAND; band++) {
for(q = 0; q < nSubBands; q++) {
Ipp32fc res = {0.f, 0.f};
for(n = 0; n < 13; n++) {
arg = (Ipp32f)(2.f * IPP_PI * (n-6) / nSubBands);
if ( 2 == nSubBands ) {
arg *= q;
hRes.re = (Ipp32f)cos(arg);
hRes.im = 0.f;
} else {
arg *= (q + 0.5f);
hRes.re = (Ipp32f)cos( arg );
hRes.im = -(Ipp32f)sin( arg );
}
res.re += pTab[n] * ( pSrc[n+band].re * hRes.re - pSrc[n+band].im * hRes.im );
res.im += pTab[n] * ( pSrc[n+band].im * hRes.re + pSrc[n+band].re * hRes.im );
}
ppDst[band][q] = res;
}
}
return 0; //OK
}
/********************************************************************/
static Ipp32s ownAnalysisUpdateMem_32fc(Ipp32fc** ppSrc, Ipp32fc* pMemBuf,
Ipp32fc* pWorkBuf, int band)
{
Ipp32fc* ptr = NULL;
Ipp32s sbr_band = 0;
ippsCopy_32fc(pMemBuf, pWorkBuf, LEN_PS_FILTER);
ptr = pWorkBuf + LEN_PS_FILTER;
for( sbr_band = 0; sbr_band < NUM_SBR_BAND; sbr_band++ ){
ptr[sbr_band] = ppSrc[ sbr_band + DELAY_PS_FILTER ][band];
}
ippsCopy_32fc(pWorkBuf + NUM_SBR_BAND, pMemBuf, LEN_PS_FILTER);
return 0;//OK
}
/********************************************************************/
static Ipp32s ownAnalysisFilter_PSDec_32fc(Ipp32fc** ppSrc,
Ipp32fc** ppDst,
sHybridAnalysis* pState,
Ipp32s flag)
{
Ipp32s nBand = 0, band = 0, sbr_band = 0, q = 0;
Ipp32s offset_tab = 0, offset_channel = 0, hRes = 0;
// Ipp32fc* ptr = NULL;
Ipp32s* pResTab = NULL;
Ipp32fc bufW[44];
/* [1] select config */
pResTab = (flag == CONFIG_HA_BAND34) ? (Ipp32s*)tabResBand34 : (Ipp32s*)tabResBand1020;
nBand = pResTab[0];
offset_tab = (flag == CONFIG_HA_BAND34) ? 0 : 1;
/* [2] core filtering */
for( band = 0; band < nBand; band++ ){
hRes = pResTab[ band + 1 ];// "+1" because [0] - len of vector
ownAnalysisUpdateMem_32fc(ppSrc, pState->mMemBuf[band], bufW, band);
/* filtering */
ownAnalysisFilter_PSDec_Kernel_32fc(bufW,
pState->mTmpBuf,
(const Ipp32f*)pCoefTabs[ hRes + offset_tab ],
hRes);
for(sbr_band = 0; sbr_band < NUM_SBR_BAND; sbr_band++) {
for(q = 0; q < hRes; q++) {
ppDst[sbr_band][offset_channel + q] = pState->mTmpBuf[sbr_band][q];
}
}
offset_channel += hRes;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -