📄 sbr_enc_encoder_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) 2006 Intel Corporation. All Rights Reserved.
//
*/
#include <ipps.h>
#include <ippac.h>
#include <math.h>
#include "aaccmn_const.h"
#include "aac_status.h"
#include "sbr_freq_tabs.h"
#include "sbr_huff_tabs.h"
#include "sbr_enc_settings.h"
#include "sbr_enc_api_fp.h"
#include "sbr_enc_own_fp.h"
#include "vm_strings.h"
/* AYALog */
#ifdef SBR_NEED_LOG
#include "sbr_enc_dbg.h"
#endif
/********************************************************************/
#ifndef UNDEF_SBR_FREQ_IDX
#define UNDEF_SBR_FREQ_IDX -999
#endif
/********************************************************************/
AACStatus sbrencCheckParams(Ipp32s sampleRate,
Ipp32s numCh,
Ipp32s bitRate,
Ipp32s* indx)
{
AACStatus status = AAC_OK;
/* check of frequency (half from inFreqSample) */
if( (2*sampleRate < MIN_SBR_ENC_FREQ) || (2*sampleRate > MAX_SBR_ENC_FREQ) ){
return AAC_UNSUPPORTED;
}
/* check of channel */
if( numCh > SBR_MAX_CH ){
return AAC_UNSUPPORTED;
}
//-------------------
switch( numCh ) {
case 1:
status = sbrencGetTuningTab(sampleRate, ID_SCE, bitRate, indx);
break;
case 2:
status = sbrencGetTuningTab(sampleRate, ID_CPE, bitRate, indx);
break;
/* may be inserted more detailed analysis, but in my opinion it will be sybaritism */
default:
bitRate = bitRate / numCh ;
status = sbrencGetTuningTab(sampleRate, ID_SCE, bitRate, indx);
if ( AAC_OK != status ) return status;
/* support asymmetric cutoff freq is turned OFF */
#if 0
bitRate *= 2;
status = sbrencGetTuningTab(sampleRate, ID_CPE, bitRate, indx+1);
if ( AAC_OK != status ) return status;
#else
indx[1] = indx[0];
#endif
break;
}
//-------------------
return status;
}
/********************************************************************
*
* this table from coreAAC ( "aac_dec_api.c" )
* if tables has been changed then SBR will work incorrect
*
* static Ipp32s sampling_frequency_table[] = {
* 96000, 88200, 64000, 48000, 44100, 32000, 24000,
* 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0
* };
*
********************************************************************/
static Ipp32s sampling_frequency_table[] = {
96000, 88200, 64000, 48000, 44100, 32000, 24000,
22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0
};
static Ipp32s sbrencGetSbrFreqIndx(Ipp32s sampleRate)
{
Ipp32s indx = UNDEF_SBR_FREQ_IDX;
Ipp32s i;
for(i=0; i<16; i++){
if( sampling_frequency_table[i] == sampleRate ){
indx = i;
break;
}
}
return indx;
}
/********************************************************************/
static Ipp32f sbrencGetSplitThr(Ipp32s sampleFreq)
{
const Ipp32s frameSize = 2048;
Ipp32f frameDur = 0.0f;
Ipp32f frameDur001 = 0.0f;
Ipp32f splitThr = 0.0f;
Ipp32f ratioBitRates = 1.0f; // ratioBitRates = totalBitRate / codecBitRate
frameDur = (Ipp32f)frameSize / (Ipp32f)sampleFreq;
frameDur001 = frameDur - 0.01f;
frameDur001 = ( frameDur001 < 0.01f ) ? 0.01f : frameDur001;
splitThr = ratioBitRates * 7.5e-5f * 1.f / ( frameDur001 * frameDur001 );
return splitThr;
}
/********************************************************************/
AACStatus sbrencReset(sSBREncState* pState, Ipp32s* indxTuningTab)
{
sSBRFeqTabsState* pFreqTabsState = (pState->sbrFreqTabsState);
sSBREnc_SCE_State* pSCE_Element = (pState->pSCE_Element);
sSBRHeader* pHeader = (pState->sbrHeader);
Ipp32s* indx_CE_Tab = (pState->indx_CE_Tab);
Ipp32s indx = 0;//indxTuningTab; /* here indx MUST be correct */
Ipp32s k0 = 0, k2 = 0, kx = 0, M = 0;
Ipp32s error = 0;
Ipp32s sampleRate = 0;
Ipp32s nf_max_level = 1;
Ipp32s bs_xover_band = 0; /* may be corrected by usr */
Ipp32s i = 0;
Ipp32s ch = 0;
Ipp32s tabPatchMap[2][ 64 ];
/* offset for any CE is 0: default */
pState->indx_FreqOffset_Tab[ID_SCE] = 0;
pState->indx_FreqOffset_Tab[ID_CPE] = 0;
//------------------------------------------------------------------------------
//while ( EMPTY_MAPPING != indx_CE_Tab[numCh++] )
//------------------------------------------------------------------------------
indx = indxTuningTab[0]; // nonchalant
/* MAIN: get correct sbr_freq_indx */
sampleRate = SBR_TUNING_TABS[indx].sampleRate << 1; // because sample rate is core aac sample rate
pState->sbrFreqIndx = sbrencGetSbrFreqIndx( sampleRate );
/* calculate split threshold */
pState->splitThr = sbrencGetSplitThr( sampleRate );
if (UNDEF_SBR_FREQ_IDX == pState->sbrFreqIndx ){
return HEAAC_UNSUPPORTED;
}
//------------------------------------------------------------------------------
i = 0;
while( EMPTY_MAPPING != indxTuningTab[i] ){
/* HEADER: up-date init params of freq tabs */
sSBRFeqTabsState* pCurFreqTabsState = pFreqTabsState + i;
sSBRHeader* pCurHeader = pHeader + i;
Ipp32s indx = indxTuningTab[i];
pCurHeader->bs_start_freq = SBR_TUNING_TABS[indx].bs_start_freq;
pCurHeader->bs_stop_freq = SBR_TUNING_TABS[indx].bs_stop_freq;
/* bs_header_extra_1 ? */
pCurHeader->bs_extra_1 = 0;
pCurHeader->bs_noise_bands = SBR_TUNING_TABS[indx].bs_noise_bands;
pCurHeader->bs_freq_scale = SBR_TUNING_TABS[indx].bs_freq_scale;
pCurHeader->bs_alter_scale = BS_ALTER_SCALE_DEFAULT;
/* CHECK: DEFAULT/ UNDEFAULT ? */
if (pCurHeader->bs_noise_bands != BS_NOISE_BANDS_DEFAULT ||
pCurHeader->bs_freq_scale != BS_FREQ_SCALE_DEFAULT ||
pCurHeader->bs_alter_scale != BS_ALTER_SCALE_DEFAULT) {
pCurHeader->bs_extra_1 = 1;
}
/* calculation number of header send */
pCurHeader->nSendSBRHeader = (Ipp32s)(SBR_HEADER_SEND_TIME * 0.001f * sampleRate / 2048.0f);
pCurHeader->nSendSBRHeader = IPP_MAX(pCurHeader->nSendSBRHeader, 1);
pCurHeader->cntSentSBRHeader = 0;
pCurHeader->flag_SBRHeaderActive = 0;
/* header extra params */
/* bs_header_extra_2 ? */
pCurHeader->bs_extra_2 = 0;
pCurHeader->bs_limiter_bands = BS_LIMITER_BANDS_DEFAULT;
pCurHeader->bs_limiter_gains = BS_LIMITER_GAINS_DEFAULT;
pCurHeader->bs_interpol_freq = BS_INTERPOL_FREQ_DEFAULT;
pCurHeader->bs_smoothing_mode= BS_SMOOTHING_MODE_DEFAULT;
if (pCurHeader->bs_limiter_bands != BS_LIMITER_BANDS_DEFAULT ||
pCurHeader->bs_limiter_gains != BS_LIMITER_GAINS_DEFAULT ||
pCurHeader->bs_interpol_freq != BS_INTERPOL_FREQ_DEFAULT ||
pCurHeader->bs_smoothing_mode != BS_SMOOTHING_MODE_DEFAULT) {
pCurHeader->bs_extra_2 = 1;
}
/* header reset: internal default */
pCurHeader->bs_amp_res = 1; //3dB
//}
//------------------------------------------------------------------------------
/* FREQ TABS: up-date freq tabs */
error = sbrCalcMasterFreqBoundary(pCurHeader->bs_start_freq,
pCurHeader->bs_stop_freq,
pState->sbrFreqIndx,
&k0,
&k2);
if ( error ){
return HEAAC_UNSUPPORTED;
}
error = sbrCalcMasterFreqBandTab(k0,
k2,
pCurHeader->bs_freq_scale,
pCurHeader->bs_alter_scale,
pCurFreqTabsState->fMasterBandTab,
&(pCurFreqTabsState->nMasterBand));
if ( error ){
return HEAAC_UNSUPPORTED;
}
error = sbrCalcHiFreqTab(pCurFreqTabsState->fMasterBandTab,
pCurFreqTabsState->nMasterBand, bs_xover_band,
pCurFreqTabsState->fHiBandTab,
&(pCurFreqTabsState->nHiBand));
if ( error ){
return HEAAC_UNSUPPORTED;
}
kx = pCurFreqTabsState->fHiBandTab[ 0 ];
M = pCurFreqTabsState->fHiBandTab[ pCurFreqTabsState->nHiBand ] - pCurFreqTabsState->fHiBandTab[ 0 ];
sbrCalcLoFreqTab(pCurFreqTabsState->fHiBandTab,
pCurFreqTabsState->nHiBand,
pCurFreqTabsState->fLoBandTab,
&(pCurFreqTabsState->nLoBand));
error = sbrCalcNoiseTab(pCurFreqTabsState->fLoBandTab,
pCurFreqTabsState->nLoBand,
pCurHeader->bs_noise_bands,
k2,
kx,
pCurFreqTabsState->fNoiseBandTab,
&(pCurFreqTabsState->nNoiseBand));
if ( error ){
return HEAAC_UNSUPPORTED;
}
error = sbrCalcPatchConstruct_indxTab(pCurFreqTabsState->fMasterBandTab,
pCurFreqTabsState->nMasterBand,
k0,
M,
pState->sbrFreqIndx,
tabPatchMap[i]);
if ( error ){
return HEAAC_UNSUPPORTED;
}
/* correct offset for freq tab */
pState->indx_FreqOffset_Tab[i] = i;
//increment
i++;
}
//------------------------------------------------------------------------------
ch = 0;
/* SCE init */
while(EMPTY_MAPPING != indx_CE_Tab[ch]){
Ipp32s indx = pState->indx_FreqOffset_Tab[ indx_CE_Tab[ch] ];
sSBRFeqTabsState* pCurFreqTabsState = pFreqTabsState + indx;
sSBREnc_SCE_State* pCurSCE_Element = pSCE_Element + ch;
pCurSCE_Element->bs_amp_res = 1; //3dB
/* patch */
ippsCopy_32s(tabPatchMap[indx], pCurSCE_Element->tabPatchMap, 64);
/* invf estimation init */
for(i = 0; i < pCurFreqTabsState->nNoiseBand; i++){
pCurSCE_Element->sbrInvfEst.prev_bs_invf_mode[i] = INVF_OFF_LEVEL;
pCurSCE_Element->sbrInvfEst.prevRegionOrig[i] = 0;
pCurSCE_Element->sbrInvfEst.prevRegionSBR[i] = 0;
}
/* noisef estimation state */
nf_max_level = SBR_TUNING_TABS[indx].nf_max_level;
pCurSCE_Element->sbrNoiseEst.nf_max_level = (Ipp32f)pow(2, nf_max_level/3.0f);
pCurSCE_Element->sbrEDState.flagEnvUpDate = 0;
pCurSCE_Element->sbrEDState.flagNoiseUpDate = 0;
/* addition initialization */
pCurSCE_Element->sbrTransientState.flagTransferTran = 0;
ch++;
/* patch */
if ( ID_LFE == indx_CE_Tab[ch]) {
return AAC_OK;
}
}
return AAC_OK;
}
/********************************************************************/
static Ipp32s
sbrencUpDateAmpRes(Ipp32s nEnv, Ipp32s frameClass)
{
Ipp32s ampRes = 1; // 3.0dB
if( (FIXFIX == frameClass) && (1 == nEnv) ){
ampRes = 0;// 1.5dB
}
return ampRes;
}
/********************************************************************/
AACStatus sbrencGetFrame(sSBREncState* pState, ownFilterSpec_SBR_C_32fc* pSpec)
{
AACStatus status = AAC_OK;
/* common part */
Ipp32s offset = pState->sbr_offset;
Ipp32s indx = pState->indx_FreqOffset_Tab[ pState->indx_CE_Tab[offset] ];
Ipp32s ch;
sSBRFeqTabsState* pFreqTabsState = (pState->sbrFreqTabsState + indx);
sSBRHeader* pHeader = (pState->sbrHeader + indx);
sSBREnc_SCE_State* pRoot_SCE_Element = ( pState->pSCE_Element + offset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -