📄 aacquant.c
字号:
static int InnerLoop(CoderInfo *coderInfo,
double *xr_pow,
int *xi,
int max_bits)
{
int bits;
/* count bits */
bits = CountBits(coderInfo, xi, xr_pow);
/* increase quantizer stepsize until needed bits are below maximum */
while (bits > max_bits) {
coderInfo->global_gain += 1;
bits = CountBits(coderInfo, xi, xr_pow);
}
return bits;
}
static void CalcAllowedDist(PsyInfo *psyInfo, int *cb_width, int num_cb,
double *xr, double *xmin)
{
int sfb, start, end, i;
double en0, xmin0;
end = 0;
for (sfb = 0; sfb < num_cb; sfb++)
{
start = end;
end += cb_width[sfb];
for (en0 = 0.0, i = start; i < end; i++)
{
en0 += xr[i] * xr[i];
}
en0 /= cb_width[sfb];
xmin0 = psyInfo->maskEn[sfb];
if (xmin0 > 0.0)
xmin0 = en0 * psyInfo->maskThr[sfb] / xmin0;
xmin[sfb] = xmin0;
}
}
static int OuterLoop(CoderInfo *coderInfo,
double *xr,
double *xr_pow,
int *xi,
double *xmin,
int target_bits)
{
int sb;
int notdone, over, better;
int store_global_gain, outer_loop_count;
int best_global_gain, age;
calcNoiseResult noiseInfo;
calcNoiseResult bestNoiseInfo;
double sfQuantFac = pow(2.0, 0.1875);
int *scale_factor = coderInfo->scale_factor;
int *best_scale_factor;
int *save_xi;
double *distort;
distort = (double*)AllocMemory(MAX_SCFAC_BANDS*sizeof(double));
best_scale_factor = (int*)AllocMemory(MAX_SCFAC_BANDS*sizeof(int));
save_xi = (int*)AllocMemory(FRAME_LEN*sizeof(int));
notdone = 1;
outer_loop_count = 0;
do { /* outer iteration loop */
over = 0;
outer_loop_count++;
InnerLoop(coderInfo, xr_pow, xi, target_bits);
store_global_gain = coderInfo->global_gain;
over = CalcNoise(coderInfo, xr, xi, coderInfo->requantFreq, distort, xmin, &noiseInfo);
if (outer_loop_count == 1)
better = 1;
else
better = QuantCompare(&bestNoiseInfo, &noiseInfo);
if (better) {
bestNoiseInfo = noiseInfo;
best_global_gain = store_global_gain;
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
best_scale_factor[sb] = scale_factor[sb];
}
memcpy(save_xi, xi, sizeof(int)*BLOCK_LEN_LONG);
age = 0;
} else
age++;
if (age > 3 && bestNoiseInfo.over_count == 0)
break;
notdone = BalanceNoise(coderInfo, distort, xr_pow);
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
if (scale_factor[sb] > 30)
notdone = 0;
if (notdone == 0)
break;
} while (1);
coderInfo->global_gain = best_global_gain;
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
scale_factor[sb] = best_scale_factor[sb];
}
memcpy(xi, save_xi, sizeof(int)*BLOCK_LEN_LONG);
if (best_scale_factor) FreeMemory(best_scale_factor);
if (save_xi) FreeMemory(save_xi);
if (distort) FreeMemory(distort);
return 0;
}
static int CalcNoise(CoderInfo *coderInfo,
double *xr,
int *xi,
double *requant_xr,
double *error_energy,
double *xmin,
calcNoiseResult *res
)
{
int i, sb, sbw;
int over = 0, count = 0;
double invQuantFac;
double linediff, noise;
double over_noise = 1;
double tot_noise = 1;
double max_noise = 1E-20;
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) {
sbw = coderInfo->sfb_offset[sb+1] - coderInfo->sfb_offset[sb];
invQuantFac = pow(2.0, -0.25*(coderInfo->scale_factor[sb] - coderInfo->global_gain));
error_energy[sb] = 0.0;
for (i = coderInfo->sfb_offset[sb]; i < coderInfo->sfb_offset[sb+1]; i++){
requant_xr[i] = pow43[xi[i]] * invQuantFac;
/* measure the distortion in each scalefactor band */
linediff = fabs(xr[i]) - requant_xr[i];
error_energy[sb] += linediff * linediff;
}
error_energy[sb] = error_energy[sb] / sbw;
noise = error_energy[sb] / xmin[sb];
/* multiplying here is adding in dB */
tot_noise *= max(noise, 1E-20);
if (noise>1) {
over++;
/* multiplying here is adding in dB */
over_noise *= noise;
}
max_noise = max(max_noise,noise);
error_energy[sb] = noise;
count++;
}
res->tot_count = count;
res->over_count = over;
res->tot_noise = 10.*log10(max(1e-20,tot_noise ));
res->over_noise = 10.*log10(max(1e+00,over_noise));
res->max_noise = 10.*log10(max(1e-20,max_noise ));
return over;
}
static int QuantCompare(calcNoiseResult *best,
calcNoiseResult *calc)
{
int better;
better = calc->over_count < best->over_count
|| ( calc->over_count == best->over_count &&
calc->over_noise < best->over_noise )
|| ( calc->over_count == best->over_count &&
calc->over_noise == best->over_noise &&
calc->tot_noise < best->tot_noise );
return better;
}
static int BalanceNoise(CoderInfo *coderInfo,
double *distort,
double *xrpow)
{
int status = 0, sb;
AmpScalefacBands(coderInfo, distort, xrpow);
for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
if (coderInfo->scale_factor[sb] == 0)
status = 1;
return status;
}
static void AmpScalefacBands(CoderInfo *coderInfo,
double *distort,
double *xr_pow)
{
int start, end, l, sfb;
double ifqstep, distort_thresh;
ifqstep = pow(2.0, 0.1875);
distort_thresh = -900;
for (sfb = 0; sfb < coderInfo->nr_of_sfb; sfb++) {
distort_thresh = max(distort[sfb], distort_thresh);
}
if (distort_thresh>1.0)
distort_thresh=1.0;
else
distort_thresh *= .95;
for ( sfb = 0; sfb < coderInfo->nr_of_sfb; sfb++ ) {
if (distort[sfb] > distort_thresh) {
coderInfo->scale_factor[sfb]++;
start = coderInfo->sfb_offset[sfb];
end = coderInfo->sfb_offset[sfb+1];
for ( l = start; l < end; l++ ) {
xr_pow[l] *= ifqstep;
}
}
}
}
static int SortForGrouping(CoderInfo* coderInfo,
PsyInfo *psyInfo,
ChannelInfo *channelInfo,
int *sfb_width_table,
double *xr)
{
int i,j,ii;
int index = 0;
double xr_tmp[1024];
double thr_tmp[150];
double en_tmp[150];
int book=1;
int group_offset=0;
int k=0;
int windowOffset = 0;
/* set up local variables for used quantInfo elements */
int* sfb_offset = coderInfo->sfb_offset;
int* nr_of_sfb = &(coderInfo->nr_of_sfb);
int* window_group_length;
int num_window_groups;
*nr_of_sfb = coderInfo->max_sfb; /* Init to max_sfb */
window_group_length = coderInfo->window_group_length;
num_window_groups = coderInfo->num_window_groups;
/* calc org sfb_offset just for shortblock */
sfb_offset[k]=0;
for (k=1 ; k <*nr_of_sfb+1; k++) {
sfb_offset[k] = sfb_offset[k-1] + sfb_width_table[k-1];
}
/* sort the input spectral coefficients */
index = 0;
group_offset=0;
for (i=0; i< num_window_groups; i++) {
for (k=0; k<*nr_of_sfb; k++) {
for (j=0; j < window_group_length[i]; j++) {
for (ii=0;ii< sfb_width_table[k];ii++)
xr_tmp[index++] = xr[ii+ sfb_offset[k] + 128*j +group_offset];
}
}
group_offset += 128*window_group_length[i];
}
for (k=0; k<1024; k++){
xr[k] = xr_tmp[k];
}
/* now calc the new sfb_offset table for the whole p_spectrum vector*/
index = 0;
sfb_offset[index++] = 0;
windowOffset = 0;
for (i=0; i < num_window_groups; i++) {
for (k=0 ; k <*nr_of_sfb; k++) {
int w;
double worstTHR;
double worstEN;
/* for this window group and this band, find worst case inverse sig-mask-ratio */
if (channelInfo->msInfo.is_present && channelInfo->msInfo.ms_usedS[windowOffset][k]) {
worstTHR = psyInfo->maskThrSMS[windowOffset][k];
worstEN = psyInfo->maskEnSMS[windowOffset][k];
} else {
worstTHR = psyInfo->maskThrS[windowOffset][k];
worstEN = psyInfo->maskEnS[windowOffset][k];
}
for (w=1;w<window_group_length[i];w++) {
if (channelInfo->msInfo.is_present && channelInfo->msInfo.ms_usedS[w+windowOffset][k]) {
if (psyInfo->maskThrSMS[w+windowOffset][k] < worstTHR) {
worstTHR = psyInfo->maskThrSMS[w+windowOffset][k];
worstEN = psyInfo->maskEnSMS[w+windowOffset][k];
}
} else {
if (psyInfo->maskThrS[w+windowOffset][k] < worstTHR) {
worstTHR = psyInfo->maskThrS[w+windowOffset][k];
worstEN = psyInfo->maskEnS[w+windowOffset][k];
}
}
}
thr_tmp[k+ i* *nr_of_sfb] = worstTHR;
en_tmp[k+ i* *nr_of_sfb] = worstEN;
sfb_offset[index] = sfb_offset[index-1] + sfb_width_table[k]*window_group_length[i] ;
index++;
}
windowOffset += window_group_length[i];
}
*nr_of_sfb = *nr_of_sfb * num_window_groups; /* Number interleaved bands. */
for (k = 0; k < *nr_of_sfb; k++){
psyInfo->maskThr[k] = thr_tmp[k];
psyInfo->maskEn[k] = en_tmp[k];
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -