All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.axet.jlame.libmp3lame.JVBR_old_iteration_loop Maven / Gradle / Ivy

The newest version!
package com.github.axet.jlame.libmp3lame;

final class JVBR_old_iteration_loop extends Jquantize/* implements Jiteration_loop */ {
	/*********************************************************************
	 *
	 *      VBR_prepare()
	 *
	 *  2000-09-04 Robert Hegemann
	 *
	 *  * converts LR to MS coding when necessary
	 *  * calculates allowed/adjusted quantization noise amounts
	 *  * detects analog silent frames
	 *
	 *  some remarks:
	 *  - 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
	 *
	 *********************************************************************/

/* RH: this one needs to be overhauled sometime */
	private static final boolean VBR_old_prepare(final Jlame_internal_flags gfc,
		final float pe[][]/*[2][2]*/, final float ms_ener_ratio[/*2*/],
		final JIII_psy_ratio ratio[][]/*[2][2]*/,
		final float l3_xmin[][][]/*[2][2][SFBMAX]*/,
		final int frameBits[]/*[16]*/, final int min_bits[][]/*[2][2]*/, final int max_bits[][]/*[2][2]*/, final int bands[][]/*[2][2]*/)
	{
		final JSessionConfig cfg = gfc.cfg;
		final JEncResult eov = gfc.ov_enc;
		final Jgr_info[][] tt = gfc.l3_side.tt;

		float adjust = 0.0f;
		boolean analog_silence = true;
		int bits = 0;

		eov.bitrate_index = cfg.vbr_max_bitrate_index;
		final int avg = ((int)Jreservoir.ResvFrameBegin( gfc/*, &avg*/ )) / cfg.mode_gr;

		get_framebits( gfc, frameBits );

		final JQntStateVar sv_qnt = gfc.sv_qnt;// java
		final int mode_gr = cfg.mode_gr;// java
		final int channels_out = cfg.channels_out;// java
		for( int gr = 0; gr < mode_gr; gr++ ) {
			final int mxb = Jquantize_pvt.on_pe( gfc, pe, max_bits[gr], avg, gr, false );
			if( gfc.ov_enc.mode_ext == Jencoder.MPG_MD_MS_LR ) {
				gfc.l3_side.ms_convert( gr );
				Jquantize_pvt.reduce_side( max_bits[gr], ms_ener_ratio[gr], avg, mxb );
			}
			final Jgr_info[] tt_gr = tt[gr];// java
			final float[] pe_gr = pe[gr];// java
			final JIII_psy_ratio[] ratio_gr = ratio[gr];// java
			final float[][] l3_xmin_gr = l3_xmin[gr];// java
			final int[] bands_gr = bands[gr];// java
			for( int ch = 0; ch < channels_out; ++ch ) {
				final Jgr_info cod_info = tt_gr[ch];

				float masking_lower_db;
				if( cod_info.block_type != Jencoder.SHORT_TYPE ) { /* NORM, START or STOP type */
					adjust = 1.28f / (1f + (float)Math.exp( (double)(3.5f - pe_gr[ch] / 300.f) )) - 0.05f;
					masking_lower_db = sv_qnt.mask_adjust - adjust;
				} else {
					adjust = 2.56f / (1f + (float)Math.exp( (double)(3.5f - pe_gr[ch] / 300.f) )) - 0.14f;
					masking_lower_db = sv_qnt.mask_adjust_short - adjust;
				}
				sv_qnt.masking_lower = (float)Math.pow( 10.0, (double)(masking_lower_db * 0.1f) );

				init_outer_loop( gfc, cod_info );
				bands_gr[ch] = Jquantize_pvt.calc_xmin( gfc, ratio_gr[ch], cod_info, l3_xmin_gr[ch] );
				if( bands_gr[ch] != 0 ) {
					analog_silence = false;
				}

				min_bits[gr][ch] = 126;

				bits += max_bits[gr][ch];
			}
		}
		final int max_frame_bits = frameBits[cfg.vbr_max_bitrate_index];// java
		for( int gr = 0; gr < mode_gr; gr++ ) {
			final int[] max_bits_gr = max_bits[gr];// java
			final int[] min_bits_gr = min_bits[gr];// java
			for( int ch = 0; ch < channels_out; ch++ ) {
				if( bits > max_frame_bits && bits > 0 ) {
					int v = max_bits_gr[ch];// java
					v *= max_frame_bits;
					v /= bits;
					max_bits_gr[ch] = v;
				}
				if( min_bits_gr[ch] > max_bits_gr[ch] ) {
					min_bits_gr[ch] = max_bits_gr[ch];
				}
			}               /* for ch */
		}                   /* for gr */

		return analog_silence;
	}

	private static final void bitpressure_strategy(final Jlame_internal_flags gfc,
			final float l3_xmin[][][]/*[2][2][SFBMAX]*/, final int min_bits[][]/*[2][2]*/, final int max_bits[][]/*[2][2]*/)
	{
		final JSessionConfig cfg = gfc.cfg;
		final Jgr_info[][] tt = gfc.l3_side.tt;
		final int mode_gr = cfg.mode_gr;// java
		final int channels_out = cfg.channels_out;// java

		for( int gr = 0; gr < mode_gr; gr++ ) {
			final Jgr_info[] tt_gr = tt[gr];// java
			final float[][] l3_xmin_gr = l3_xmin[gr];// java
			final int[] max_bits_gr = max_bits[gr];// java
			final int[] min_bits_gr = min_bits[gr];// java
			for( int ch = 0; ch < channels_out; ch++ ) {
				final Jgr_info gi = tt_gr[ch];
				final float[] xmin = l3_xmin_gr[ch];// java
				int pxmin = 0;
				for( int sfb = 0, psy_lmax = gi.psy_lmax; sfb < psy_lmax; sfb++ ) {
					xmin[pxmin++] *= 1.f + .029f * sfb * sfb / Jencoder.SBMAX_l / Jencoder.SBMAX_l;
				}

				if( gi.block_type == Jencoder.SHORT_TYPE ) {
					for( int sfb = gi.sfb_smin; sfb < Jencoder.SBMAX_s; sfb++ ) {
						final float v = 1.f + .029f * sfb * sfb / Jencoder.SBMAX_s / Jencoder.SBMAX_s;// java
						xmin[pxmin++] *= v;
						xmin[pxmin++] *= v;
						xmin[pxmin++] *= v;
					}
				}
				final int v1 = min_bits_gr[ch];
				final int v2 = (int)(0.9f * max_bits_gr[ch]);
				max_bits_gr[ch] = (v1 >= v2 ? v1 : v2);
			}
		}
	}

	/*********************************************************************
	 *
	 *      VBR_encode_granule()
	 *
	 *  2000-09-04 Robert Hegemann
	 *
	 *********************************************************************/
	private static final void VBR_encode_granule(final Jlame_internal_flags gfc, final Jgr_info cod_info, final float[] l3_xmin, /* allowed distortion of the scalefactor */
                   final float xrpow[/*576*/], /* coloured magnitudes of spectral values */
                   final int ch, int min_bits, int max_bits)
	{
		final Jgr_info bst_cod_info = new Jgr_info();
		final float bst_xrpow[] = new float[576];
		final int Max_bits = max_bits;
		int real_bits = max_bits + 1;
		int this_bits = (max_bits + min_bits) >> 1;
		int found = 0;
		final boolean sfb21_extra = gfc.sv_qnt.sfb21_extra;

		final int[] buf = bst_cod_info.l3_enc;
		int i = buf.length;
		do {
			buf[--i] = 0;
		} while( i > 0 );

		/*  search within round about 40 bits of optimal */
		int dbits;
		do {

			if( this_bits > Max_bits - 42 ) {
				gfc.sv_qnt.sfb21_extra = false;
			} else {
				gfc.sv_qnt.sfb21_extra = sfb21_extra;
			}

			final int over = outer_loop( gfc, cod_info, l3_xmin, xrpow, ch, this_bits );

			/*  is quantization as good as we are looking for ?
			 *  in this case: is no scalefactor band distorted?
			 */
			if( over <= 0 ) {
				found = 1;
				/*  now we know it can be done with "real_bits"
				 *  and maybe we can skip some iterations
				 */
				real_bits = cod_info.part2_3_length;

				/*  store best quantization so far */
				bst_cod_info.copyFrom( cod_info );
				System.arraycopy( xrpow, 0, bst_xrpow, 0, 576 );

				/*  try with fewer bits */
				max_bits = real_bits - 32;
				dbits = max_bits - min_bits;
				this_bits = (max_bits + min_bits) >> 1;
			} else {
				/*  try with more bits */
				min_bits = this_bits + 32;
				dbits = max_bits - min_bits;
				this_bits = (max_bits + min_bits) >> 1;

				if( found != 0 ) {
					found = 2;
					/*  start again with best quantization so far */
					cod_info.copyFrom( bst_cod_info );
					System.arraycopy( bst_xrpow, 0, xrpow, 0, 576 );
				}
			}
		} while( dbits > 12 );

		gfc.sv_qnt.sfb21_extra = sfb21_extra;

		/*  found=0 => nothing found, use last one
		 *  found=1 => we just found the best and left the loop
		 *  found=2 => we restored a good one and have now l3_enc to restore too
		 */
		if( found == 2 ) {
			System.arraycopy( bst_cod_info.l3_enc, 0, cod_info.l3_enc, 0, 576 );
		}
	}

	/************************************************************************
	 *
	 *      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
	 *
	 *  Robert Hegemann 2000-09-06 rewrite
	 *
	 ************************************************************************/

	//private static final void VBR_old_iteration_loop(final Jlame_internal_flags gfc, final float pe[][]/*[2][2]*/,
	//		final float ms_ener_ratio[]/*[2]*/, final JIII_psy_ratio ratio[][]/*[2][2]*/)
	//@Override
	static final void iteration(final Jlame_internal_flags gfc, final float pe[][]/*[2][2]*/,
			final float ms_ener_ratio[]/*[2]*/, final JIII_psy_ratio ratio[][]/*[2][2]*/)
	{
		final JSessionConfig cfg = gfc.cfg;
		final JEncResult eov = gfc.ov_enc;
		final float l3_xmin[][][] = new float[2][2][Jencoder.SFBMAX];

		final float xrpow[] = new float[576];
		final int bands[][] = new int[2][2];
		final int frameBits[] = new int[15];
		final int min_bits[][] = new int[2][2];
		final int max_bits[][] = new int[2][2];
		final Jgr_info[][] tt = gfc.l3_side.tt;
		final int mode_gr = cfg.mode_gr;// java
		final int channels_out = cfg.channels_out;// java

		final boolean analog_silence = VBR_old_prepare( gfc, pe, ms_ener_ratio, ratio,
						 l3_xmin, frameBits, min_bits, max_bits, bands );

		/*---------------------------------*/
		int mean_bits;
		for( ;; ) {

			/*  quantize granules with lowest possible number of bits */

			int used_bits = 0;

			for( int gr = 0; gr < mode_gr; gr++ ) {
				final Jgr_info[] tt_gr = tt[gr];// java
				final float[][] l3_xmin_gr = l3_xmin[gr];// java
				final int[] max_bits_gr = max_bits[gr];// java
				final int[] min_bits_gr = min_bits[gr];// java
				for( int ch = 0; ch < channels_out; ch++ ) {
					final Jgr_info cod_info = tt_gr[ch];// java

					/*  init_outer_loop sets up cod_info, scalefac and xrpow */
					if( ! init_xrpow( gfc, cod_info, xrpow ) || max_bits_gr[ch] == 0 ) {
						/*  xr contains no energy
						 *  l3_enc, our encoding data, will be quantized to zero
						 */
						continue; /* with next channel */
					}

					VBR_encode_granule( gfc, cod_info, l3_xmin_gr[ch], xrpow,
							ch, min_bits_gr[ch], max_bits_gr[ch] );

					/*  do the 'substep shaping' */
					if( (gfc.sv_qnt.substep_shaping & 1) != 0 ) {
						trancate_smallspectrums( gfc, tt_gr[ch], l3_xmin_gr[ch], xrpow );
					}

					final int ret = cod_info.part2_3_length + cod_info.part2_length;
					used_bits += ret;
				}           /* for ch */
			}               /* for gr */

			/*  find lowest bitrate able to hold used bits */
			if( analog_silence && ! cfg.enforce_min_bitrate ) {
				eov.bitrate_index = 1;
			} else {
				eov.bitrate_index = cfg.vbr_min_bitrate_index;
			}

			for( ; eov.bitrate_index < cfg.vbr_max_bitrate_index; eov.bitrate_index++ ) {
				if( used_bits <= frameBits[eov.bitrate_index] ) {
					break;
				}
			}
			final long tmp = Jreservoir.ResvFrameBegin( gfc/*, &mean_bits */);
			final int bits = (int)tmp;
			mean_bits = (int)(tmp >> 32);

			if( used_bits <= bits ) {
				break;
			}

			bitpressure_strategy( gfc, l3_xmin, min_bits, max_bits );

		}                   /* breaks adjusted */
		/*--------------------------------------*/

		for( int gr = 0; gr < mode_gr; gr++ ) {
			for( int ch = 0; ch < channels_out; ch++ ) {
				iteration_finish_one( gfc, gr, ch );
			}               /* for ch */
		}                   /* for gr */
		Jreservoir.ResvFrameEnd( gfc, mean_bits );
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy