/* * MP3 quantization * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: quantize.c,v 1.57 2001/02/27 06:14:57 markt Exp $ */ #ifdef HAVE_CONFIG_H# include <config.h>#endif #include <math.h>#include <assert.h>#include "util.h"#include "l3side.h"#include "quantize.h"#include "reservoir.h"#include "quantize_pvt.h"#include "lame-analysis.h" #ifdef WITH_DMALLOC#include <dmalloc.h>#endif /************************************************************************ * * init_outer_loop() * mt 6/99 * * initializes cod_info, scalefac and xrpow * * returns 0 if all energies in xr are zero, else 1 * ************************************************************************/ static int init_outer_loop( gr_info *const cod_info, III_scalefac_t *const scalefac, const int is_mpeg1, const FLOAT8 xr[576], FLOAT8 xrpow[576] ){ FLOAT8 tmp, sum = 0; int i; /* initialize fresh cod_info */ cod_info->part2_3_length = 0; cod_info->big_values = 0; cod_info->count1 = 0; cod_info->global_gain = 210; cod_info->scalefac_compress = 0; /* window_switching_flag was set in psymodel.c? */ /* block_type was set in psymodel.c? */ /* mixed_block_flag would be set in ^ */ 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->preflag = 0; cod_info->scalefac_scale = 0; cod_info->count1table_select = 0; cod_info->part2_length = 0; if (cod_info->block_type == SHORT_TYPE) { cod_info->sfb_lmax = 0; cod_info->sfb_smin = 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_lmax = is_mpeg1 ? 8 : 6; cod_info->sfb_smin = 3; } } else { cod_info->sfb_lmax = SBPSY_l; cod_info->sfb_smin = SBPSY_s; } 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; /* fresh scalefactors are all zero */ memset(scalefac, 0, sizeof(III_scalefac_t)); /* check if there is some energy we have to quantize * and calculate xrpow matching our fresh scalefactors */ for (i = 0; i < 576; ++i) { tmp = fabs (xr[i]); sum += tmp; xrpow[i] = sqrt (tmp * sqrt(tmp)); } /* return 1 if we have something to quantize, else 0 */ return sum > (FLOAT8)1E-20;} /************************************************************************ * * 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, const int desired_rate, const int start, const FLOAT8 xrpow [576], int l3enc [576] ) { int nBits; int CurrentStep; int flag_GoneOver = 0; int StepSize = start; binsearchDirection_t Direction = BINSEARCH_NONE; assert(gfc->CurrentStep); CurrentStep = gfc->CurrentStep; do { cod_info->global_gain = StepSize; nBits = count_bits(gfc,l3enc,xrpow,cod_info); if (CurrentStep == 1) break; /* nothing to adjust anymore */ if (flag_GoneOver) CurrentStep /= 2; if (nBits > desired_rate) { /* increase Quantize_StepSize */ if (Direction == BINSEARCH_DOWN && !flag_GoneOver) { flag_GoneOver = 1; CurrentStep /= 2; /* late adjust */ } Direction = BINSEARCH_UP; StepSize += CurrentStep; if (StepSize > 255) break; } else if (nBits < desired_rate) { /* decrease Quantize_StepSize */ if (Direction == BINSEARCH_UP && !flag_GoneOver) { flag_GoneOver = 1; CurrentStep /= 2; /* late adjust */ } Direction = BINSEARCH_DOWN; StepSize -= CurrentStep; if (StepSize < 0) break; } else break; /* nBits == desired_rate;; most unlikely to happen.*/ } while (1); /* For-ever, break is adjusted. */ CurrentStep = start - StepSize; gfc->CurrentStep = CurrentStep/4 != 0 ? 4 : 2; return nBits;} /*************************************************************************** * * inner_loop () * * author/date?? * * The code selects the best global gain for a particular set of scalefacs * ***************************************************************************/ int inner_loop( lame_internal_flags * const gfc, gr_info * const cod_info, const int max_bits, const FLOAT8 xrpow [576], int l3enc [576] ){ int bits; assert(max_bits >= 0); /* scalefactors may have changed, so count bits */ bits=count_bits(gfc,l3enc,xrpow,cod_info); /* increase quantizer stepsize until needed bits are below maximum */ while (bits > max_bits) { cod_info->global_gain++; bits = count_bits (gfc, l3enc, xrpow, cod_info); } return bits;} /************************************************************************* * * 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, const III_scalefac_t * const scalefac ) { unsigned int i, sfb; for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) if (scalefac->l[sfb] == 0) return 0; for (sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++) for (i = 0; i < 3; i++) if (scalefac->s[sfb][i] == 0 && cod_info->subblock_gain[i] == 0) return 0; return 1;} /************************************************************************* * * quant_compare() * * author/date?? * * several different codes to decide which quantization is better * *************************************************************************/ inline static int quant_compare( const int experimentalX, const calc_noise_result * const best, const calc_noise_result * const calc ){ /* 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 (experimentalX) { default: 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 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+2; break; case 4: better = ( calc->max_noise <= 0 && best->max_noise > 2 ) || ( calc->max_noise <= 0 && best->max_noise < 0 && best->max_noise > calc->max_noise-2 && calc->tot_noise < best->tot_noise ) || ( calc->max_noise <= 0 && best->max_noise > 0 && best->max_noise > calc->max_noise-2 && calc->tot_noise < best->tot_noise+best->over_noise ) || ( calc->max_noise > 0 && best->max_noise > -0.5 && best->max_noise > calc->max_noise-1 && calc->tot_noise+calc->over_noise < best->tot_noise+best->over_noise ) || ( calc->max_noise > 0 && best->max_noise > -1 && best->max_noise > calc->max_noise-1.5 && 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; case 8: better = calc->klemm_noise < best->klemm_noise; break; } return better;} /************************************************************************* * * 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, const gr_info *const cod_info, III_scalefac_t *const scalefac, III_psy_xmin *distort, FLOAT8 xrpow[576] ){ lame_internal_flags *gfc=gfp->internal_flags; int start, end, l,i,j,sfb; FLOAT8 ifqstep34, trigger; 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->sfb_lmax; sfb++) { if (trigger < distort->l[sfb]) trigger = distort->l[sfb]; } for (sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++) { for (i = 0; i < 3; i++ ) { if (trigger < distort->s[sfb][i]) trigger = distort->s[sfb][i]; } } switch (gfc->noise_shaping_amp) { case 2: /* amplify exactly 1 band */ //trigger = distort_thresh; 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; } for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++ ) { start = gfc->scalefac_band.l[sfb]; end = gfc->scalefac_band.l[sfb+1]; if (distort->l[sfb]>=trigger ) { scalefac->l[sfb]++; for ( l = start; l < end; l++ ) xrpow[l] *= ifqstep34; if (gfc->noise_shaping_amp==2) goto done; } } for ( j=0,sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++ ) { start = gfc->scalefac_band.s[sfb]; end = gfc->scalefac_band.s[sfb+1]; for ( i = 0; i < 3; i++ ) { int j2 = j; if ( distort->s[sfb][i]>=trigger) { scalefac->s[sfb][i]++; for (l = start; l < end; l++) xrpow[j2++] *= ifqstep34; if (gfc->noise_shaping_amp==2) goto done; } j += end-start; } } done: return;} /************************************************************************* * * inc_scalefac_scale() * * Takehiro Tominaga 2000-xx-xx * * turns on scalefac scale and adjusts scalefactors * *************************************************************************/ static voidinc_scalefac_scale ( const lame_internal_flags * const gfc, gr_info * const cod_info, III_scalefac_t * const scalefac, FLOAT8 xrpow[576] ){Lines 1–500 of 1838. Load more
/* * MP3 quantization * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: quantize.c,v 1.57 2001/02/27 06:14:57 markt Exp $ */ #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <math.h> #include <assert.h> #include "util.h" #include "l3side.h" #include "quantize.h" #include "reservoir.h" #include "quantize_pvt.h" #include "lame-analysis.h" #ifdef WITH_DMALLOC #include <dmalloc.h> #endif /************************************************************************ * * init_outer_loop() * mt 6/99 * * initializes cod_info, scalefac and xrpow * * returns 0 if all energies in xr are zero, else 1 * ************************************************************************/ static int init_outer_loop( gr_info *const cod_info, III_scalefac_t *const scalefac, const int is_mpeg1, const FLOAT8 xr[576], FLOAT8 xrpow[576] ) { FLOAT8 tmp, sum = 0; int i; /* initialize fresh cod_info */ cod_info->part2_3_length = 0; cod_info->big_values = 0; cod_info->count1 = 0; cod_info->global_gain = 210; cod_info->scalefac_compress = 0; /* window_switching_flag was set in psymodel.c? */ /* block_type was set in psymodel.c? */ /* mixed_block_flag would be set in ^ */ 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->preflag = 0; cod_info->scalefac_scale = 0; cod_info->count1table_select = 0; cod_info->part2_length = 0; if (cod_info->block_type == SHORT_TYPE) { cod_info->sfb_lmax = 0; cod_info->sfb_smin = 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_lmax = is_mpeg1 ? 8 : 6; cod_info->sfb_smin = 3; } } else { cod_info->sfb_lmax = SBPSY_l; cod_info->sfb_smin = SBPSY_s; } 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; /* fresh scalefactors are all zero */ memset(scalefac, 0, sizeof(III_scalefac_t)); /* check if there is some energy we have to quantize * and calculate xrpow matching our fresh scalefactors */ for (i = 0; i < 576; ++i) { tmp = fabs (xr[i]); sum += tmp; xrpow[i] = sqrt (tmp * sqrt(tmp)); } /* return 1 if we have something to quantize, else 0 */ return sum > (FLOAT8)1E-20; } /************************************************************************ * * 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, const int desired_rate, const int start, const FLOAT8 xrpow [576], int l3enc [576] ) { int nBits; int CurrentStep; int flag_GoneOver = 0; int StepSize = start; binsearchDirection_t Direction = BINSEARCH_NONE; assert(gfc->CurrentStep); CurrentStep = gfc->CurrentStep; do { cod_info->global_gain = StepSize; nBits = count_bits(gfc,l3enc,xrpow,cod_info); if (CurrentStep == 1) break; /* nothing to adjust anymore */ if (flag_GoneOver) CurrentStep /= 2; if (nBits > desired_rate) { /* increase Quantize_StepSize */ if (Direction == BINSEARCH_DOWN && !flag_GoneOver) { flag_GoneOver = 1; CurrentStep /= 2; /* late adjust */ } Direction = BINSEARCH_UP; StepSize += CurrentStep; if (StepSize > 255) break; } else if (nBits < desired_rate) { /* decrease Quantize_StepSize */ if (Direction == BINSEARCH_UP && !flag_GoneOver) { flag_GoneOver = 1; CurrentStep /= 2; /* late adjust */ } Direction = BINSEARCH_DOWN; StepSize -= CurrentStep; if (StepSize < 0) break; } else break; /* nBits == desired_rate;; most unlikely to happen.*/ } while (1); /* For-ever, break is adjusted. */ CurrentStep = start - StepSize; gfc->CurrentStep = CurrentStep/4 != 0 ? 4 : 2; return nBits; } /*************************************************************************** * * inner_loop () * * author/date?? * * The code selects the best global gain for a particular set of scalefacs * ***************************************************************************/ int inner_loop( lame_internal_flags * const gfc, gr_info * const cod_info, const int max_bits, const FLOAT8 xrpow [576], int l3enc [576] ) { int bits; assert(max_bits >= 0); /* scalefactors may have changed, so count bits */ bits=count_bits(gfc,l3enc,xrpow,cod_info); /* increase quantizer stepsize until needed bits are below maximum */ while (bits > max_bits) { cod_info->global_gain++; bits = count_bits (gfc, l3enc, xrpow, cod_info); } return bits; } /************************************************************************* * * loop_break() * * author/date?? * * Function: Returns zero if there is a scalefac which has not been * amplified. Otherwise it returns one. * *************************************************************************/ inline static int loop_break( const gr_info * const cod_info, const III_scalefac_t * const scalefac ) { unsigned int i, sfb; for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) if (scalefac->l[sfb] == 0) return 0; for (sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++) for (i = 0; i < 3; i++) if (scalefac->s[sfb][i] == 0 && cod_info->subblock_gain[i] == 0) return 0; return 1; } /************************************************************************* * * quant_compare() * * author/date?? * * several different codes to decide which quantization is better * *************************************************************************/ inline static int quant_compare( const int experimentalX, const calc_noise_result * const best, const calc_noise_result * const calc ) { /* 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 (experimentalX) { default: 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 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+2; break; case 4: better = ( calc->max_noise <= 0 && best->max_noise > 2 ) || ( calc->max_noise <= 0 && best->max_noise < 0 && best->max_noise > calc->max_noise-2 && calc->tot_noise < best->tot_noise ) || ( calc->max_noise <= 0 && best->max_noise > 0 && best->max_noise > calc->max_noise-2 && calc->tot_noise < best->tot_noise+best->over_noise ) || ( calc->max_noise > 0 && best->max_noise > -0.5 && best->max_noise > calc->max_noise-1 && calc->tot_noise+calc->over_noise < best->tot_noise+best->over_noise ) || ( calc->max_noise > 0 && best->max_noise > -1 && best->max_noise > calc->max_noise-1.5 && 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; case 8: better = calc->klemm_noise < best->klemm_noise; break; } return better; } /************************************************************************* * * 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, const gr_info *const cod_info, III_scalefac_t *const scalefac, III_psy_xmin *distort, FLOAT8 xrpow[576] ) { lame_internal_flags *gfc=gfp->internal_flags; int start, end, l,i,j,sfb; FLOAT8 ifqstep34, trigger; 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->sfb_lmax; sfb++) { if (trigger < distort->l[sfb]) trigger = distort->l[sfb]; } for (sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++) { for (i = 0; i < 3; i++ ) { if (trigger < distort->s[sfb][i]) trigger = distort->s[sfb][i]; } } switch (gfc->noise_shaping_amp) { case 2: /* amplify exactly 1 band */ //trigger = distort_thresh; 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; } for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++ ) { start = gfc->scalefac_band.l[sfb]; end = gfc->scalefac_band.l[sfb+1]; if (distort->l[sfb]>=trigger ) { scalefac->l[sfb]++; for ( l = start; l < end; l++ ) xrpow[l] *= ifqstep34; if (gfc->noise_shaping_amp==2) goto done; } } for ( j=0,sfb = cod_info->sfb_smin; sfb < SBPSY_s; sfb++ ) { start = gfc->scalefac_band.s[sfb]; end = gfc->scalefac_band.s[sfb+1]; for ( i = 0; i < 3; i++ ) { int j2 = j; if ( distort->s[sfb][i]>=trigger) { scalefac->s[sfb][i]++; for (l = start; l < end; l++) xrpow[j2++] *= ifqstep34; if (gfc->noise_shaping_amp==2) goto done; } j += end-start; } } done: return; } /************************************************************************* * * inc_scalefac_scale() * * Takehiro Tominaga 2000-xx-xx * * turns on scalefac scale and adjusts scalefactors * *************************************************************************/ static void inc_scalefac_scale ( const lame_internal_flags * const gfc, gr_info * const cod_info, III_scalefac_t * const scalefac, FLOAT8 xrpow[576] ) {