📄 aac_enc_quantization_fp.c
字号:
*bitsForScaleFactorData = bits_for_scale_factor_data;
common_scalefactor += SF_OFFSET;
if (!pBlock->ns_mode) {
for (i = 0; i < num_scale_factor; i++) {
pStream->scale_factors[i] = (Ipp16s)common_scalefactor;
}
}
}
/****************************************************************************/
static Ipp32f aac_NoiseCalculation(Ipp32f* mdct_scaled,
Ipp32f* mdct_line_abs,
Ipp16s* scalefactor,
Ipp16s* maxXQuant,
Ipp32s width)
{
Ipp32f sf, temp, real_sf, noise;
Ipp32f mdct_rqnt[N_LONG/2];
Ipp16s x_quant_unsigned[N_LONG/2];
sf = (Ipp32f)scalefac_pow[scalefactor[0] + SF_OFFSET];
temp = (Ipp32f)(MAGIC_NUMBER - 0.5f)/sf;
ippsAddC_32f(mdct_scaled, temp, mdct_rqnt, width);
ippsMulC_Low_32f16s(mdct_rqnt, sf, x_quant_unsigned, width);
ippsPow43_16s32f(x_quant_unsigned, mdct_rqnt, width);
ippsCalcSF_16s32f(scalefactor, 0, &real_sf, 1);
ippsMulC_32f_I(real_sf, mdct_rqnt, width);
ippsSub_32f_I(mdct_line_abs, mdct_rqnt, width);
ippsDotProd_32f(mdct_rqnt, mdct_rqnt, width, &noise);
ippsMax_16s(x_quant_unsigned, width, maxXQuant);
return noise;
}
/****************************************************************************/
void aac_FindSF(sEnc_individual_channel_stream* pStream,
sQuantizationData* qData,
Ipp32f* mdct_scaled,
Ipp32f* mdct_line_abs,
Ipp32s* startSF,
Ipp32s* finishSF,
Ipp16s* scalefac,
Ipp16s* maxXQuant)
{
Ipp16s scalefactor;
Ipp32f noise;
Ipp32s sfb;
Ipp32f *noiseThr = qData->noiseThr;
Ipp32s stopSF;
Ipp32s *sfb_offset = pStream->sfb_offset;
Ipp32s *sfb_width = pStream->sfb_width;
for (sfb = 0; sfb < pStream->num_window_groups * pStream->max_sfb; sfb++) {
Ipp32s sfb_start = sfb_offset[sfb];
Ipp32s width = sfb_width[sfb];
Ipp32s start_scalefac = startSF[sfb];
Ipp32s finish_scalefac = finishSF[sfb];
Ipp32s i, ind;
Ipp32f sqrtMdctLine = 0;
Ipp16s maxXQuantSaved;
Ipp32f minNoise;
for (i = 0; i < width; i++) {
sqrtMdctLine += (Ipp32f)sqrt(mdct_line_abs[sfb_start+i]);
}
if ((noiseThr[sfb] > 0) && (qData->energy[sfb] >= noiseThr[sfb])) {
Ipp32f tmp;
tmp = (Ipp32f)log((27.0/4.0)*noiseThr[sfb]/sqrtMdctLine)/(Ipp32f)log(2);
tmp *= (Ipp32f)8/(Ipp32f)3;
scalefactor = (Ipp16s)(tmp+0.5);
if (scalefactor < start_scalefac) scalefactor = (Ipp16s)start_scalefac;
if (scalefactor > finish_scalefac) scalefactor = (Ipp16s)finish_scalefac;
noise = aac_NoiseCalculation(mdct_scaled + sfb_start, mdct_line_abs + sfb_start,
&scalefactor, maxXQuant + sfb, width);
minNoise = noise;
ind = 0;
maxXQuantSaved = maxXQuant[sfb];
/* Let's check other scalefactors. */
/* Perhaps quantization with bigger scalefactors will give us less noise. */
stopSF = finish_scalefac - scalefactor + 1;
if (stopSF > 5) stopSF = 5; /* magic value :) */
for (i = 1; i < stopSF; i++) {
Ipp16s scalefactor1 = scalefactor + (Ipp16s)i;
if (scalefactor1 > finish_scalefac) scalefactor1 = (Ipp16s)finish_scalefac;
noise = aac_NoiseCalculation(mdct_scaled + sfb_start, mdct_line_abs + sfb_start,
&scalefactor1, maxXQuant + sfb, width);
if (noise < minNoise) {
minNoise = noise;
ind = i;
maxXQuantSaved = maxXQuant[sfb];
}
}
scalefac[sfb] = scalefactor + (Ipp16s)ind;
maxXQuant[sfb] = maxXQuantSaved;
} else {
scalefac[sfb] = -100;
maxXQuant[sfb] = 0;
}
}
}
/****************************************************************************/
void aac_UpdateSF(sEnc_individual_channel_stream* pStream,
Ipp32f* mdct_scaled,
Ipp32f* mdct_line_abs,
Ipp32s* startSF,
Ipp16s* scalefac,
Ipp16s* maxXQuant,
Ipp32s minSf,
Ipp32f bitsToPeCoeff,
Ipp32f possibleAddBits)
{
Ipp32s numScf[MAX_SECTION_NUMBER];
Ipp32s sfb_start[MAX_SECTION_NUMBER];
Ipp32s width[MAX_SECTION_NUMBER];
Ipp32s transferTable[MAX_SECTION_NUMBER];
Ipp32s index[MAX_SECTION_NUMBER][61];
Ipp32s tmpMaxXQuant[MAX_SECTION_NUMBER][61];
Ipp32f numBits[MAX_SECTION_NUMBER][61];
Ipp16s scalefactor0, mXQuant;
Ipp32f minBits, iniBits;
Ipp32f minNoise;
Ipp32s i, j, sfb, bestIndx, realSfb;
Ipp32s *sfb_offset = pStream->sfb_offset;
Ipp32s *sfb_width = pStream->sfb_width;
Ipp32s numSfb = pStream->num_window_groups * pStream->max_sfb;
Ipp32f coeff = 0.3f * 3.0f/8.0f / (bitsToPeCoeff * 3.32f); /* 3.32 ~ 1/log10(2) */
realSfb = 0;
for (sfb = 0; sfb < numSfb; sfb++) {
/* Exclude scalefactor bands which contain only zero elements */
if (maxXQuant[sfb] != 0) {
if (minSf > startSF[sfb]) {
numScf[realSfb] = scalefac[sfb] - minSf + 1;
} else {
numScf[realSfb] = scalefac[sfb] - startSF[sfb] + 1;
}
width[realSfb] = sfb_width[sfb];
for (i = 0; i < numScf[realSfb]; i++) {
numBits[realSfb][i] = coeff * i * width[realSfb];
}
sfb_start[realSfb] = sfb_offset[sfb];
transferTable[realSfb] = sfb;
realSfb++;
}
}
if (realSfb > 0) {
numSfb = realSfb;
iniBits = 0;
for (sfb = 1; sfb < numSfb; sfb++) {
Ipp32f addBits = possibleAddBits/(numSfb - sfb + 1);
iniBits += sf_huff_codebook[2*(scalefac[transferTable[sfb]] -
scalefac[transferTable[sfb-1]] + SF_MID)];
for (i = 0; i < numScf[sfb]; i++) {
Ipp32f bits[61];
Ipp32s bestIdx;
Ipp32s deltaSF = scalefac[transferTable[sfb]] - i -
scalefac[transferTable[sfb-1]];
minBits = bits[0] = sf_huff_codebook[2*(deltaSF + SF_MID)] +
numBits[sfb-1][0];
bestIdx = 0;
deltaSF++;
for (j = 1; j < numScf[sfb-1]; j++) {
bits[j] = sf_huff_codebook[2*(deltaSF + SF_MID)] + numBits[sfb-1][j];
if (minBits > bits[j]) {
minBits = bits[j];
bestIdx = j;
}
deltaSF++;
}
scalefactor0 = scalefac[transferTable[sfb-1]] - (Ipp16s)bestIdx;
minNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[sfb-1],
mdct_line_abs + sfb_start[sfb-1],
&scalefactor0, &mXQuant, width[sfb-1]);
index[sfb-1][i] = bestIdx;
tmpMaxXQuant[sfb-1][i] = mXQuant;
scalefactor0 = scalefac[transferTable[sfb-1]];
for (j = 0; j < numScf[sfb-1]; j++) {
if (bits[j] <= minBits + addBits) {
Ipp32f tmpNoise;
tmpNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[sfb-1],
mdct_line_abs + sfb_start[sfb-1],
&scalefactor0, &mXQuant, width[sfb-1]);
if (tmpNoise <= minNoise) {
minNoise = tmpNoise;
index[sfb-1][i] = j;
tmpMaxXQuant[sfb-1][i] = mXQuant;
}
}
scalefactor0--;
}
numBits[sfb][i] += bits[index[sfb-1][i]];
possibleAddBits -= bits[index[sfb-1][i]] - minBits;
}
}
scalefactor0 = scalefac[transferTable[numSfb - 1]];
minBits = numBits[numSfb-1][0];
minNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[numSfb-1],
mdct_line_abs + sfb_start[numSfb-1],
&scalefactor0, &mXQuant, width[numSfb-1]);
index[sfb-1][0] = 0;
tmpMaxXQuant[sfb-1][0] = mXQuant;
scalefactor0--;
for (j = 1; j < numScf[numSfb - 1]; j++) {
Ipp32f tmpBits;
tmpBits = numBits[numSfb - 1][j];
if (tmpBits < minBits) {
Ipp32f tmpNoise;
tmpNoise = aac_NoiseCalculation(mdct_scaled + sfb_start[numSfb-1],
mdct_line_abs + sfb_start[numSfb-1],
&scalefactor0, &mXQuant, width[numSfb-1]);
if (tmpNoise < minNoise) {
minNoise = tmpNoise;
minBits = tmpBits;
index[numSfb-1][0] = j;
tmpMaxXQuant[numSfb-1][0] = mXQuant;
}
}
scalefactor0--;
}
bestIndx = index[numSfb-1][0];
mXQuant = (Ipp16s)tmpMaxXQuant[numSfb-1][0];
for (sfb = numSfb-1; sfb > 0; sfb--) {
/* Include scalefactor bands which contain only zero elements */
scalefac[transferTable[sfb]] -= (Ipp16s)bestIndx;
maxXQuant[transferTable[sfb]] = mXQuant;
mXQuant = (Ipp16s)tmpMaxXQuant[sfb-1][bestIndx];
bestIndx = index[sfb-1][bestIndx];
}
/* Include scalefactor bands which contain only zero elements */
scalefac[transferTable[0]] -= (Ipp16s)bestIndx;
maxXQuant[transferTable[0]] = mXQuant;
}
}
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -