📄 quantize.c
字号:
#define MAXNOISEXX
/*
* MP3 quantization
*
* Copyright (c) 1999 Mark Taylor
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <assert.h>
#include "util.h"
#include "l3side.h"
#include "quantize.h"
#include "l3bitstream.h"
#include "reservoir.h"
#include "quantize-pvt.h"
#ifdef HAVEGTK
#include "gtkanal.h"
#endif
#ifdef HAVEGTK
/************************************************************************/
/* updates plotting data */
/************************************************************************/
void
set_pinfo (
gr_info *cod_info,
III_psy_ratio *ratio,
III_scalefac_t *scalefac,
FLOAT8 xr[576],
FLOAT8 xfsf[4][SBPSY_l],
FLOAT8 noise[4],
int gr,
int ch
)
{
int sfb;
FLOAT ifqstep;
int i,l,start,end,bw;
FLOAT8 en0;
D192_3 *xr_s = (D192_3 *)xr;
ifqstep = ( cod_info->scalefac_scale == 0 ) ? .5 : 1.0;
if (cod_info->block_type == SHORT_TYPE) {
for ( i = 0; i < 3; i++ ) {
for ( sfb = 0; sfb < SBPSY_s; sfb++ ) {
start = scalefac_band.s[ sfb ];
end = scalefac_band.s[ sfb + 1 ];
bw = end - start;
for ( en0 = 0.0, l = start; l < end; l++ )
en0 += (*xr_s)[l][i] * (*xr_s)[l][i];
en0=Max(en0/bw,1e-20);
/* conversion to FFT units */
en0 = ratio->en.s[sfb][i]/en0;
pinfo->xfsf_s[gr][ch][3*sfb+i] = xfsf[i+1][sfb]*en0;
pinfo->thr_s[gr][ch][3*sfb+i] = ratio->thm.s[sfb][i];
pinfo->en_s[gr][ch][3*sfb+i] = ratio->en.s[sfb][i];
pinfo->LAMEsfb_s[gr][ch][3*sfb+i]=
-2*cod_info->subblock_gain[i]-ifqstep*scalefac->s[sfb][i];
}
}
}else{
for ( sfb = 0; sfb < SBPSY_l; sfb++ ) {
start = scalefac_band.l[ sfb ];
end = scalefac_band.l[ sfb+1 ];
bw = end - start;
for ( en0 = 0.0, l = start; l < end; l++ )
en0 += xr[l] * xr[l];
en0=Max(en0/bw,1e-20);
/*
printf("diff = %f \n",10*log10(Max(ratio[gr][ch].en.l[sfb],1e-20))
-(10*log10(en0)+150));
*/
/* convert to FFT units */
en0 = ratio->en.l[sfb]/en0;
pinfo->xfsf[gr][ch][sfb] = xfsf[0][sfb]*en0;
pinfo->thr[gr][ch][sfb] = ratio->thm.l[sfb];
pinfo->en[gr][ch][sfb] = ratio->en.l[sfb];
pinfo->LAMEsfb[gr][ch][sfb]=-ifqstep*scalefac->l[sfb];
if (cod_info->preflag && sfb>=11)
pinfo->LAMEsfb[gr][ch][sfb]-=ifqstep*pretab[sfb];
}
}
pinfo->LAMEqss[gr][ch] = cod_info->global_gain;
pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length;
pinfo->over [gr][ch] = noise[0];
pinfo->max_noise [gr][ch] = noise[1];
pinfo->over_noise[gr][ch] = noise[2];
pinfo->tot_noise [gr][ch] = noise[3];
}
#endif
/************************************************************************/
/* iteration_loop() */
/************************************************************************/
void
iteration_loop( lame_global_flags *gfp,
FLOAT8 pe[2][2], FLOAT8 ms_ener_ratio[2],
FLOAT8 xr[2][2][576], III_psy_ratio ratio[2][2],
III_side_info_t *l3_side, int l3_enc[2][2][576],
III_scalefac_t scalefac[2][2])
{
FLOAT8 xfsf[4][SBPSY_l];
FLOAT8 noise[4]; /* over,max_noise,over_noise,tot_noise; */
III_psy_xmin l3_xmin[2];
gr_info *cod_info;
int bitsPerFrame;
int mean_bits;
int ch, gr, i, bit_rate;
iteration_init(gfp,l3_side,l3_enc);
bit_rate = bitrate_table[gfp->version][gfp->bitrate_index];
getframebits(gfp,&bitsPerFrame, &mean_bits);
ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame );
/* quantize! */
for ( gr = 0; gr < gfp->mode_gr; gr++ ) {
int targ_bits[2];
if (convert_mdct)
ms_convert(xr[gr], xr[gr]);
on_pe(gfp,pe,l3_side,targ_bits,mean_bits, gr);
#ifdef RH_SIDE_CBR
#else
if (reduce_sidechannel)
reduce_side(targ_bits,ms_ener_ratio[gr],mean_bits);
#endif
for (ch=0 ; ch < gfp->stereo ; ch ++) {
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
{
calc_xmin(gfp,xr[gr][ch], &ratio[gr][ch], cod_info, &l3_xmin[ch]);
outer_loop( gfp,xr[gr][ch], targ_bits[ch], noise,
&l3_xmin[ch], l3_enc[gr][ch],
&scalefac[gr][ch], cod_info, xfsf, ch);
}
best_scalefac_store(gfp,gr, ch, l3_enc, l3_side, scalefac);
if (gfp->use_best_huffman==1 && cod_info->block_type == NORM_TYPE) {
best_huffman_divide(gr, ch, cod_info, l3_enc[gr][ch]);
}
#ifdef HAVEGTK
if (gfp->gtkflag)
set_pinfo (cod_info, &ratio[gr][ch], &scalefac[gr][ch], xr[gr][ch], xfsf, noise, gr, ch);
#endif
/*#define NORES_TEST */
#ifndef NORES_TEST
ResvAdjust(gfp,cod_info, l3_side, mean_bits );
#endif
/* set the sign of l3_enc */
for ( i = 0; i < 576; i++) {
if (xr[gr][ch][i] < 0)
l3_enc[gr][ch][i] *= -1;
}
}
} /* loop over gr */
#ifdef NORES_TEST
/* replace ResvAdjust above with this code if you do not want
the second granule to use bits saved by the first granule.
when combined with --nores, this is usefull for testing only */
for ( gr = 0; gr < gfp->mode_gr; gr++ ) {
for ( ch = 0; ch < gfp->stereo; ch++ ) {
cod_info = &l3_side->gr[gr].ch[ch].tt;
ResvAdjust(gfp, cod_info, l3_side, mean_bits );
}
}
#endif
ResvFrameEnd(gfp,l3_side, mean_bits );
}
void
set_masking_lower (int VBR_q,int nbits)
{
FLOAT masking_lower_db, adjust;
/* quality setting */
/* Adjust allowed masking based on quality setting */
#ifdef RH_QUALITY_CONTROL
/* - lower masking depending on Quality setting
* - quality control together with adjusted ATH MDCT scaling
* on lower quality setting allocate more noise from
* ATH masking, and on higher quality setting allocate
* less noise from ATH masking.
* - experiments show that going more than 2dB over GPSYCHO's
* limits ends up in very annoying artefacts
*/
static FLOAT dbQ[10]={-6.0,-4.5,-3.0,-1.5,0,0.3,0.6,1.0,1.5,2.0};
assert( VBR_q <= 9 );
assert( VBR_q >= 0 );
masking_lower_db = dbQ[VBR_q];
adjust = 0;
#else
/* masking_lower varies from -8 to +10 db */
masking_lower_db = -6 + 2*VBR_q;
/* adjust by -6(min)..0(max) depending on bitrate */
adjust = (nbits-125)/(2500.0-125.0);
adjust = 4*(adjust-1);
#endif
masking_lower_db += adjust;
masking_lower = pow(10.0,masking_lower_db/10);
}
/************************************************************************
*
* VBR_iteration_loop()
*
* tries to find out how many bits are needed for each granule and channel
* to get an acceptable quantization. An appropriate bitrate will then be
* choosed for quantization. rh 8/99
*
************************************************************************/
void
VBR_iteration_loop (lame_global_flags *gfp,
FLOAT8 pe[2][2], FLOAT8 ms_ener_ratio[2],
FLOAT8 xr[2][2][576], III_psy_ratio ratio[2][2],
III_side_info_t * l3_side, int l3_enc[2][2][576],
III_scalefac_t scalefac[2][2])
{
#ifdef HAVEGTK
plotting_data bst_pinfo;
#endif
gr_info bst_cod_info, clean_cod_info;
III_scalefac_t bst_scalefac;
int bst_l3_enc[576];
III_psy_xmin l3_xmin;
gr_info *cod_info = NULL;
int save_bits[2][2];
FLOAT8 noise[4]; /* over,max_noise,over_noise,tot_noise; */
FLOAT8 targ_noise[4]; /* over,max_noise,over_noise,tot_noise; */
FLOAT8 xfsf[4][SBPSY_l];
int this_bits, dbits;
int used_bits=0;
int min_bits,max_bits,min_mean_bits=0;
int frameBits[15];
int bitsPerFrame;
int bits;
int mean_bits;
int i,ch, gr, analog_silence;
int reparted = 0;
iteration_init(gfp,l3_side,l3_enc);
#ifdef RH_QUALITY_CONTROL
/* with RH_QUALITY_CONTROL we have to set masking_lower only once */
set_masking_lower(gfp->VBR_q, 0 );
#endif
/*******************************************************************
* how many bits are available for each bitrate?
*******************************************************************/
for( gfp->bitrate_index = 1;
gfp->bitrate_index <= gfp->VBR_max_bitrate;
gfp->bitrate_index++ ) {
getframebits (gfp,&bitsPerFrame, &mean_bits);
if (gfp->bitrate_index == gfp->VBR_min_bitrate) {
/* always use at least this many bits per granule per channel */
/* unless we detect analog silence, see below */
min_mean_bits=mean_bits/gfp->stereo;
}
frameBits[gfp->bitrate_index]=
ResvFrameBegin (gfp,l3_side, mean_bits, bitsPerFrame);
}
gfp->bitrate_index=gfp->VBR_max_bitrate;
/*******************************************************************
* how many bits would we use of it?
*******************************************************************/
analog_silence=0;
for (gr = 0; gr < gfp->mode_gr; gr++) {
int num_chan=gfp->stereo;
#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
/* determine quality based on mid channel only */
if (reduce_sidechannel) num_chan=1;
#endif
/* copy data to be quantized into xr */
if (convert_mdct)
ms_convert(xr[gr],xr[gr]);
for (ch = 0; ch < num_chan; ch++) {
int real_bits;
/******************************************************************
* find smallest number of bits for an allowable quantization
******************************************************************/
cod_info = &l3_side->gr[gr].ch[ch].tt;
min_bits = Max(125,min_mean_bits);
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));
save_bits[gr][ch] = 0;
#ifdef HAVEGTK
if (gfp->gtkflag)
set_pinfo(cod_info, &ratio[gr][ch], &scalefac[gr][ch], xr[gr][ch], xfsf, noise, gr, ch);
#endif
analog_silence=1;
continue; /* with next channel */
}
memcpy( &clean_cod_info, cod_info, sizeof(gr_info) );
#ifdef RH_QUALITY_CONTROL
/*
* masking lower already set in the beginning
*/
#else
/*
* has to be set before calculating l3_xmin
*/
set_masking_lower( gfp->VBR_q,2500 );
#endif
/* check for analolg silence */
/* if energy < ATH, set min_bits = 125 */
if (0==calc_xmin(gfp,xr[gr][ch], &ratio[gr][ch], cod_info, &l3_xmin)) {
analog_silence=1;
min_bits=125;
}
if (cod_info->block_type==SHORT_TYPE) {
min_bits += Max(1100,pe[gr][ch]);
min_bits=Min(min_bits,1800);
}
max_bits = 1200 + frameBits[gfp->VBR_max_bitrate]/(gfp->stereo*gfp->mode_gr);
max_bits=Min(max_bits,2500);
max_bits=Max(max_bits,min_bits);
dbits = (max_bits-min_bits)/4;
this_bits = (max_bits+min_bits)/2;
real_bits = max_bits+1;
/* bin search to within +/- 10 bits of optimal */
do {
int better;
assert(this_bits>=min_bits);
assert(this_bits<=max_bits);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -