⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 quantize.c

📁 音频编码
💻 C
📖 第 1 页 / 共 5 页
字号:
    cod_info->part2_length        = 0;    cod_info->sfb_lmax        = SBPSY_l;    cod_info->sfb_smin        = SBPSY_s;    cod_info->psy_lmax        = gfc->sfb21_extra ? SBMAX_l : SBPSY_l;    cod_info->psymax          = cod_info->psy_lmax;    cod_info->sfbmax          = cod_info->sfb_lmax;    cod_info->sfbdivide       = 11;    for (sfb = 0; sfb < SBMAX_l; sfb++) {	cod_info->width[sfb]	    = gfc->scalefac_band.l[sfb+1] - gfc->scalefac_band.l[sfb];	cod_info->window[sfb] = 3; /* which is always 0. */    }    if (cod_info->block_type == SHORT_TYPE) {	FLOAT ixwork[576];	FLOAT *ix;        cod_info->sfb_smin        = 0;        cod_info->sfb_lmax        = 0;	if (cod_info->mixed_block_flag) {            /*             *  MPEG-1:      sfbs 0-7 long block, 3-12 short blocks              *  MPEG-2(.5):  sfbs 0-5 long block, 3-12 short blocks             */ 	    cod_info->sfb_smin    = 3;            cod_info->sfb_lmax    = gfc->mode_gr*2 + 4;	}	cod_info->psymax	    = cod_info->sfb_lmax	    + 3*((gfc->sfb21_extra ? SBMAX_s : SBPSY_s) - cod_info->sfb_smin);	cod_info->sfbmax	    = cod_info->sfb_lmax + 3*(SBPSY_s - cod_info->sfb_smin);	cod_info->sfbdivide   = cod_info->sfbmax - 18;	cod_info->psy_lmax    = cod_info->sfb_lmax;	/* re-order the short blocks, for more efficient encoding below */	/* By Takehiro TOMINAGA */	/*	  Within each scalefactor band, data is given for successive	  time windows, beginning with window 0 and ending with window 2.	  Within each window, the quantized values are then arranged in	  order of increasing frequency...	*/	ix = &cod_info->xr[gfc->scalefac_band.l[cod_info->sfb_lmax]];	memcpy(ixwork, cod_info->xr, 576*sizeof(FLOAT));	for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {	    int start = gfc->scalefac_band.s[sfb];	    int end   = gfc->scalefac_band.s[sfb + 1];	    int window, l;	    for (window = 0; window < 3; window++) {		for (l = start; l < end; l++) {		    *ix++ = ixwork[3*l+window];		}	    }	}	j = cod_info->sfb_lmax;	for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {	    cod_info->width[j] = cod_info->width[j+1] = cod_info->width[j + 2]		= gfc->scalefac_band.s[sfb+1] - gfc->scalefac_band.s[sfb];	    cod_info->window[j  ] = 0;	    cod_info->window[j+1] = 1;	    cod_info->window[j+2] = 2;	    j += 3;	}    }    cod_info->count1bits          = 0;      cod_info->sfb_partition_table = nr_of_sfb_block[0][0];    cod_info->slen[0]             = 0;    cod_info->slen[1]             = 0;    cod_info->slen[2]             = 0;    cod_info->slen[3]             = 0;        cod_info->max_nonzero_coeff = 575;    /*  fresh scalefactors are all zero     */    memset(cod_info->scalefac, 0, sizeof(cod_info->scalefac));    psfb21_analogsilence(gfp, gfc, cod_info);}/************************************************************************ * *      bin_search_StepSize() * *  author/date?? * *  binary step size search *  used by outer_loop to get a quantizer step size to start with * ************************************************************************/typedef enum {    BINSEARCH_NONE,    BINSEARCH_UP,     BINSEARCH_DOWN} binsearchDirection_t;int bin_search_StepSize(          lame_internal_flags * const gfc,          gr_info * const cod_info,	 int             desired_rate,    const int             ch,    const FLOAT          xrpow [576] ) {    int nBits;    int CurrentStep = gfc->CurrentStep[ch];    int flag_GoneOver = 0;    int start = gfc->OldValue[ch];    binsearchDirection_t Direction = BINSEARCH_NONE;    cod_info->global_gain = start;    desired_rate -= cod_info->part2_length;    assert(CurrentStep);    do {	int step;        nBits = count_bits(gfc, xrpow, cod_info, 0);          if (CurrentStep == 1 || nBits == desired_rate)	    break; /* nothing to adjust anymore */        if (nBits > desired_rate) {              /* increase Quantize_StepSize */            if (Direction == BINSEARCH_DOWN)                flag_GoneOver = 1;	    if (flag_GoneOver) CurrentStep /= 2;            Direction = BINSEARCH_UP;	    step = CurrentStep;        } else {            /* decrease Quantize_StepSize */            if (Direction == BINSEARCH_UP)                flag_GoneOver = 1;	    if (flag_GoneOver) CurrentStep /= 2;            Direction = BINSEARCH_DOWN;	    step = -CurrentStep;        }	cod_info->global_gain += step;    } while (cod_info->global_gain < 256u);    if (cod_info->global_gain < 0) {	    cod_info->global_gain = 0;	    nBits = count_bits(gfc, xrpow, cod_info, 0);    } else if (cod_info->global_gain > 255) {	    cod_info->global_gain = 255;	    nBits = count_bits(gfc, xrpow, cod_info, 0);    } else if (nBits > desired_rate) {	    cod_info->global_gain++;	    nBits = count_bits(gfc, xrpow, cod_info, 0);    }    gfc->CurrentStep[ch] = (start - cod_info->global_gain >= 4) ? 4 : 2;    gfc->OldValue[ch] = cod_info->global_gain;    cod_info->part2_3_length = nBits;    return nBits;}/************************************************************************ * *      trancate_smallspectrums() * *  Takehiro TOMINAGA 2002-07-21 * *  trancate smaller nubmers into 0 as long as the noise threshold is allowed. * ************************************************************************/static intfloatcompare(const void * v1, const void * v2){    const FLOAT *a = v1, *b = v2;    if (*a > *b) return 1;    if (*a == *b) return 0;    return -1;}voidtrancate_smallspectrums(    lame_internal_flags *gfc,    gr_info		* const gi,    const FLOAT	* const l3_xmin,    FLOAT		* work    ){    int sfb, j, width;    FLOAT distort[SFBMAX];    calc_noise_result dummy;    if ((!(gfc->substep_shaping & 4) && gi->block_type == SHORT_TYPE)	|| gfc->substep_shaping & 0x80)	return;    calc_noise (gfc, gi, l3_xmin, distort, &dummy, 0);    for (j = 0; j < 576; j++) {	FLOAT xr = 0.0;	if (gi->l3_enc[j] != 0)	    xr = fabs(gi->xr[j]);	work[j] = xr;    }    j = 0;    sfb = 8;    if (gi->block_type == SHORT_TYPE)	sfb = 6;    do {	FLOAT allowedNoise, trancateThreshold;	int nsame, start;	width = gi->width[sfb];	j += width;	if (distort[sfb] >= 1.0)	    continue;	qsort(&work[j-width], width, sizeof(FLOAT), floatcompare);	if (work[j - 1] == 0.0)	    continue; /* all zero sfb */	allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb];	trancateThreshold = 0.0;	start = 0;	do {	    FLOAT noise;	    for (nsame = 1; start + nsame < width; nsame++)		if (work[start + j-width] != work[start+j+nsame-width])		    break;	    noise = work[start+j-width] * work[start+j-width] * nsame;	    if (allowedNoise < noise) {		if (start != 0)		    trancateThreshold = work[start+j-width - 1];		break;	    }	    allowedNoise -= noise;	    start += nsame;	} while (start < width);	if (trancateThreshold == 0.0)	    continue;/*	printf("%e %e %e\n", *//*	       trancateThreshold/l3_xmin[sfb], *//*	       trancateThreshold/(l3_xmin[sfb]*start), *//*	       trancateThreshold/(l3_xmin[sfb]*(start+width)) *//*	    ); *//*	if (trancateThreshold > 1000*l3_xmin[sfb]*start) *//*	    trancateThreshold = 1000*l3_xmin[sfb]*start; */	do {	    if (fabs(gi->xr[j - width]) <= trancateThreshold)		gi->l3_enc[j - width] = 0;	} while (--width > 0);    } while (++sfb < gi->psymax);    gi->part2_3_length = noquant_count_bits(gfc, gi, 0);}/************************************************************************* * *      loop_break()                                                * *  author/date?? * *  Function: Returns zero if there is a scalefac which has not been *            amplified. Otherwise it returns one.  * *************************************************************************/inline static intloop_break(     const gr_info        * const cod_info){    int sfb;    for (sfb = 0; sfb < cod_info->sfbmax; sfb++)        if (cod_info->scalefac[sfb]	    + cod_info->subblock_gain[cod_info->window[sfb]] == 0)            return 0;    return 1;}/*  mt 5/99:  Function: Improved calc_noise for a single channel   *//************************************************************************* * *      quant_compare()                                                * *  author/date?? * *  several different codes to decide which quantization is better * *************************************************************************/static double penalties ( double noise ){    return FAST_LOG10( 0.368 + 0.632 * noise * noise * noise );}static double get_klemm_noise(    const FLOAT  * distort,    const gr_info * const gi    ){    int sfb;    double klemm_noise = 1E-37;    for (sfb = 0; sfb < gi->psymax; sfb++)	klemm_noise += penalties(distort[sfb]);    return Max(1e-20, klemm_noise);}inline static int quant_compare(    const int                   quant_comp,          lame_internal_flags	* const gfc,    const calc_noise_result	* const best,          calc_noise_result	* const calc,    const gr_info		* const gi,    const FLOAT		* distort    ){    /*       noise is given in decibels (dB) relative to masking thesholds.       over_noise:  ??? (the previous comment is fully wrong)       tot_noise:   ??? (the previous comment is fully wrong)       max_noise:   max quantization noise      */    int better;    switch (quant_comp) {        default:        case 9: {            if (best->over_count > 0 ) {                /* there are distorted sfb*/	            better = calc->over_SSD <= best->over_SSD;                if (calc->over_SSD == best->over_SSD)                    better = calc->bits < best->bits;            } else {                /* no distorted sfb*/                better = ((calc->max_noise < 0) &&                          ((calc->max_noise*10 + calc->bits) <= (best->max_noise*10 + best->bits)));            }	        break;        }        case 0:	    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  ); 	    break;        case 8:	    calc->max_noise = get_klemm_noise(distort, gi);	    /* pass through */        case 1:	    better = calc->max_noise < best->max_noise; 	    break;        case 2:	    better = calc->tot_noise < best->tot_noise; 	    break;        case 3:		better = (calc->tot_noise < best->tot_noise)		    &&   (calc->max_noise < best->max_noise);	    break;        case 4:	    better = ( calc->max_noise <= 0.0  &&                       best->max_noise >  0.2 )                 ||  ( calc->max_noise <= 0.0  &&                       best->max_noise <  0.0  &&                       best->max_noise >  calc->max_noise-0.2  &&                       calc->tot_noise <  best->tot_noise )                 ||  ( calc->max_noise <= 0.0  &&                       best->max_noise >  0.0  &&                       best->max_noise >  calc->max_noise-0.2  &&                       calc->tot_noise <  best->tot_noise+best->over_noise )                 ||  ( calc->max_noise >  0.0  &&                       best->max_noise > -0.05  &&                       best->max_noise >  calc->max_noise-0.1  &&                       calc->tot_noise+calc->over_noise < best->tot_noise+best->over_noise )                 ||  ( calc->max_noise >  0.0  &&                       best->max_noise > -0.1  &&                       best->max_noise >  calc->max_noise-0.15  &&                       calc->tot_noise+calc->over_noise+calc->over_noise < best->tot_noise+best->over_noise+best->over_noise );            break;        case 5:	    better =   calc->over_noise  < best->over_noise                 ||  ( calc->over_noise == best->over_noise  &&                       calc->tot_noise   < best->tot_noise ); 	    break;        case 6:	    better =   calc->over_noise  < best->over_noise                 ||  ( calc->over_noise == best->over_noise  &&                     ( calc->max_noise   < best->max_noise  		     ||  ( calc->max_noise  == best->max_noise  &&                           calc->tot_noise  <= best->tot_noise )		      )); 	    break;        case 7:	    better =   calc->over_count < best->over_count                   ||  calc->over_noise < best->over_noise; 	    break;    }       if (best->over_count == 0) {        /*            If no distorted bands, only use this quantization            if it is better, and if it uses less bits.            Unfortunately, part2_3_length is sometimes a poor            estimator of the final size at low bitrates.        */        better = better &&                calc->bits < best->bits;    }    return better;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -