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

javazoom.jl.decoder.LayerIIIDecoder Maven / Gradle / Ivy

Go to download

Maven artifact for JLayer library. http://www.javazoom.net/javalayer/sources.html

There is a newer version: 1.0.1.4
Show newest version
/*
 * 11/19/04	 1.0 moved to LGPL.
 * 
 * 18/06/01  Michael Scheerer,  Fixed bugs which causes
 *           negative indexes in method huffmann_decode and in method 
 *           dequanisize_sample.
 *
 * 16/07/01  Michael Scheerer, Catched a bug in method
 *           huffmann_decode, which causes an outOfIndexException.
 *           Cause : Indexnumber of 24 at SfBandIndex,
 *           which has only a length of 22. I have simply and dirty 
 *           fixed the index to <= 22, because I'm not really be able
 *           to fix the bug. The Indexnumber is taken from the MP3 
 *           file and the origin Ma-Player with the same code works 
 *           well.      
 * 
 * 02/19/99  Java Conversion by E.B, [email protected]
 *-----------------------------------------------------------------------
 *   This program 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 program 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 program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *----------------------------------------------------------------------
 */

package javazoom.jl.decoder;

/**
 * Class Implementing Layer 3 Decoder.
 *
 * @since 0.0
 */
final class LayerIIIDecoder implements FrameDecoder
{
	final double d43 = (4.0/3.0);
	
	public int[]				scalefac_buffer;

	// MDM: removed, as this wasn't being used.
	//private float               CheckSumOut1d = 0.0f;
    private int                 CheckSumHuff = 0;
	private int[] 				is_1d;
    private float[][][]			ro;
    private float[][][]			lr;
	private float[]				out_1d;
    private float[][]		    prevblck;
    private float[][]			k;
    private int[] 				nonzero;
	private Bitstream 			stream;
    private Header 				header;
    private SynthesisFilter 	filter1, filter2;
    private Obuffer 			buffer;
    private int 				which_channels;
    private BitReserve 			br;
    private III_side_info_t 	si;

    private temporaire2[]        III_scalefac_t;
    private temporaire2[]        scalefac;
    // private III_scalefac_t 		scalefac;

    private int 				max_gr;
    private int					frame_start;
    private int 				part2_start;
    private int 				channels;
    private int 				first_channel;
    private int 				last_channel;
    private int					sfreq;


	/**
	 * Constructor.
	 */
	// REVIEW: these constructor arguments should be moved to the
	// decodeFrame() method, where possible, so that one
	public LayerIIIDecoder(Bitstream stream0, Header header0,
   	                        SynthesisFilter filtera, SynthesisFilter filterb,
                            Obuffer buffer0, int which_ch0)
	{
        huffcodetab.inithuff();
		is_1d = new int[SBLIMIT*SSLIMIT+4];
		ro = new float[2][SBLIMIT][SSLIMIT];
		lr = new float[2][SBLIMIT][SSLIMIT];
		out_1d = new float[SBLIMIT*SSLIMIT];
		prevblck = new float[2][SBLIMIT*SSLIMIT];
		k = new float[2][SBLIMIT*SSLIMIT];
		nonzero = new int[2];

        //III_scalefact_t
        III_scalefac_t = new temporaire2[2];
        III_scalefac_t[0] = new temporaire2();
        III_scalefac_t[1] = new temporaire2();
        scalefac = III_scalefac_t;
        // L3TABLE INIT

		sfBandIndex = new SBI[9];	// SZD: MPEG2.5 +3 indices
		int[] l0 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
		int[] s0 = {0,4,8,12,18,24,32,42,56,74,100,132,174,192};
		int[] l1 = {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576};
		int[] s1 = {0,4,8,12,18,26,36,48,62,80,104,136,180,192};
		int[] l2 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
		int[] s2 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};

		int[] l3 = {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576};
		int[] s3 = {0,4,8,12,16,22,30,40,52,66,84,106,136,192};
		int[] l4 = {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576};
		int[] s4 = {0,4,8,12,16,22,28,38,50,64,80,100,126,192};
		int[] l5 = {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576};
		int[] s5 = {0,4,8,12,16,22,30,42,58,78,104,138,180,192};
		// SZD: MPEG2.5
		int[] l6 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
		int[] s6 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
		int[] l7 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
		int[] s7 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
		int[] l8 = {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576};
		int[] s8 = {0,8,16,24,36,52,72,96,124,160,162,164,166,192};

		sfBandIndex[0]= new SBI(l0,s0);
		sfBandIndex[1]= new SBI(l1,s1);
		sfBandIndex[2]= new SBI(l2,s2);

		sfBandIndex[3]= new SBI(l3,s3);
		sfBandIndex[4]= new SBI(l4,s4);
		sfBandIndex[5]= new SBI(l5,s5);
		//SZD: MPEG2.5
		sfBandIndex[6]= new SBI(l6,s6);
		sfBandIndex[7]= new SBI(l7,s7);
		sfBandIndex[8]= new SBI(l8,s8);
		// END OF L3TABLE INIT

		if(reorder_table == null) {	// SZD: generate LUT
			reorder_table = new int[9][];
			for(int i = 0; i < 9; i++)
				reorder_table[i] = reorder(sfBandIndex[i].s);
		}

		// Sftable
		int[] ll0 = {0, 6, 11, 16, 21};
		int[] ss0 = {0, 6, 12};
		sftable = new Sftable(ll0,ss0);
		// END OF Sftable

        // scalefac_buffer
		scalefac_buffer = new int[54];
		// END OF scalefac_buffer

	  	stream         = stream0;
	  	header         = header0;
	  	filter1        = filtera;
	  	filter2        = filterb;
	  	buffer         = buffer0;
	  	which_channels = which_ch0;

	  	frame_start = 0;
	  	channels    = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2;
	  	max_gr      = (header.version() == Header.MPEG1) ? 2 : 1;

	  	sfreq       =  header.sample_frequency() +
	                 ((header.version() == Header.MPEG1) ? 3 :
	                 (header.version() == Header.MPEG25_LSF) ? 6 : 0);	// SZD

	  	if (channels == 2)
		{
	  	  switch (which_channels)
		  {
	     	case OutputChannels.LEFT_CHANNEL:
		     case OutputChannels.DOWNMIX_CHANNELS:
		     first_channel = last_channel = 0;
		     break;

		     case OutputChannels.RIGHT_CHANNEL:
		     first_channel = last_channel = 1;
		     break;

		     case OutputChannels.BOTH_CHANNELS:
			  default:
		     first_channel  = 0;
		     last_channel   = 1;
		     break;
	     }
	   }
	   else
	   {
	    first_channel = last_channel = 0;
	   }

	  for(int ch=0;ch<2;ch++)
	     for (int j=0; j<576; j++)
	   		prevblck[ch][j] = 0.0f;

	  nonzero[0] = nonzero[1] = 576;

	  br = new BitReserve();
  	  si = new III_side_info_t();
	}

   /**
    * Notify decoder that a seek is being made.
	*/
   public void seek_notify()
   {
	  frame_start = 0;
	  for(int ch=0;ch<2;ch++)
	  for (int j=0; j<576; j++)
   	   prevblck[ch][j] = 0.0f;
   	  br = new BitReserve();
   }

   public void decodeFrame()
   {
	   decode();
   }

   /**
    * Decode one frame, filling the buffer with the output samples.
	*/

   // subband samples are buffered and passed to the
   // SynthesisFilter in one go.
	private float[] samples1 = new float[32];
	private float[] samples2 = new float[32];

	public void decode()
	{
		int nSlots = header.slots();
	    int flush_main;
	    int gr, ch, ss, sb, sb18;
	    int main_data_end;
		int bytes_to_discard;
	    int i;

		get_side_info();

	    for (i=0; i>> 3; // of previous frame

	    if ((flush_main = (br.hsstell() & 7)) != 0) {
	         br.hgetbits(8 - flush_main);
				main_data_end++;
		 }

		 bytes_to_discard = frame_start - main_data_end
								  - si.main_data_begin;

		 frame_start += nSlots;

	    if (bytes_to_discard < 0)
				return;

		 if (main_data_end > 4096) {
				frame_start -= 4096;
				br.rewindNbytes(4096);
		 }

		 for (; bytes_to_discard > 0; bytes_to_discard--)
	    		br.hgetbits(8);

		 for (gr=0;gr>> 4) / 5 ;
				new_slen[1] = (scalefac_comp >>> 4) % 5 ;
				new_slen[2] = (scalefac_comp & 0xF) >>> 2 ;
				new_slen[3] = (scalefac_comp & 3);
	         	si.ch[ch].gr[gr].preflag = 0;
	         	blocknumber = 0;

	       } else if (scalefac_comp  < 500) {

				new_slen[0] = ((scalefac_comp - 400) >>> 2) / 5 ;
				new_slen[1] = ((scalefac_comp - 400) >>> 2) % 5 ;
				new_slen[2] = (scalefac_comp - 400 ) & 3 ;
				new_slen[3] = 0;
	         	si.ch[ch].gr[gr].preflag = 0;
	         	blocknumber = 1;

		   } else if (scalefac_comp < 512) {

				new_slen[0] = (scalefac_comp - 500 ) / 3 ;
				new_slen[1] = (scalefac_comp - 500)  % 3 ;
				new_slen[2] = 0;
				new_slen[3] = 0;
	      		si.ch[ch].gr[gr].preflag = 1;
		      	blocknumber = 2;
	 	   }
	   }

	   if((((mode_ext == 1) || (mode_ext == 3)) && (ch == 1)))
	   {
	      int_scalefac_comp = scalefac_comp >>> 1;

	      if (int_scalefac_comp < 180)
	      {
				new_slen[0] = int_scalefac_comp  / 36 ;
				new_slen[1] = (int_scalefac_comp % 36 ) / 6 ;
				new_slen[2] = (int_scalefac_comp % 36) % 6;
				new_slen[3] = 0;
	         	si.ch[ch].gr[gr].preflag = 0;
	         	blocknumber = 3;
	      } else if (int_scalefac_comp < 244) {
				new_slen[0] = ((int_scalefac_comp - 180 )  & 0x3F) >>> 4 ;
				new_slen[1] = ((int_scalefac_comp - 180) & 0xF) >>> 2 ;
				new_slen[2] = (int_scalefac_comp - 180 ) & 3 ;
				new_slen[3] = 0;
	         	si.ch[ch].gr[gr].preflag = 0;
	         	blocknumber = 4;
	      } else if (int_scalefac_comp < 255) {
				new_slen[0] = (int_scalefac_comp - 244 ) / 3 ;
				new_slen[1] = (int_scalefac_comp - 244 )  % 3 ;
				new_slen[2] = 0 ;
				new_slen[3] = 0;
	         	si.ch[ch].gr[gr].preflag = 0;
	         	blocknumber = 5;
	      }
	   }

	   for (int x=0; x<45; x++) // why 45, not 54?
	   	scalefac_buffer[x] = 0;

	   m = 0;
	   for (int i=0; i<4;i++) {
	     	for (int j = 0; j < nr_of_sfb_block[blocknumber][blocktypenumber][i];
	      	 j++)
	      {
	        scalefac_buffer[m] = (new_slen[i] == 0) ? 0 :
	        							  br.hgetbits(new_slen[i]);
	        m++;

	      } // for (unint32 j ...
   		} // for (uint32 i ...
	}

	/**
	 *
	 */
    private void get_LSF_scale_factors(int ch, int gr)
	{
		int m = 0;
	    int sfb, window;
		gr_info_s gr_info = (si.ch[ch].gr[gr]);

	    get_LSF_scale_data(ch, gr);

	    if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
	      if (gr_info.mixed_block_flag != 0) { 	// MIXED
	         for (sfb = 0; sfb < 8; sfb++)
	         {
	              scalefac[ch].l[sfb] = scalefac_buffer[m];
	              m++;
	         }
	         for (sfb = 3; sfb < 12; sfb++) {
	            for (window=0; window<3; window++)
	            {
	               scalefac[ch].s[window][sfb] = scalefac_buffer[m];
	               m++;
	            }
	         }
	         for (window=0; window<3; window++)
	            scalefac[ch].s[window][12] = 0;

	      } else {  // SHORT

	           for (sfb = 0; sfb < 12; sfb++) {
	               for (window=0; window<3; window++)
	               {
	                  scalefac[ch].s[window][sfb] = scalefac_buffer[m];
	                  m++;
	               }
	           }

	           for (window=0; window<3; window++)
	               scalefac[ch].s[window][12] = 0;
	      }
	   } else {   // LONG types 0,1,3

	      for (sfb = 0; sfb < 21; sfb++) {
	          scalefac[ch].l[sfb] = scalefac_buffer[m];
	          m++;
	      }
	      scalefac[ch].l[21] = 0; // Jeff
	      scalefac[ch].l[22] = 0;
		}
	}

	/**
	 *
	 */
    int[] x = {0};
	int[] y = {0};
	int[] v = {0};
	int[] w = {0};
	private void huffman_decode(int ch, int gr)
	{
		x[0] = 0;
		y[0] = 0;
		v[0] = 0;
		w[0] = 0;

	   	int part2_3_end = part2_start + si.ch[ch].gr[gr].part2_3_length;
	   	int num_bits;
		int region1Start;
		int region2Start;
	    int index;

	    int buf, buf1;

	 	huffcodetab h;

		// Find region boundary for short block case

		if ( ((si.ch[ch].gr[gr].window_switching_flag) != 0) &&
			  (si.ch[ch].gr[gr].block_type == 2) ) {

			// Region2.
	    //MS: Extrahandling for 8KHZ
	    region1Start = (sfreq == 8) ? 72 : 36;  // sfb[9/3]*3=36 or in case 8KHZ = 72
			region2Start = 576; // No Region2 for short block case

	  } else {          // Find region boundary for long block case

	    buf = si.ch[ch].gr[gr].region0_count + 1;
	    buf1 = buf + si.ch[ch].gr[gr].region1_count + 1;

	    if(buf1 > sfBandIndex[sfreq].l.length - 1) buf1 = sfBandIndex[sfreq].l.length - 1;

			region1Start = sfBandIndex[sfreq].l[buf];
			region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */
	   }

	   index = 0;
		// Read bigvalues area
		for (int i=0; i<(si.ch[ch].gr[gr].big_values<<1); i+=2) {
			if      (i= is_1d.length) System.out.println("i0="+i+"/"+(si.ch[ch].gr[gr].big_values<<1)+" Index="+index+" is_1d="+is_1d.length);
	      
	      is_1d[index++] = x[0];
	      is_1d[index++] = y[0];
	      
	      CheckSumHuff = CheckSumHuff + x[0] + y[0];
	      // System.out.println("x = "+x[0]+" y = "+y[0]);
		}

		// Read count1 area
		h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select+32];
	    num_bits = br.hsstell();

		while ((num_bits < part2_3_end) && (index < 576)) {

			huffcodetab.huffman_decoder(h, x, y, v, w, br);

	      is_1d[index++] = v[0];
	      is_1d[index++] = w[0];
	      is_1d[index++] = x[0];
	      is_1d[index++] = y[0];
          CheckSumHuff = CheckSumHuff + v[0] + w[0] + x[0] + y[0];
	      // System.out.println("v = "+v[0]+" w = "+w[0]);
	      // System.out.println("x = "+x[0]+" y = "+y[0]);
	      num_bits = br.hsstell();
	   }

		if (num_bits > part2_3_end) {
			br.rewindNbits(num_bits - part2_3_end);
	      index-=4;
	   }

	   num_bits = br.hsstell();

		// Dismiss stuffing bits
		if (num_bits < part2_3_end)
	   	br.hgetbits(part2_3_end - num_bits);

		// Zero out rest

	   if (index < 576)
		   nonzero[ch] = index;
	   else
	   	nonzero[ch] = 576;

	   if (index < 0) index = 0;

	   // may not be necessary
	   for (; index<576; index++)
   		is_1d[index] = 0;
	}

	/**
	 *
	 */
    private void i_stereo_k_values(int is_pos, int io_type, int i)
	{
	   if (is_pos == 0) {
	      k[0][i] = 1.0f;
	      k[1][i] = 1.0f;
	   } else if ((is_pos & 1) != 0) {
			k[0][i] = io[io_type][(is_pos + 1) >>> 1];
	      k[1][i] = 1.0f;
	   } else {
	      k[0][i] = 1.0f;
	      k[1][i] = io[io_type][is_pos >>> 1];
   	   }
	}

	/**
	 *
	 */
	private void dequantize_sample(float xr[][], int ch, int gr)
	{
		gr_info_s gr_info = (si.ch[ch].gr[gr]);
		int  cb=0;
		int  next_cb_boundary;
		int cb_begin = 0;
		int cb_width = 0;
		int  index=0, t_index, j;
	   	float g_gain;
	    float[][] xr_1d = xr;

		// choose correct scalefactor band per block type, initalize boundary

		if ((gr_info.window_switching_flag !=0 ) && (gr_info.block_type == 2) ) {
			if (gr_info.mixed_block_flag != 0)
				next_cb_boundary=sfBandIndex[sfreq].l[1];  // LONG blocks: 0,1,3
			else {
	         cb_width = sfBandIndex[sfreq].s[1];
			   next_cb_boundary = (cb_width << 2) - cb_width;
		 	   cb_begin = 0;
			}
		} else {
			next_cb_boundary=sfBandIndex[sfreq].l[1];  // LONG blocks: 0,1,3
	   }

	   // Compute overall (global) scaling.

		g_gain = (float) Math.pow(2.0 , (0.25 * (gr_info.global_gain - 210.0)));

	  	for (j=0; j 0) xr_1d[quotien][reste] = g_gain * t_43[abv];
				else
				{
					if (-abv < t_43.length) xr_1d[quotien][reste] = -g_gain * t_43[-abv];
					else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43);	
				} 
	         }
	         else
	         {
				if (is_1d[j] > 0) xr_1d[quotien][reste] = g_gain * (float)Math.pow(abv, d43);
				else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43);	         	
	         }
	        }
	   }

	   // apply formula per block type
	   for (j=0; j= 36)) ))
	      {

				t_index = (index - cb_begin) / cb_width;
	/*            xr[sb][ss] *= pow(2.0, ((-2.0 * gr_info.subblock_gain[t_index])
	                                    -(0.5 * (1.0 + gr_info.scalefac_scale)
	                                      * scalefac[ch].s[t_index][cb]))); */
				int idx = scalefac[ch].s[t_index][cb]
	           				 << gr_info.scalefac_scale;
	         idx += (gr_info.subblock_gain[t_index] << 2);

				xr_1d[quotien][reste] *= two_to_negative_half_pow[idx];

			} else {   // LONG block types 0,1,3 & 1st 2 subbands of switched blocks
	/*				xr[sb][ss] *= pow(2.0, -0.5 * (1.0+gr_info.scalefac_scale)
														 * (scalefac[ch].l[cb]
														 + gr_info.preflag * pretab[cb])); */
				int idx = scalefac[ch].l[cb];

	   		if (gr_info.preflag != 0)
			   	idx += pretab[cb];

			   idx = idx << gr_info.scalefac_scale;
	         xr_1d[quotien][reste] *= two_to_negative_half_pow[idx];
			}
	      index++;
		}

	   for (j=nonzero[ch]; j<576; j++)
	   {
            // Modif E.B 02/22/99
            int reste = j % SSLIMIT;
            int quotien = (int) ((j-reste)/SSLIMIT);
            if(reste < 0) reste = 0;
            if(quotien < 0) quotien = 0;
	     	xr_1d[quotien][reste] = 0.0f;
	   }

   	   return;
	}

    /**
	 *
	 */
	private void reorder(float xr[][], int ch, int gr)
	{
	   gr_info_s gr_info = (si.ch[ch].gr[gr]);
	   int freq, freq3;
	   int index;
	   int sfb, sfb_start, sfb_lines;
	   int src_line, des_line;
	   float[][] xr_1d = xr;

	   if ((gr_info.window_switching_flag !=0) && (gr_info.block_type == 2)) {

	      for(index=0; index<576; index++)
	         out_1d[index] = 0.0f;

			if (gr_info.mixed_block_flag !=0 ) {
				// NO REORDER FOR LOW 2 SUBBANDS
	            for (index = 0; index < 36; index++)
	            {
                    // Modif E.B 02/22/99
                    int reste = index % SSLIMIT;
                    int quotien = (int) ((index-reste)/SSLIMIT);
	                out_1d[index] = xr_1d[quotien][reste];
	            }
				// REORDERING FOR REST SWITCHED SHORT
				/*for( sfb=3,sfb_start=sfBandIndex[sfreq].s[3],
					 sfb_lines=sfBandIndex[sfreq].s[4] - sfb_start;
					 sfb < 13; sfb++,sfb_start = sfBandIndex[sfreq].s[sfb],
					 sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start )
					 {*/						   
		 		for( sfb=3; sfb < 13; sfb++)
	            	 {						   
							//System.out.println("sfreq="+sfreq+" sfb="+sfb+" sfBandIndex="+sfBandIndex.length+" sfBandIndex[sfreq].s="+sfBandIndex[sfreq].s.length);
							sfb_start = sfBandIndex[sfreq].s[sfb];
							sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start;

						   int sfb_start3 = (sfb_start << 2) - sfb_start;

							for(freq=0, freq3=0; freq=3; sfb-- ) {
	               	i = sfBandIndex[sfreq].s[sfb];
							lines = sfBandIndex[sfreq].s[sfb+1] - i;
	                  i = (i << 2) - i + (j+1) * lines - 1;

							while (lines > 0) {
	                  	if (ro[1][i/18][i%18] != 0.0f) {
							// MDM: in java, array access is very slow.
							// Is quicker to compute div and mod values.
						//if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) {
	                     	sfbcnt = sfb;
									sfb = -10;
									lines = -10;
								}

								lines--;
								i--;

							} // while (lines > 0)

						} // for (sfb=12 ...
						sfb = sfbcnt + 1;

						if (sfb > max_sfb)
							max_sfb = sfb;

						while(sfb < 12) {
	               	temp = sfBandIndex[sfreq].s[sfb];
	               	sb   = sfBandIndex[sfreq].s[sfb+1] - temp;
	                  i    = (temp << 2) - temp + j * sb;

							for ( ; sb > 0; sb--) {
	                  	is_pos[i] = scalefac[1].s[j][sfb];
								if (is_pos[i] != 7)
	                     	if (lsf)
	                           i_stereo_k_values(is_pos[i], io_type, i);
	                        else
	                        	is_ratio[i] = TAN12[is_pos[i]];

								i++;
							} // for (; sb>0...
							sfb++;
						} // while (sfb < 12)
						sfb = sfBandIndex[sfreq].s[10];
	               sb  = sfBandIndex[sfreq].s[11] - sfb;
	               sfb = (sfb << 2) - sfb + j * sb;
	               temp  = sfBandIndex[sfreq].s[11];
	               sb = sfBandIndex[sfreq].s[12] - temp;
	               i = (temp << 2) - temp + j * sb;

						for (; sb > 0; sb--) {
	               	is_pos[i] = is_pos[sfb];

			            if (lsf) {
			               k[0][i] = k[0][sfb];
					         k[1][i] = k[1][sfb];
			            } else {
	     						is_ratio[i] = is_ratio[sfb];
	                  }
							i++;
						} // for (; sb > 0 ...
					 }
					 if (max_sfb <= 3) {
	                i = 2;
						 ss = 17;
						 sb = -1;
						 while (i >= 0) {
	                	if (ro[1][i][ss] != 0.0f) {
	                   	 sb = (i<<4) + (i<<1) + ss;
								 i = -1;
							} else {
	                      ss--;
								 if (ss < 0) {
	                         i--;
									 ss = 17;
								 }
							} // if (ro ...
						 } // while (i>=0)
						 i = 0;
						 while (sfBandIndex[sfreq].l[i] <= sb)
							 i++;
						 sfb = i;
						 i = sfBandIndex[sfreq].l[i];
						 for (; sfb<8; sfb++) {
	                   sb = sfBandIndex[sfreq].l[sfb+1]-sfBandIndex[sfreq].l[sfb];
							 for (; sb>0; sb--) {
	                      is_pos[i] = scalefac[1].l[sfb];
	                   	 if (is_pos[i] != 7)
		                      if (lsf)
	                           i_stereo_k_values(is_pos[i], io_type, i);
	                         else
	                        	is_ratio[i] = TAN12[is_pos[i]];
								 i++;
							 } // for (; sb>0 ...
						 } // for (; sfb<8 ...
					 } // for (j=0 ...
				} else { // if (gr_info.mixed_block_flag)
	         	for (int j=0; j<3; j++) {
	            	int sfbcnt;
						sfbcnt = -1;
						for( sfb=12; sfb >=0; sfb-- )
						{
							temp = sfBandIndex[sfreq].s[sfb];
	                  lines = sfBandIndex[sfreq].s[sfb+1] - temp;
	                  i = (temp << 2) - temp + (j+1) * lines - 1;

							while (lines > 0) {
								if (ro[1][i/18][i%18] != 0.0f) {
								// MDM: in java, array access is very slow.
								// Is quicker to compute div and mod values.
								//if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) {
	                     	sfbcnt = sfb;
									sfb = -10;
									lines = -10;
								}
								lines--;
								i--;
							} // while (lines > 0) */

						} // for (sfb=12 ...
						sfb = sfbcnt + 1;
						while(sfb<12) {
							temp = sfBandIndex[sfreq].s[sfb];
	                  sb   = sfBandIndex[sfreq].s[sfb+1] - temp;
	                  i    = (temp << 2) - temp + j * sb;
							for ( ; sb > 0; sb--) {
	                  	is_pos[i] = scalefac[1].s[j][sfb];
								if (is_pos[i] != 7)
		                      if (lsf)
	                           i_stereo_k_values(is_pos[i], io_type, i);
	                         else
	                        	is_ratio[i] = TAN12[is_pos[i]];
								i++;
							} // for (; sb>0 ...
							sfb++;
						} // while (sfb<12)

						temp = sfBandIndex[sfreq].s[10];
	               temp2= sfBandIndex[sfreq].s[11];
	               sb   = temp2 - temp;
	               sfb  = (temp << 2) - temp + j * sb;
	               sb   = sfBandIndex[sfreq].s[12] - temp2;
	               i    = (temp2 << 2) - temp2 + j * sb;

						for (; sb>0; sb--) {
	               	is_pos[i] = is_pos[sfb];

			            if (lsf) {
			               k[0][i] = k[0][sfb];
					         k[1][i] = k[1][sfb];
	      		      } else {
	               		is_ratio[i] = is_ratio[sfb];
	                  }
							i++;
						} // for (; sb>0 ...
					} // for (sfb=12
				} // for (j=0 ...
			} else { // if (gr_info.window_switching_flag ...
	      	i = 31;
				ss = 17;
				sb = 0;
				while (i >= 0) {
	         	if (ro[1][i][ss] != 0.0f) {
	            	sb = (i<<4) + (i<<1) + ss;
						i = -1;
					} else {
	            	ss--;
						if (ss < 0) {
	               	i--;
							ss = 17;
						}
					}
				}
				i = 0;
				while (sfBandIndex[sfreq].l[i] <= sb)
					i++;

				sfb = i;
				i = sfBandIndex[sfreq].l[i];
				for (; sfb<21; sfb++) {
	         	sb = sfBandIndex[sfreq].l[sfb+1] - sfBandIndex[sfreq].l[sfb];
	         	for (; sb > 0; sb--) {
	            	is_pos[i] = scalefac[1].l[sfb];
						if (is_pos[i] != 7)
	                  if (lsf)
	                     i_stereo_k_values(is_pos[i], io_type, i);
	                  else
	                   	is_ratio[i] = TAN12[is_pos[i]];
						i++;
					}
				}
				sfb = sfBandIndex[sfreq].l[20];
				for (sb = 576 - sfBandIndex[sfreq].l[21]; (sb > 0) && (i<576); sb--)
				{
	         	is_pos[i] = is_pos[sfb]; // error here : i >=576

	            if (lsf) {
	               k[0][i] = k[0][sfb];
			         k[1][i] = k[1][sfb];
	            } else {
	  					is_ratio[i] = is_ratio[sfb];
	            }
					i++;
				} // if (gr_info.mixed_block_flag)
			} // if (gr_info.window_switching_flag ...
		} // if (i_stereo)

	   	i = 0;
			for(sb=0;sb




© 2015 - 2025 Weber Informatics LLC | Privacy Policy