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

📄 quantize.c

📁 音频编码
💻 C
📖 第 1 页 / 共 5 页
字号:
}/************************************************************************* * *          amp_scalefac_bands()  * *  author/date?? *         *  Amplify the scalefactor bands that violate the masking threshold. *  See ISO 11172-3 Section C.1.5.4.3.5 *  *  distort[] = noise/masking *  distort[] > 1   ==> noise is not masked *  distort[] < 1   ==> noise is masked *  max_dist = maximum value of distort[] *   *  Three algorithms: *  noise_shaping_amp *        0             Amplify all bands with distort[]>1. * *        1             Amplify all bands with distort[] >= max_dist^(.5); *                     ( 50% in the db scale) * *        2             Amplify first band with distort[] >= max_dist; *                        * *  For algorithms 0 and 1, if max_dist < 1, then amplify all bands  *  with distort[] >= .95*max_dist.  This is to make sure we always *  amplify at least one band.   *  * *************************************************************************/static void amp_scalefac_bands(    lame_global_flags *gfp,    gr_info  *const cod_info,     FLOAT *distort,    FLOAT xrpow[576],    int bRefine){    lame_internal_flags *gfc=gfp->internal_flags;    int j, sfb;    FLOAT ifqstep34, trigger;    int noise_shaping_amp;    if (cod_info->scalefac_scale == 0) {	ifqstep34 = 1.29683955465100964055; /* 2**(.75*.5)*/    } else {	ifqstep34 = 1.68179283050742922612;  /* 2**(.75*1) */    }    /* compute maximum value of distort[]  */    trigger = 0;    for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {	if (trigger < distort[sfb])	    trigger = distort[sfb];    }    noise_shaping_amp = gfc->noise_shaping_amp;    if (noise_shaping_amp == 3) {        if (bRefine == 1)            noise_shaping_amp = 2;        else            noise_shaping_amp = 1;    }    switch (noise_shaping_amp) {    case 2:	/* amplify exactly 1 band */	break;    case 1:	/* amplify bands within 50% of max (on db scale) */	if (trigger>1.0)	    trigger = pow(trigger, .5);	else	    trigger *= .95;	break;    case 0:    default:	/* ISO algorithm.  amplify all bands with distort>1 */	if (trigger>1.0)	    trigger=1.0;	else	    trigger *= .95;	break;    }    j = 0;    for (sfb = 0; sfb < cod_info->sfbmax; sfb++ ) {	int width = cod_info->width[sfb];	int l;	j += width;	if (distort[sfb] < trigger)	    continue;	if (gfc->substep_shaping & 2) {	    gfc->pseudohalf[sfb] = !gfc->pseudohalf[sfb];	    if (!gfc->pseudohalf[sfb] && gfc->noise_shaping_amp==2)		return;	}	cod_info->scalefac[sfb]++;    for (l = -width; l < 0; l++) {	    xrpow[j+l] *= ifqstep34;        if (xrpow[j+l] > cod_info->xrpow_max)            cod_info->xrpow_max = xrpow[j+l];    }	if (gfc->noise_shaping_amp==2)	    return;    }}/************************************************************************* * *      inc_scalefac_scale() * *  Takehiro Tominaga 2000-xx-xx * *  turns on scalefac scale and adjusts scalefactors * *************************************************************************/ static voidinc_scalefac_scale (    gr_info        * const cod_info,     FLOAT                 xrpow[576] ){    int l, j, sfb;    const FLOAT ifqstep34 = 1.29683955465100964055;    j = 0;    for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {	int width = cod_info->width[sfb];        int s = cod_info->scalefac[sfb];	if (cod_info->preflag)	    s += pretab[sfb];	j += width;        if (s & 1) {            s++;            for (l = -width; l < 0; l++) {                xrpow[j+l] *= ifqstep34;                if (xrpow[j+l] > cod_info->xrpow_max)                    cod_info->xrpow_max = xrpow[j+l];            }        }        cod_info->scalefac[sfb] = s >> 1;    }    cod_info->preflag = 0;    cod_info->scalefac_scale = 1;}/************************************************************************* * *      inc_subblock_gain() * *  Takehiro Tominaga 2000-xx-xx * *  increases the subblock gain and adjusts scalefactors * *************************************************************************/ static int inc_subblock_gain (    const lame_internal_flags        * const gfc,          gr_info        * const cod_info,          FLOAT                 xrpow[576] ){    int sfb, window;    int * const scalefac = cod_info->scalefac;    /* subbloc_gain can't do anything in the long block region */    for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) {	if (scalefac[sfb] >= 16)	    return 1;    }    for (window = 0; window < 3; window++) {        int s1, s2, l, j;        s1 = s2 = 0;        for (sfb = cod_info->sfb_lmax+window;        sfb < cod_info->sfbdivide; sfb += 3) {            if (s1 < scalefac[sfb])                s1 = scalefac[sfb];        }        for (; sfb < cod_info->sfbmax; sfb += 3) {            if (s2 < scalefac[sfb])                s2 = scalefac[sfb];        }        if (s1 < 16 && s2 < 8)            continue;        if (cod_info->subblock_gain[window] >= 7)            return 1;        /* even though there is no scalefactor for sfb12        * subblock gain affects upper frequencies too, that's why        * we have to go up to SBMAX_s        */        cod_info->subblock_gain[window]++;        j = gfc->scalefac_band.l[cod_info->sfb_lmax];        for (sfb = cod_info->sfb_lmax+window;        sfb < cod_info->sfbmax; sfb += 3) {            FLOAT amp;            int width = cod_info->width[sfb], s = scalefac[sfb];            assert(s >= 0);            s = s - (4 >> cod_info->scalefac_scale);            if (s >= 0) {                scalefac[sfb] = s;                j += width*3;                continue;            }            scalefac[sfb] = 0;            amp = IPOW20(210 + (s << (cod_info->scalefac_scale + 1)));            j += width * (window+1);            for (l = -width; l < 0; l++) {                xrpow[j+l] *= amp;                if (xrpow[j+l] > cod_info->xrpow_max)                    cod_info->xrpow_max = xrpow[j+l];            }            j += width*(3 - window - 1);        }        {            FLOAT amp = IPOW20(210 - 8);            j += cod_info->width[sfb] * (window+1);            for (l = -cod_info->width[sfb]; l < 0; l++) {                xrpow[j+l] *= amp;                if (xrpow[j+l] > cod_info->xrpow_max)                    cod_info->xrpow_max = xrpow[j+l];            }        }    }    return 0;}/******************************************************************** * *      balance_noise() * *  Takehiro Tominaga /date?? *  Robert Hegemann 2000-09-06: made a function of it * *  amplifies scalefactor bands,  *   - if all are already amplified returns 0 *   - if some bands are amplified too much: *      * try to increase scalefac_scale *      * if already scalefac_scale was set *          try on short blocks to increase subblock gain * ********************************************************************/inlinestatic int balance_noise (    lame_global_flags  *const gfp,    gr_info        * const cod_info,    FLOAT         * distort,    FLOAT         xrpow[576],    int bRefine){    lame_internal_flags *const gfc = gfp->internal_flags;    int status;        amp_scalefac_bands ( gfp, cod_info, distort, xrpow, bRefine);    /* check to make sure we have not amplified too much      * loop_break returns 0 if there is an unamplified scalefac     * scale_bitcount returns 0 if no scalefactors are too large     */        status = loop_break (cod_info);        if (status)         return 0; /* all bands amplified */        /* not all scalefactors have been amplified.  so these      * scalefacs are possibly valid.  encode them:      */    if (gfc->mode_gr == 2)        status = scale_bitcount (cod_info);    else         status = scale_bitcount_lsf (gfc, cod_info);        if (!status)         return 1; /* amplified some bands not exceeding limits */        /*  some scalefactors are too large.     *  lets try setting scalefac_scale=1      */    if (gfc->noise_shaping > 1) {	    memset(&gfc->pseudohalf, 0, sizeof(gfc->pseudohalf));	    if (!cod_info->scalefac_scale) {	        inc_scalefac_scale (cod_info, xrpow);	        status = 0;	    } else {	        if (cod_info->block_type == SHORT_TYPE && gfc->subblock_gain > 0) {		    status = inc_subblock_gain (gfc, cod_info, xrpow)		        || loop_break (cod_info);	        }	    }    }    if (!status) {        if (gfc->mode_gr == 2)            status = scale_bitcount (cod_info);        else             status = scale_bitcount_lsf (gfc, cod_info);    }    return !status;}/************************************************************************ * *  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 * *  some code shuffle rh 9/00 ************************************************************************/static int outer_loop (    lame_global_flags	*gfp,    gr_info		* const cod_info,    const FLOAT	* const l3_xmin,  /* allowed distortion */    FLOAT		xrpow[576], /* coloured magnitudes of spectral */    const int           ch,    const int           targ_bits )  /* maximum allowed bits */{    lame_internal_flags *gfc=gfp->internal_flags;    gr_info cod_info_w;    FLOAT save_xrpow[576];    FLOAT distort[SFBMAX];    calc_noise_result best_noise_info;    int huff_bits;    int better;    int over;    int age;    calc_noise_data prev_noise;    int best_part2_3_length = 9999999;    int bEndOfSearch = 0;    int bRefine = 0;    int best_ggain_pass1 = 0;    bin_search_StepSize (gfc, cod_info, targ_bits, ch, xrpow);    if (!gfc->noise_shaping) 	/* fast mode, no noise shaping, we are ready */	return 100; /* default noise_info.over_count */    memset(&prev_noise, 0, sizeof(calc_noise_data));    /* compute the distortion in this quantization */    /* coefficients and thresholds both l/r (or both mid/side) */    over = calc_noise (gfc, cod_info, l3_xmin, distort, &best_noise_info, &prev_noise);    best_noise_info.bits = cod_info->part2_3_length;    cod_info_w = *cod_info;    age = 0;   /* if (gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh)*/	memcpy(save_xrpow, xrpow, sizeof(FLOAT)*576);    while (!bEndOfSearch) {        /* BEGIN MAIN LOOP */        do {	        calc_noise_result noise_info;            int search_limit;            int maxggain = 255;            /* When quantization with no distorted bands is found,             * allow up to X new unsuccesful tries in serial. This             * gives us more possibilities for different quant_compare modes.             * Much more than 3 makes not a big difference, it is only slower.             */            if (gfc->substep_shaping & 2) {	            search_limit = 20;            }else {	            search_limit = 3;            }	        /* Check if the last scalefactor band is distorted.	         * in VBR mode we can't get rid of the distortion, so quit now	         * and VBR mode will try again with more bits.  	         * (makes a 10% speed increase, the files I tested were	         * binary identical, 2000/05/20 Robert Hegemann)	         * distort[] > 1 means noise > allowed noise	         */	        if (gfc->sfb21_extra) {	            if (distort[cod_info_w.sfbmax] > 1.0)		        break;	            if (cod_info_w.block_type == SHORT_TYPE		        && (distort[cod_info_w.sfbmax+1] > 1.0		            || distort[cod_info_w.sfbmax+2] > 1.0))		            break;	        }	        /* try a new scalefactor conbination on cod_info_w */	        if (balance_noise (gfp, &cod_info_w, distort, xrpow, bRefine) == 0)	            break;            if (cod_info_w.scalefac_scale)                maxggain = 254;            /* 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 + -