📄 quantize.c
字号:
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 + -