📄 quantize.c
字号:
if( this_bits >= real_bits ){
/*
* we already found a quantization with fewer bits
* so we can skip this try
*/
this_bits -= dbits;
dbits /= 2;
continue; /* skips the rest of this do-while loop */
}
/* VBR will look for a quantization which has better values
* then those specified below.*/
targ_noise[0]=0; /* over */
targ_noise[1]=0; /* max_noise */
targ_noise[2]=0; /* over_noise */
targ_noise[3]=0; /* tot_noise */
targ_noise[0]=Max(0,targ_noise[0]);
targ_noise[2]=Max(0,targ_noise[2]);
/*
* OK, start with a fresh setting
* - scalefac will be set up by outer_loop
* - l3_enc will be set up by outer_loop
* + cod_info we will restore our initialized one, see below
*/
memcpy( cod_info, &clean_cod_info, sizeof(gr_info) );
#ifdef RH_QUALITY_CONTROL
/*
* there is no need for a recalculation of l3_xmin,
* because masking_lower did not change within this do-while
*/
#else
/* quality setting */
set_masking_lower( gfp->VBR_q,this_bits );
/*
* compute max allowed distortion, masking lower has changed
*/
calc_xmin(gfp,xr[gr][ch], &ratio[gr][ch], cod_info, &l3_xmin);
#endif
outer_loop( gfp,xr[gr][ch], this_bits, noise,
&l3_xmin, l3_enc[gr][ch],
&scalefac[gr][ch], cod_info, xfsf,
ch);
/* is quantization as good as we are looking for ? */
better=VBR_compare((int)targ_noise[0],targ_noise[3],targ_noise[2],
targ_noise[1],(int)noise[0],noise[3],noise[2],
noise[1]);
#ifdef HAVEGTK
if (gfp->gtkflag)
set_pinfo(cod_info, &ratio[gr][ch], &scalefac[gr][ch], xr[gr][ch], xfsf, noise, gr, ch);
#endif
if (better) {
/*
* we now know it can be done with "real_bits"
* and maybe we can skip some iterations
*/
real_bits = cod_info->part2_3_length;
/*
* save best quantization so far
*/
memcpy( &bst_scalefac, &scalefac[gr][ch], sizeof(III_scalefac_t) );
memcpy( bst_l3_enc, l3_enc [gr][ch], sizeof(int)*576 );
memcpy( &bst_cod_info, cod_info, sizeof(gr_info) );
#ifdef HAVEGTK
if (gfp->gtkflag)
memcpy( &bst_pinfo, pinfo, sizeof(plotting_data) );
#endif
/*
* try with fewer bits
*/
this_bits -= dbits;
} else {
/*
* try with more bits
*/
this_bits += dbits;
}
dbits /= 2;
} while (dbits>10) ;
if (real_bits <= max_bits)
{
/* restore best quantization found */
memcpy( cod_info, &bst_cod_info, sizeof(gr_info) );
memcpy( &scalefac[gr][ch], &bst_scalefac, sizeof(III_scalefac_t) );
memcpy( l3_enc [gr][ch], bst_l3_enc, sizeof(int)*576 );
#ifdef HAVEGTK
if (gfp->gtkflag)
memcpy( pinfo, &bst_pinfo, sizeof(plotting_data) );
#endif
}
assert((int)cod_info->part2_3_length <= max_bits);
save_bits[gr][ch] = cod_info->part2_3_length;
used_bits += save_bits[gr][ch];
} /* for ch */
} /* for gr */
#ifdef RH_SIDE_VBR
/* my experiences are, that side channel reduction
* does more harm than good when VBR encoding
* (Robert.Hegemann@gmx.de 2000-02-18)
*/
#else
if (reduce_sidechannel) {
/* number of bits needed was found for MID channel above. Use formula
* (fixed bitrate code) to set the side channel bits */
for (gr = 0; gr < gfp->mode_gr; gr++) {
FLOAT8 fac = .33*(.5-ms_ener_ratio[gr])/.5;
save_bits[gr][1]=((1-fac)/(1+fac))*save_bits[gr][0];
save_bits[gr][1]=Max(125,save_bits[gr][1]);
used_bits += save_bits[gr][1];
}
}
#endif
/******************************************************************
* find lowest bitrate able to hold used bits
******************************************************************/
for( gfp->bitrate_index = (analog_silence ? 1 : gfp->VBR_min_bitrate );
gfp->bitrate_index < gfp->VBR_max_bitrate;
gfp->bitrate_index++ )
if( used_bits <= frameBits[gfp->bitrate_index] ) break;
/*******************************************************************
* calculate quantization for this bitrate
*******************************************************************/
getframebits (gfp,&bitsPerFrame, &mean_bits);
bits=ResvFrameBegin (gfp,l3_side, mean_bits, bitsPerFrame);
/* repartion available bits in same proportion */
if (used_bits > bits ) {
reparted = 1;
for( gr = 0; gr < gfp->mode_gr; gr++) {
for(ch = 0; ch < gfp->stereo; ch++) {
save_bits[gr][ch]=(save_bits[gr][ch]*frameBits[gfp->bitrate_index])/used_bits;
}
}
used_bits=0;
for( gr = 0; gr < gfp->mode_gr; gr++) {
for(ch = 0; ch < gfp->stereo; ch++) {
used_bits += save_bits[gr][ch];
}
}
}
assert(used_bits <= bits);
for(gr = 0; gr < gfp->mode_gr; gr++) {
for(ch = 0; ch < gfp->stereo; ch++) {
#ifdef RH_SIDE_VBR
if (reparted)
#else
if (reparted || (reduce_sidechannel && ch == 1))
#endif
{
cod_info = &l3_side->gr[gr].ch[ch].tt;
if (!init_outer_loop(gfp,xr[gr][ch], cod_info))
{
/* xr contains no energy
* cod_info was set in init_outer_loop above
*/
memset(&scalefac[gr][ch],0,sizeof(III_scalefac_t));
memset(l3_enc[gr][ch],0,576*sizeof(int));
noise[0]=noise[1]=noise[2]=noise[3]=0;
}
else
{
#ifdef RH_QUALITY_CONTROL
/*
* masking lower already set in the beginning
*/
#else
/* quality setting */
set_masking_lower( gfp->VBR_q,save_bits[gr][ch] );
#endif
calc_xmin(gfp,xr[gr][ch], &ratio[gr][ch], cod_info, &l3_xmin);
outer_loop( gfp,xr[gr][ch], save_bits[gr][ch], noise,
&l3_xmin, l3_enc[gr][ch],
&scalefac[gr][ch], cod_info, xfsf, ch);
}
#ifdef HAVEGTK
if (gfp->gtkflag)
set_pinfo(cod_info, &ratio[gr][ch], &scalefac[gr][ch], xr[gr][ch], xfsf, noise, gr, ch);
#endif
}
}
}
/*******************************************************************
* update reservoir status after FINAL quantization/bitrate
*******************************************************************/
for (gr = 0; gr < gfp->mode_gr; gr++)
for (ch = 0; ch < gfp->stereo; ch++) {
cod_info = &l3_side->gr[gr].ch[ch].tt;
best_scalefac_store(gfp,gr, ch, l3_enc, l3_side, scalefac);
if (cod_info->block_type == NORM_TYPE) {
best_huffman_divide(gr, ch, cod_info, l3_enc[gr][ch]);
}
#ifdef HAVEGTK
if (gfp->gtkflag)
pinfo->LAMEmainbits[gr][ch]=cod_info->part2_3_length;
#endif
ResvAdjust (gfp,cod_info, l3_side, mean_bits);
}
/*******************************************************************
* set the sign of l3_enc
*******************************************************************/
for (gr = 0; gr < gfp->mode_gr; gr++)
for (ch = 0; ch < gfp->stereo; ch++) {
/*
* is the following code correct?
*
int *pi = &l3_enc[gr][ch][0];
for (i = 0; i < 576; i++) {
FLOAT8 pr = xr[gr][ch][i];
if ((pr < 0) && (pi[i] > 0))
pi[i] *= -1;
}
*
* or is the code used for CBR correct?
*/
for ( i = 0; i < 576; i++) {
if (xr[gr][ch][i] < 0) l3_enc[gr][ch][i] *= -1;
}
}
ResvFrameEnd (gfp,l3_side, mean_bits);
}
/************************************************************************/
/* init_outer_loop mt 6/99 */
/* returns 0 if all energies in xr are zero, else 1 */
/************************************************************************/
int init_outer_loop(lame_global_flags *gfp,
FLOAT8 xr[576], /* could be L/R OR MID/SIDE */
gr_info *cod_info)
{
int i;
for ( i = 0; i < 4; i++ )
cod_info->slen[i] = 0;
cod_info->sfb_partition_table = &nr_of_sfb_block[0][0][0];
cod_info->part2_3_length = 0;
cod_info->big_values = 0;
cod_info->count1 = 0;
cod_info->scalefac_compress = 0;
cod_info->table_select[0] = 0;
cod_info->table_select[1] = 0;
cod_info->table_select[2] = 0;
cod_info->subblock_gain[0] = 0;
cod_info->subblock_gain[1] = 0;
cod_info->subblock_gain[2] = 0;
cod_info->region0_count = 0;
cod_info->region1_count = 0;
cod_info->part2_length = 0;
cod_info->preflag = 0;
cod_info->scalefac_scale = 0;
cod_info->global_gain = 210;
cod_info->count1table_select= 0;
cod_info->count1bits = 0;
if (gfp->experimentalZ) {
/* compute subblock gains */
int j,b; FLOAT8 en[3],mx;
if ((cod_info->block_type==SHORT_TYPE) ) {
/* estimate energy within each subblock */
for (b=0; b<3; b++) en[b]=0;
for ( i=0,j = 0; j < 192; j++ ) {
for (b=0; b<3; b++) {
en[b]+=xr[i] * xr[i];
i++;
}
}
mx = 1e-12;
for (b=0; b<3; b++) mx=Max(mx,en[b]);
for (b=0; b<3; b++) en[b] = Max(en[b],1e-12)/mx;
/*printf("ener = %4.2f %4.2f %4.2f \n",en[0],en[1],en[2]);*/
/* pick gain so that 2^(2gain)*en[0] = 1 */
/* gain = .5* log( 1/en[0] )/LOG2 = -.5*log(en[])/LOG2 */
for (b=0; b<3; b++) {
cod_info->subblock_gain[b] = (int)(-.5*log(en[b])/LOG2 + 0.5);
if (cod_info->subblock_gain[b] > 2)
cod_info->subblock_gain[b]=2;
if (cod_info->subblock_gain[b] < 0)
cod_info->subblock_gain[b]=0;
}
/*
* check if there is some energy we have to quantize
* if so, then return 1 else 0
*/
if (1e-99 < en[0]+en[1]+en[2])
return 1;
else
return 0;
}
}
/*
* check if there is some energy we have to quantize
* if so, then return 1 else 0
*/
for (i=0; i<576; i++)
if ( 1e-99 < fabs (xr[i]) )
return 1;
return 0;
}
/************************************************************************/
/* outer_loop */
/************************************************************************/
/* Function: The outer iteration loop controls the masking conditions */
/* of all scalefactorbands. It computes the best scalefac and */
/* global gain. This module calls the inner iteration loop
*
* mt 5/99 completely rewritten to allow for bit reservoir control,
* mid/side channels with L/R or mid/side masking thresholds,
* and chooses best quantization instead of last quantization when
* no distortion free quantization can be found.
*
* added VBR support mt 5/99
************************************************************************/
void outer_loop(
lame_global_flags *gfp,
FLOAT8 xr[576],
int targ_bits,
FLOAT8 best_noise[4],
III_psy_xmin *l3_xmin, /* the allowed distortion of the scalefactor */
int l3_enc[576], /* vector of quantized values ix(0..575) */
III_scalefac_t *scalefac, /* scalefactors */
gr_info *cod_info,
FLOAT8 xfsf[4][SBPSY_l],
int ch)
{
III_scalefac_t scalefac_w;
gr_info save_cod_info;
int l3_enc_w[576];
int i, iteration;
int status,bits_found=0;
int huff_bits;
FLOAT8 xrpow[576],temp;
int better;
int over=0;
FLOAT8 max_noise;
FLOAT8 over_noise;
FLOAT8 tot_noise;
int best_over=100;
FLOAT8 best_max_noise=0;
FLOAT8 best_over_noise=0;
FLOAT8 best_tot_noise=0;
FLOAT8 xfsf_w[4][SBPSY_l];
FLOAT8 distort[4][SBPSY_l];
int compute_stepsize=1;
int notdone=1;
/* BEGIN MAIN LOOP */
iteration = 0;
while ( notdone ) {
static int OldValue[2] = {180, 180};
int try_scale=0;
iteration ++;
if (compute_stepsize) {
/* init and compute initial quantization step */
compute_stepsize=0;
/* reset of iteration variables */
memset(&scalefac_w, 0, sizeof(III_scalefac_t));
for (i=0;i<576;i++) {
temp=fabs(xr[i]);
xrpow[i]=sqrt(sqrt(temp)*temp);
}
bits_found=bin_search_StepSize2(gfp,targ_bits,OldValue[ch],
l3_enc_w,xrpow,cod_info);
OldValue[ch] = cod_info->global_gain;
}
/* inner_loop starts with the initial quantization step computed above
* and slowly increases until the bits < huff_bits.
* Thus it is important not to start with too large of an inital
* quantization step. Too small is ok, but inner_loop will take longer
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -