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

📄 rpe.java

📁 java处理声音文件
💻 JAVA
字号:
/* * Rpe port to Java. * Copyright (C) 1999  Christopher Edwards *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. * */package	org.tritonus.lowlevel.gsm;public class Rpe{	private short 	exp_in;      /* IN   */	private short 	mant_in;     /* IN   */	private short 	exp_out;     /* OUT  */	private short 	mant_out;    /* OUT  */	private int 	xMp_point = 0;	private static final int ENCODE = 0;	private static final int DECODE = 1;        	private short[] x = new short[40];	/* signal [0..39]         OUT */   	public void Gsm_RPE_Encoding(		short[]	e,	/* -5..-1][0..39][40..44            IN/OUT  */		short[]	xmaxc,	/* [0..3] Coded maximum amplitude   OUT     */		short[]	Mc,	/* [0..3] RPE grid selection        OUT     */		int	xmaxc_Mc_index,	/* Ref. point for xmaxc and Mc            */		short[]	xMc,	/* [0..12]                          OUT     */		int	xMc_index	/* Ref. for xmc, '+=13' */ )	{		short[]	xM  = new short[13]; 		short[]	xMp = new short[13];		Weighting_filter( e );  /* Sets up the private data member 'x[40]' */		RPE_grid_selection( xM, Mc, xmaxc_Mc_index );    /* Sets up xM[13] */		/* Sets up xmc (13 array locations starting from xMc_index),		 * xmaxc (one array location at xmaxc_Mc_index), 		 * exp_in and mant_in 		 */		APCM_quantization( xM, xMc, xMc_index, xmaxc, xmaxc_Mc_index );		/* Sets up xMp[13] */		APCM_inverse_quantization( xMc, xMp, xMc_index, ENCODE );		RPE_grid_positioning( Mc[xmaxc_Mc_index], xMp, e, ENCODE );	}	/*	 *  The coefficients of the weighting filter are stored in a table	 *  (see table 4.4).  The following scaling is used:	 *	 *      H[0..10] = integer( real_H[ 0..10] * 8192 );	 */	private void Weighting_filter(		short[] e)	/* signal [-5..0.39.44] IN  */ 	{		int     L_result = 0;		int     i = 0;		/*		 *  (e[-5..-1] and e[40..44] are allocated by the caller,		 *  are initially zero and are not written anywhere.)		 *		 *  e -= 5;		 * 		 *  The above case is true with the C code, although java		 *  does not have pointers so e[0..49] is all set for this 		 *  method.		 */		/*  Compute the signal x[0..39]		 */		for (int k = 0; k <= 39; k++)		{			L_result = 8192 >> 1;			/*  Every one of these multiplications is done twice --			 *  but I don't see an elegant way to optimize this.			 *  Do you?			 */		        /* #define STEP( i, H )    (e[ k + i ] * H) */			i = 0;                			L_result +=( e[ k + 0 ] * -134 )				+ ( e[ k + 1 ] * -374 )				/* + STEP( 2,      0    ) no sense in adding zero */				+ ( e[ k + 3 ] * 2054 )				+ ( e[ k + 4 ] * 5741 )				+ ( e[ k + 5 ] * 8192 )				+ ( e[ k + 6 ] * 5741 )				+ ( e[ k + 7 ] * 2054 )				/* + STEP( 8,      0    ) no sense in adding zero */				+ ( e[ k + 9 ] * -374 )				+ ( e[ k + 10 ] * -134 );			/* 2 adds vs. >>16 => 14, minus one shift to compensate for			 * those we lost when replacing L_MULT by '*'.			 */ 			L_result = Add.SASR( L_result, 13 );			x[k] = (short) ((L_result < Gsm_Def.MIN_WORD ? Gsm_Def.MIN_WORD					 : (L_result > Gsm_Def.MAX_WORD ? Gsm_Def.MAX_WORD 					    : L_result )));		}	}	/*	 *  The signal x[0..39] is used to select the RPE grid which is	 *  represented by Mc.	 */	private void RPE_grid_selection(		short[]    xM,           /* [0..12]              OUT */		short[]    Mc_out,       /*                      OUT */   		int	   Mc_index)	{		int     m = 0;		int     L_result = 0;		int     EM = 0;     /* xxx should be L_EM? */		short   Mc = 0;		int     L_common_0_3;		/* common part of 0 and 3 */		L_result = 0;        		L_result += STEP( 0, 1 ) +  STEP( 0, 2 ) +  STEP( 0, 3 ) +  STEP( 0, 4 ) 			+  STEP( 0, 5 ) +  STEP( 0, 6 ) +  STEP( 0, 7 ) +  STEP( 0, 8 ) 			+  STEP( 0, 9 ) +  STEP( 0, 10) +  STEP( 0, 11) +  STEP( 0, 12);                 		L_common_0_3 = L_result;		/* i = 0 */		L_result += STEP( 0, 0 );		L_result <<= 1; /* implicit in L_MULT */		EM = L_result;		/* i = 1 */		L_result = 0;		L_result += STEP( 1, 0 ) + STEP( 1, 1 ) + STEP( 1, 2 ) + STEP( 1, 3 )			+  STEP( 1, 4 ) + STEP( 1, 5 ) + STEP( 1, 6 ) + STEP( 1, 7 )			+  STEP( 1, 8 ) + STEP( 1, 9 ) + STEP( 1, 10) + STEP( 1, 11)			+  STEP( 1, 12);        		L_result <<= 1;		if (L_result > EM) {			Mc = 1;			EM = L_result;		}		/* i = 2 */		L_result = 0;		L_result += STEP( 2, 0 ) + STEP( 2, 1 ) + STEP( 2, 2 ) + STEP( 2, 3 )			+  STEP( 2, 4 ) + STEP( 2, 5 ) + STEP( 2, 6 ) + STEP( 2, 7 )			+  STEP( 2, 8 ) + STEP( 2, 9 ) + STEP( 2, 10) + STEP( 2, 11)			+  STEP( 2, 12);       		L_result <<= 1;		if (L_result > EM) {			Mc = 2;			EM = L_result;		}		/* i = 3 */		L_result = L_common_0_3;		L_result += STEP( 3, 12 );		L_result <<= 1;		if (L_result > EM)		{			Mc = 3;			EM = L_result;		}		/*  Down-sampling by a factor 3 to get the selected xM[0..12]		 *  RPE sequence.		 */		for (int i = 0; i <= 12; i ++)		{			xM[i] = x[Mc + 3*i];		}	    		Mc_out[Mc_index] = Mc;	}	private int STEP(int m, int i )	{		int L_temp;		L_temp = Add.SASR( x[m + 3 * i], 2 );       		return ( L_temp * L_temp );	} 	private void APCM_quantization (		short[]         xM,           /* [0..12]              IN      */		short[]         xMc,          /* [0..12]              OUT     */		int		xMc_index,		short[]         xmaxc_out,    /*                      OUT     */		int 		xmaxc_index)		throws IllegalArgumentException {		int     itest = 0;		short   xmax = 0, xmaxc = 0, temp = 0, temp1 = 0, temp2 = 0;		short   exp = 0, mant = 0;		/*  Find the maximum absolute value xmax of xM[0..12].		 */		for (int i = 0; i <= 12; i++)		{			temp = xM[i];			temp = Add.GSM_ABS(temp);			if (temp > xmax)			{				xmax = temp;			}		}		/*  Qantizing and coding of xmax to get xmaxc.		 */		exp   = 0;		temp  = Add.SASR( xmax, 9 );		itest = 0;		for (int i = 0; i <= 5; i++)		{			if(temp <= 0)			{				itest |= 1;			}			else			{				itest |= 0;			}			temp = Add.SASR( temp, 1 );			if( ! (exp <= 5))			{				throw new IllegalArgumentException					("APCM_quantization: exp = "					 +exp+" is out of range. Should be <= 5");			}			if (itest == 0)			{				exp++;          /* exp = add (exp, 1) */			}		}		if( ! (exp <= 6 && exp >= 0))		{			throw new IllegalArgumentException				("APCM_quantization: exp = "				 +exp+" is out of range. Should be >= -4 and <= 6");		}		temp = (short) (exp + 5);		if( ! (temp <= 11 && temp >= 0))		{			throw new IllegalArgumentException				("APCM_quantization: temp = "				 +temp+" is out of range. Should be >= 0 and <= 11");		}		xmaxc = Add.GSM_ADD( Add.SASR(xmax, temp), (short) (exp << 3) );		/*   Quantizing and coding of the xM[0..12] RPE sequence		 *   to get the xMc[0..12]		 */        		APCM_quantization_xmaxc_to_exp_mant( xmaxc, ENCODE );		exp = exp_in;		mant = mant_in;        		/*  This computation uses the fact that the decoded version of xmaxc		 *  can be calculated by using the exponent and the mantissa part of		 *  xmaxc (logarithmic table).		 *  So, this method avoids any division and uses only a scaling		 *  of the RPE samples by a function of the exponent.  A direct		 *  multiplication by the inverse of the mantissa (NRFAC[0..7]		 *  found in table 4.5) gives the 3 bit coded version xMc[0..12]		 *  of the RPE samples.		 */		/* Direct computation of xMc[0..12] using table 4.5		 */		if( ! (exp <= 4096 && exp >= -4096))		{			throw new IllegalArgumentException				("APCM_quantization: exp = "				 +exp+" is out of range. Should be >= -4096 and <= 4096");		}		if( ! (mant >= 0 && mant <= 7 ))		{			throw new IllegalArgumentException				("APCM_quantization: mant = "				 +mant+" is out of range. Should be >= 0 and <= 7");		}		temp1 = (short) (6 - exp);          /* normalization by the exponent */		temp2 = Gsm_Def.gsm_NRFAC[ mant ];  /* inverse mantissa          */		for (int i = 0; i <= 12; i++)		{			if( ! (temp1 >= 0 && temp1 < 16))			{				throw new IllegalArgumentException					("APCM_quantization: temp = "					 +temp+" is out of range. Should be >= 0 and < 16");			}			temp = (short) (xM[i] << temp1);			temp = Add.GSM_MULT( temp, temp2 );			temp = Add.SASR(temp, 12);			xMc[i + xMc_index] = (short) (temp + 4);    /* see note below */		}		/*  NOTE: This equation is used to make all the xMc[i] positive.		 */		mant_in   = mant;		exp_in    = exp;		xmaxc_out[xmaxc_index] = xmaxc;	}	public void APCM_quantization_xmaxc_to_exp_mant(		short xmaxc_elem,		int METHOD_ID)		throws IllegalArgumentException	{		short    exp = 0, mant = 0;		/* Compute exponent and mantissa of the decoded version of xmaxc		 */		if (xmaxc_elem > 15)		{			exp = (short) (Add.SASR(xmaxc_elem, 3) - 1);		}		mant = (short) (xmaxc_elem - (exp << 3));		if (mant == 0)		{			exp = (short) -4;			mant = (short) 7;		}		else		{			while (mant <= 7)			{				mant = (short) (mant << 1 | 1);				exp--;			}			mant -= (short) 8;		}		if( exp < -4 || exp > 6 )		{			throw new IllegalArgumentException				("APCM_quantization_xmaxc_to_exp_mant: exp = "				 +exp+" is out of range. Should be >= -4 and <= 6");		}		if( mant < 0 || mant > 7 )		{			throw new IllegalArgumentException				("APCM_quantization_xmaxc_to_exp_mant: mant = "				 +mant+" is out of range. Should be >= 0 and <= 7");		}		if ( METHOD_ID == ENCODE )		{			exp_in  = exp;			mant_in = mant;		}		else		{ /* DECODE */			exp_out  = exp;			mant_out = mant;		}	}	public void Gsm_RPE_Decoding_java(		short xmaxc_elem,  /* From Gsm_Decoder xmaxc short array */		short Mc_elem,     /* From Gsm_Decoder Mc short array */		int	xmc_start,	/* Starting point for the three bit part of xmc */		short[] xmc,       /* [0..12], 3 bits     IN      */		short[] erp        /* [0..39]             OUT     */  )	{		short    xMp[] = new short[13];		/* exp_out and mant_out are modified in this method */		APCM_quantization_xmaxc_to_exp_mant(xmaxc_elem, DECODE);		APCM_inverse_quantization(xmc, xMp, xmc_start, DECODE);		RPE_grid_positioning(Mc_elem, xMp, erp, DECODE);	}	/*	 *  This part is for decoding the RPE sequence of coded xMc[0..12]	 *  samples to obtain the xMp[0..12] array.  Table 4.6 is used to get	 *  the mantissa of xmaxc (FAC[0..7]).	 */	public void APCM_inverse_quantization(		short[] xmc,   /* [0..12]                      IN      */		short[] xMp,   /* [0..12]                      OUT     */		int 	xmc_start,		int 	METHOD_ID)		throws IllegalArgumentException	{		short      temp, temp1, temp2, temp3;		if ( METHOD_ID == ENCODE )		{			temp1 = Gsm_Def.gsm_FAC[ mant_in ];			temp2 = Add.GSM_SUB( (short)6, exp_in );		}		else		{ /* DECODE */			temp1 = Gsm_Def.gsm_FAC[ mant_out ];   			temp2 = Add.GSM_SUB( (short)6, exp_out ); 		}		temp3 = Add.gsm_asl( (short)1, Add.GSM_SUB( temp2, (short)1 ));        		xMp_point = 0;        		for (int i = 0; i < 13; i++)		{			/* restore sign   */			temp = (short) ((xmc[xmc_start++] << 1) - 7);  			if( ! (temp <= 7 && temp >= -7) )			{    /* 4 bit signed   */				throw new IllegalArgumentException					("APCM_inverse_quantization: temp = "					 +temp+" is out of range. Should be >= -7 and <= 7");			}			temp <<= 12;                        /* 16 bit signed  */			temp = Add.GSM_MULT_R( temp1, temp );			temp = Add.GSM_ADD( temp, temp3 );			xMp[ xMp_point++ ] = Add.gsm_asr( temp, temp2 );		}	}	/*	 *  This method computes the reconstructed long term residual signal	 *  ep[0..39] for the LTP analysis filter.  The inputs are the Mc	 *  which is the grid position selection and the xMp[0..12] decoded	 *  RPE samples which are upsampled by a factor of 3 by inserting zero	 *  values.	 */	public static void RPE_grid_positioning(		short   Mc,            /* grid position        IN      */		short[] xMp,           /* [0..12]              IN      */		short[] ep,            /* [0..39]              OUT     */		int     METHOD_ID)		throws IllegalArgumentException	{    		int     i = 13;	     		int     xMp_index = 0;		int 	ep_index;        		if (METHOD_ID == ENCODE)		{			ep_index = 5;		}		else		{ /* Decode */			ep_index = 0;		}        		if( ! (0 <= Mc && Mc <= 3) )		{			throw new IllegalArgumentException				("RPE_grid_positioning: Mc = "				 +Mc+" is out of range. Should be >= 0 and <= 3");		}		switch (Mc)		{                case 3:			ep[ep_index++] = 0;		        do			{				ep[ep_index++] = 0;				ep[ep_index++] = 0;				ep[ep_index++] = xMp[xMp_index++];				--i;                        }			while (i != 0);			break;                case 2:			do			{				ep[ep_index++] = 0;				ep[ep_index++] = 0;				ep[ep_index++] = xMp[xMp_index++];				--i;			}			while (i != 0);			break;                case 1:			do			{				ep[ep_index++] = 0;				ep[ep_index++] = xMp[xMp_index++];				ep[ep_index++] = 0;				--i;			}			while (i != 0);			break;                case 0:			do			{				ep[ep_index++] = xMp[xMp_index++];				ep[ep_index++] = 0;				ep[ep_index++] = 0;				--i;			}			while (i != 0);			break;		}		if (METHOD_ID == ENCODE)		{			ep[ep_index++] = 0;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -