📄 sbr_freq_tabs.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-2006 Intel Corporation. All Rights Reserved.
//
*/
#include<ipps.h>
#include<ippac.h>
#include<math.h>
#include<stdio.h>
#include "sbr_settings.h"
#include "sbr_struct.h"
#include "sbr_freq_tabs.h"
/********************************************************************/
// Q14
static const Ipp32s iTABLE_LIMITER_BANDS_PER_OCTAVE[] = { 19661, 32768, 49152 };
static Ipp32s offset_16kHz[16] = { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 };
static Ipp32s offset_22kHz[16] = { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13 };
static Ipp32s offset_24kHz[16] = { -5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 };
static Ipp32s offset_32kHz[16] = { -6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 };
static Ipp32s offset_44_64kHz[16] = { -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20 };
static Ipp32s offset_up64kHz[16] = { -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24 };
static Ipp32s* SBR_TABLE_OFFSET[] = {offset_up64kHz, offset_up64kHz, offset_44_64kHz,
offset_44_64kHz, offset_44_64kHz, offset_32kHz, offset_24kHz, offset_22kHz, offset_16kHz};
/********************************************************************/
static Ipp32s stopDk_96kHz[14] = { 0, 2, 4, 6, 8, 11, 14, 18, 22, 26, 31, 37, 44, 51 };
static Ipp32s stopDk_88kHz[14] = { 0, 2, 4, 6, 8, 11, 14, 18, 22, 26, 31, 36, 42, 49 };
static Ipp32s stopDk_64kHz[14] = { 0, 2, 4, 6, 8, 11, 14, 17, 21, 25, 29, 34, 39, 44 };
static Ipp32s stopDk_48kHz[14] = { 0, 2, 4, 6, 8, 11, 14, 17, 20, 24, 28, 33, 38, 43 };
static Ipp32s stopDk_44kHz[14] = { 0, 2, 4, 6, 8, 11, 14, 17, 20, 24, 28, 32, 36, 41 };
static Ipp32s stopDk_32kHz[14] = { 0, 2, 4, 6, 8, 10, 12, 14, 17, 20, 23, 26, 29, 32 };
static Ipp32s stopDk_24kHz[14] = { 0, 2, 4, 6, 8, 10, 12, 14, 17, 20, 23, 26, 29, 32 };
static Ipp32s stopDk_22kHz[14] = { 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 20, 23, 26, 29 };
static Ipp32s stopDk_16kHz[14] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16 };
static Ipp32s stopDk_12kHz[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static Ipp32s stopDk_11kHz[14] = { 0, -1, -2, -3, -4, -5, -6, -6, -6, -6, -6, -6, -6, -6 };
static Ipp32s stopDk_08kHz[14] = { 0, -3, -6, -9, -12, -15, -18, -20, -22, -24, -26, -28, -30, -32 };
static Ipp32s* SBR_TABLE_STOP_DK[] = {stopDk_96kHz, stopDk_88kHz, stopDk_64kHz, stopDk_48kHz, stopDk_44kHz,
stopDk_32kHz, stopDk_24kHz, stopDk_22kHz, stopDk_16kHz, stopDk_12kHz,
stopDk_11kHz, stopDk_08kHz};
/********************************************************************/
/* FIXED POINT: Q28 format */
/* input arg from 0 to 72 */
static Ipp32s SBR_TABLE_LOG2[] = {
0, 0, 268435456, 425460128, 536870912, 623287808, 693895616, 753593600, 805306368,
850920256,891723264,928634112,962331072, 993329216, 1022029056,1048747968,1073741824,1097219968,
1119355776,1140294400,1160158720,1179053696,1197069568,1214284416,1230766464,1246575616,1261764736,
1276380416,1290464512,1304054400,1317183360,1329881984,1342177280,1354094208,1365655424,1376881408,
1387791232,1398402048,1408729856,1418789376,1428594176,1438156928,1447489152,1456601856,1465505024,
1474208128,1482719872,1491048576,1499201920,1507187200,1515011072,1522680064,1530200192,1537576960,
1544815872,1551921920,1558899968,1565754496,1572489856,1579110016,1585618816,1592020224,1598317440,
1604513920,1610612736,1616617088,1622529664,1628353408,1634090880,1639744512,1645316864,1650810112,
1656226688
};
/********************************************************************/
/* NINT[ mult * log(num / denum) / log(2) ] */
static Ipp32s GetRatioLog( Ipp32s mult, Ipp32s num, Ipp32s denum )
{
Ipp32s ret_val;
ret_val = mult * (SBR_TABLE_LOG2[num] - SBR_TABLE_LOG2[denum]) + 134217728;
ret_val >>= 28;
return ret_val;
}
/********************************************************************/
static Ipp32s sbrCalcMasterFreq1(Ipp32s k0, Ipp32s k2, Ipp32s bs_alter_scale, Ipp32s *fMasterBandTab,
Ipp32s *nMasterBand)
{
Ipp32s dk;
Ipp32s numBands;
Ipp32s k2Achieved;
Ipp32s k2Diff;
Ipp32s k;
Ipp32s incr = 0;
Ipp32s vDk[ 100 ];
for (k = 0; k < 64; k++) {
fMasterBandTab[k] = 0;
}
if (bs_alter_scale == 0) {
dk = 1;
numBands = (k2 - k0) >> 1;
} else {
dk = 2;
numBands = (k2 - k0 + 2) >> 2;
}
numBands <<= 1;
if(numBands <= 0)
return SBR_ERR_REQUIREMENTS;
k2Achieved = k0 + numBands * dk;
k2Diff = k2 - k2Achieved;
for (k = 0; k < numBands; k++)
vDk[k] = dk;
if (k2Diff < 0) {
incr = 1;
k = 0;
}
if (k2Diff > 0) {
incr = -1;
k = numBands - 1;
}
while (k2Diff != 0) {
vDk[k] -= incr;
k += incr;
k2Diff += incr;
}
fMasterBandTab[0] = k0;
for (k = 1; k <= numBands; k++)
fMasterBandTab[k] = fMasterBandTab[k - 1] + vDk[k - 1];
*nMasterBand = numBands;
if (numBands < 0)
return SBR_ERR_REQUIREMENTS;
return 0; // OK
}
/********************************************************************/
static Ipp32s sbrCalcMasterFreq2(Ipp32s k0, Ipp32s k2, Ipp32s bs_freq_scale,
Ipp32s bs_alter_scale, Ipp32s *fMasterBandTab, Ipp32s *nMasterBand)
{
Ipp32s temp1[3] = { 6, 5, 4 };
Ipp32s bands = temp1[bs_freq_scale - 1];
Ipp32s twoRegions;
Ipp32s k1, k;
Ipp32s numBands0, numBands1, change;
Ipp32s vDk0[100];
Ipp32s vDk1[100];
Ipp32s vk0[100];
Ipp32s vk1[100];
Ipp32s pow_vec[100];
Ipp32s min_vDk1, max_vDk0;
Ipp32s threshold;
/* Q28 */
const Ipp32s iTemp2[2] = { 268435456, 348966093 };
Ipp32s iWarp = iTemp2[bs_alter_scale];
/* Q14 */
const Ipp32s BandDivWarp[] = { 75618, 63015, 50412 };
for (k = 0; k < 64; k++) {
fMasterBandTab[k] = 0;
}
/* Q22 */
threshold = 9436764 * k0;
if ( (k2 << 22) > threshold ){
twoRegions = 1;
k1 = 2 * k0;
} else {
twoRegions = 0;
k1 = k2;
}
numBands0 = GetRatioLog( bands, k1, k0 );
numBands0 <<= 1;
if (numBands0 < 0)
return SBR_ERR_REQUIREMENTS;
sbrGetPowerVector( numBands0, k1, k0, pow_vec);
ippsSub_32s_Sfs((const Ipp32s*)pow_vec, (const Ipp32s*)(pow_vec+1), vDk0, numBands0, 0);
ippsSortAscend_32s_I(vDk0, numBands0);
ippsMin_32s(vDk0, numBands0, &threshold);
if (threshold < 0)
return SBR_ERR_REQUIREMENTS;
vk0[0] = k0;
for (k = 1; k <= numBands0; k++)
vk0[k] = vk0[k - 1] + vDk0[k - 1];
if (twoRegions == 1) {
if ( iWarp == 268435456 ){ // warp == 1.0f ?
numBands1 = GetRatioLog( bands, k2, k1 );
}else{
numBands1 = BandDivWarp[ bs_freq_scale - 1 ] * ((SBR_TABLE_LOG2[k2] - SBR_TABLE_LOG2[k1]) >> 14 ) + 134217728;
numBands1 >>= 28;
}
numBands1 <<= 1;
sbrGetPowerVector( numBands1, k2, k1, pow_vec );
ippsSub_32s_Sfs((const Ipp32s*)pow_vec, (const Ipp32s*)(pow_vec+1), vDk1, numBands1, 0);
ippsMin_32s(vDk1, numBands1, &min_vDk1);
if (min_vDk1 < 0)
return SBR_ERR_REQUIREMENTS;
ippsMax_32s(vDk0, numBands0, &max_vDk0);
if (min_vDk1 < max_vDk0) {
ippsSortAscend_32s_I(vDk1, numBands1);
change = max_vDk0 - vDk1[0];
threshold = (vDk1[numBands1 - 1] - vDk1[0]) >> 1;
if (change > threshold)
change = threshold;
vDk1[0] += change;
vDk1[numBands1 - 1] -= change;
}
ippsSortAscend_32s_I(vDk1, numBands1);
vk1[0] = k1;
for (k = 1; k <= numBands1; k++)
vk1[k] = vk1[k - 1] + vDk1[k - 1];
*nMasterBand = numBands0 + numBands1;
for (k = 0; k <= numBands0; k++)
fMasterBandTab[k] = vk0[k];
for (k = numBands0 + 1; k <= (*nMasterBand); k++)
fMasterBandTab[k] = vk1[k - numBands0];
} else {
*nMasterBand = numBands0;
for (k = 0; k <= numBands0; k++)
fMasterBandTab[k] = vk0[k];
}
return 0; // OK
}
/********************************************************************
*
* this table from coreAAC ( "aac_dec_api.c" )
* if tables has been changed then SBR may work incorrect
*
* static Ipp32s sampling_frequency_table[] = {
* 96000, 88200, 64000, 48000, 44100, 32000, 24000,
* 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0
* };
*
********************************************************************/
Ipp32s sbrCalcMasterFreqBoundary(Ipp32s bs_start_freq, Ipp32s bs_stop_freq,
Ipp32s sbrFreqIndx, Ipp32s *k0, Ipp32s *k2)
{
Ipp32s startMin, stopMin;
Ipp32s SBR_TABLE_START_MIN[] = { 7, 7, 10, 11, 12, 16, 16, 17, 24, 32, 35, 48 };
Ipp32s SBR_TABLE_STOP_MIN[] = { 13, 15, 20, 21, 23,32, 32, 35, 48, 64, 70, 96 };
/* may be error form core AAC */
if( ( sbrFreqIndx < 0 ) || (sbrFreqIndx > 11) ) {
return SBR_ERR_REQUIREMENTS;
}
startMin = SBR_TABLE_START_MIN[ sbrFreqIndx ];
stopMin = SBR_TABLE_STOP_MIN[ sbrFreqIndx ];
*k0 = startMin + SBR_TABLE_OFFSET[ sbrFreqIndx ][bs_start_freq];
if ((bs_stop_freq >= 0) && (bs_stop_freq < 14)) {
*k2 = IPP_MIN(64, stopMin + SBR_TABLE_STOP_DK[sbrFreqIndx][bs_stop_freq] );
}else if (bs_stop_freq == 14){
*k2 = IPP_MIN(64, 2 * (*k0));
}else if (bs_stop_freq == 15){
*k2 = IPP_MIN(64, 3 * (*k0));
}
// check
#if 0
if (((*k2) - (*k0) < 0) || (sbr_freq_sample < 32000) && ((*k2) - (*k0) > 48) ||
(sbr_freq_sample == 44000) && ((*k2) - (*k0) > 35) || (sbr_freq_sample >= 48000) &&
((*k2) - (*k0) > 32))
return SBR_ERR_REQUIREMENTS;
#endif
if (((*k2) - (*k0) < 0) ||
(sbrFreqIndx > 5) && ((*k2) - (*k0) > 48) ||
(sbrFreqIndx == 4) && ((*k2) - (*k0) > 35) ||
(sbrFreqIndx <= 3) && ((*k2) - (*k0) > 32)){
return SBR_ERR_REQUIREMENTS;
}
return 0; // OK
}
/********************************************************************/
Ipp32s sbrCalcMasterFreqBandTab(Ipp32s k0, Ipp32s k2, Ipp32s bs_freq_scale,
Ipp32s bs_alter_scale, Ipp32s *fMasterBandTab, Ipp32s *nMasterBand)
{
Ipp32s error = 0;
if (bs_freq_scale == 0)
error = sbrCalcMasterFreq1(k0, k2, bs_alter_scale, fMasterBandTab, nMasterBand);
else
error =
sbrCalcMasterFreq2(k0, k2, bs_freq_scale, bs_alter_scale, fMasterBandTab,
nMasterBand);
return error;
}
/********************************************************************/
Ipp32s sbrCalcHiFreqTab(Ipp32s* fMasterBandTab, Ipp32s nMasterBand, Ipp32s bs_xover_band,
Ipp32s* fHiFreqTab, Ipp32s* nHighBand)
{
Ipp32s k;
*nHighBand = nMasterBand - bs_xover_band;
if (*nHighBand < 0)
return SBR_ERR_REQUIREMENTS;
for (k = 0; k <= *nHighBand; k++){
fHiFreqTab[k] = fMasterBandTab[k + bs_xover_band];
}
return 0;//OK
}
/********************************************************************/
Ipp32s sbrCalcLoFreqTab(Ipp32s* fHiFreqTab, Ipp32s nHiBand,
Ipp32s* fLoFreqTab, Ipp32s* nLoBand)
{
Ipp32s k;
Ipp32s operand1, operand2;
Ipp32s indx;
operand1 = nHiBand >> 1;
operand2 = operand1 << 1;
*nLoBand = operand1 + nHiBand - operand2;
indx = nHiBand & 1;
fLoFreqTab[0] = fHiFreqTab[0];
for (k = 1; k <= *nLoBand; k++)
fLoFreqTab[k] = fHiFreqTab[2 * k - indx];
return 0;//OK
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -