www.pudn.com > aacenc.rar > tns.c
#include "tns.h"
/***********************************************/
/* TNS Profile/Frequency Dependent Parameters */
/***********************************************/
static unsigned long tnsSupportedSamplingRates[13] =
{8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,0};
/* 将带宽限制在2.0 kHz之内 */
static unsigned short tnsMinBandNumberLong[12] =
{ 31, 30, 28, 24, 26, 25, 20, 17, 16, 15, 12, 11 };
static unsigned short tnsMinBandNumberShort[12] =
{ 12, 10, 10, 8, 6, 6, 4, 3, 3, 2, 2, 2 };
/**************************************/
/* 采用基本配置和低复杂性配置时的TNS 参数 */
/**************************************/
static unsigned short tnsMaxBandsLongMainLow[12] =
{ 39, 42, 42, 42, 46, 46, 51, 42, 40, 34, 31, 31 };
static unsigned short tnsMaxBandsShortMainLow[12] =
{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 10, 9, 9 };
static unsigned short tnsMaxOrderLongMain = 20;
static unsigned short tnsMaxOrderLongLow = 12;
static unsigned short tnsMaxOrderShortMainLow = 7;
/**************************************/
/*采用可变采样率配置时的TNS 参数*/
/**************************************/
static unsigned short tnsMaxBandsLongSSR[12] =
{ 19, 23, 23, 23, 29, 29, 26, 26, 26, 27, 28, 28 };
static unsigned short tnsMaxBandsShortSSR[12] =
{ 7, 8, 8, 8, 7, 7, 6, 6, 6, 7, 7, 7 };
static unsigned short tnsMaxOrderLongSSR = 12;
static unsigned short tnsMaxOrderShortSSR = 7;
/*****************************************************/
/* InitTns: */
/*****************************************************/
void TnsInit(long samplingRate,enum AAC_PROFILE profile,TNS_INFO* tnsInfo)
{
int fsIndex=0;
/* 判决采样率是否被支持*/
while (samplingRate!=tnsSupportedSamplingRates[fsIndex]) {
fsIndex++;
}
switch( profile ) {
case MAIN :
tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex];
tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex];
tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongMain;
tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow;
break;
case LOW :
tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex];
tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex];
tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongLow;
tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow;
break;
case SSR :
tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongSSR[fsIndex];
tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortSSR[fsIndex];
tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongSSR;
tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortSSR;
break;
}
tnsInfo->tnsMinBandNumberLong = tnsMinBandNumberLong[fsIndex];
tnsInfo->tnsMinBandNumberShort = tnsMinBandNumberShort[fsIndex];
}
/*****************************************************/
/* TnsEncode: */
/*****************************************************/
int TnsEncode(int numberOfBands, /* 每一段的频带数 */
int maxSfb, /* 最大sfb */
enum WINDOW_TYPE blockType, /* 窗口块的类型(长段,短段) */
int* sfbOffsetTable, /* 比例因子偏移表 */
double* spec, /* 频谱数据数组 */
TNS_INFO* tnsInfo) /* TNS信息 */
{
int numberOfWindows,windowSize;
int startBand,stopBand,order; /* 要进行TNS的频带 */
int lengthInBands; /* 要进行滤波的长度,以频带为单位*/
int w, error;
int startIndex,length;
double gain;
switch( blockType ) {
case ONLY_SHORT_WINDOW :
numberOfWindows = NSHORT;
windowSize = SN2;
startBand = tnsInfo->tnsMinBandNumberShort;
stopBand = numberOfBands;
lengthInBands = stopBand-startBand;
order = tnsInfo->tnsMaxOrderShort;
startBand = min(startBand,tnsInfo->tnsMaxBandsShort);
stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort);
break;
default:
numberOfWindows = 1;
windowSize = LN2;
startBand = tnsInfo->tnsMinBandNumberLong;
stopBand = numberOfBands;
lengthInBands = stopBand - startBand;
order = tnsInfo->tnsMaxOrderLong;
startBand = min(startBand,tnsInfo->tnsMaxBandsLong);
stopBand = min(stopBand,tnsInfo->tnsMaxBandsLong);
break;
}
/* 确认起始和结束的频带数小于maxSfb 并且大于等于0*/
startBand = min(startBand,maxSfb);
stopBand = min(stopBand,maxSfb);
startBand = max(startBand,0);
stopBand = max(stopBand,0);
tnsInfo->tnsDataPresent=0; /* 缺省为没有使用 TNS */
#if 1
if (blockType != ONLY_SHORT_WINDOW)
/* 对每一段进行分析并滤波 */
for (w=0;wwindowData[w];
TNS_FILTER_DATA* tnsFilter = windowData->tnsFilter;
double* k = tnsFilter->kCoeffs; /*反射系数 */
double* a = tnsFilter->aCoeffs; /* 预测系数 */
windowData->numFilters=0;
windowData->coefResolution = DEF_TNS_COEFF_RES;
startIndex = w * windowSize + sfbOffsetTable[startBand];
length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand];
gain = LevinsonDurbin(order,length,&spec[startIndex],k);
if (gain>DEF_TNS_GAIN_THRESH) { /* Use TNS */
int truncatedOrder;
windowData->numFilters++;
tnsInfo->tnsDataPresent=1;
tnsFilter->direction = 0;
tnsFilter->coefCompress = 0;
tnsFilter->length = lengthInBands;
QuantizeReflectionCoeffs(order,DEF_TNS_COEFF_RES,k,tnsFilter->index);
truncatedOrder = TruncateCoeffs(order,DEF_TNS_COEFF_THRESH,k);
tnsFilter->order = truncatedOrder;
StepUp(truncatedOrder,k,a); /* Compute predictor coefficients */
error = TnsInvFilter(length,&spec[startIndex],tnsFilter); /* Filter */
if (error == MBERROR)
return MBERROR;
}
}
return MBNO_ERROR;
#endif
}
/*****************************************************/
/* TnsFilter: */
/* 对给定的频谱进行滤波 */
/*****************************************************/
void TnsFilter(int length,double* spec,TNS_FILTER_DATA* filter) {
int i,j,k=0;
int order=filter->order;
double* a=filter->aCoeffs;
/* Determine loop parameters for given direction */
if (filter->direction) {
/* Startup, initial state is zero */
for (i=length-2;i>(length-1-order);i--) {
k++;
for (j=1;j<=k;j++) {
spec[i]-=spec[i+j]*a[j];
}
}
/* Now filter completely inplace */
for (i=length-1-order;i>=0;i--) {
for (j=1;j<=order;j++) {
spec[i]-=spec[i+j]*a[j];
}
}
} else {
/* Startup, initial state is zero */
for (i=1;iorder;
double* a=filter->aCoeffs;
double* temp;
temp = (double *) malloc( length * sizeof (double));
if (!temp) {
return MBERROR;
// CommonExit( 1, "TnsInvFilter: Could not allocate memory for TNS array\nExiting program...\n");
}
/* Determine loop parameters for given direction */
if (filter->direction) {
/* Startup, initial state is zero */
temp[length-1]=spec[length-1];
for (i=length-2;i>(length-1-order);i--) {
temp[i]=spec[i];
k++;
for (j=1;j<=k;j++) {
spec[i]+=temp[i+j]*a[j];
}
}
/* Now filter the rest */
for (i=length-1-order;i>=0;i--) {
temp[i]=spec[i];
for (j=1;j<=order;j++) {
spec[i]+=temp[i+j]*a[j];
}
}
} else {
/* Startup, initial state is zero */
temp[0]=spec[0];
for (i=1;i=0;i--) {
kArray[i] = (fabs(kArray[i])>threshold) ? kArray[i] : 0.0;
if (kArray[i]!=0.0) return i;
}
}
/*****************************************************/
/* QuantizeReflectionCoeffs: */
/* 将给定的反射系数量化为指定的阶数
/*****************************************************/
void QuantizeReflectionCoeffs(int fOrder,
int coeffRes,
double* kArray,
int* indexArray) {
double iqfac,iqfac_m;
int i;
iqfac = ((1<<(coeffRes-1))-0.5)/(PI/2);
iqfac_m = ((1<<(coeffRes-1))+0.5)/(PI/2);
/* Quantize and inverse quantize */
for (i=1;i<=fOrder;i++) {
indexArray[i] = (int)(0.5+(asin(kArray[i])*((kArray[i]>=0)?iqfac:iqfac_m)));
kArray[i] = sin((double)indexArray[i]/((indexArray[i]>=0)?iqfac:iqfac_m));
}
}
/*****************************************************/
/* Autocorrelation, */
/* 针对给定的数据计算自相关函数
/*****************************************************/
void Autocorrelation(int maxOrder, /* Maximum autocorr order */
int dataSize, /* Size of the data array */
double* data, /* Data array */
double* rArray) { /* Autocorrelation array */
int order,index;
for (order=0;order<=maxOrder;order++) {
rArray[order]=0.0;
for (index=0;index