mmlibs/mmfw/Codecs/Src/Gsm610CodecCommon/basicop.cpp
changeset 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/Codecs/Src/Gsm610CodecCommon/basicop.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,726 @@
+// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "basicop.h"
+
+/*
+** int2 add( int2 var1, int2 var2 )
+**
+** Function performs the addition (var1+var2) with overflow control
+** and saturation; the result is set at +32767 when overflow occurs
+** or at -32768 when underflow occurs
+**
+** Input:
+**   var1, var2
+**     16-bit variables to be summed
+**
+** Output:
+**   Sum of var and var2, see description above
+**  
+** Return value:
+**   See above
+*/
+/*
+** One way to implement saturation control to add and sub is to
+** use temporary result that has enough bits to make overflow
+** impossible and the limit the final result
+*/
+int2 add( int2 var1, int2 var2 )
+{
+  int4 L_temp;
+  
+  L_temp = (int4) var1 + var2;
+  
+  if ( L_temp < MININT2 )
+    return MININT2;
+  else if ( L_temp > MAXINT2 )
+    return MAXINT2;
+  else
+    return (int2) L_temp;
+}
+
+
+/*
+** int2 sub( int2 var1, int2 var2 )
+**
+** Function performs the subtraction (var1-var2) with overflow control
+** and saturation; the result is set at +32767 when overflow occurs
+** or at -32768 when underflow occurs
+**
+** Input:
+**   var1, var2
+**     16-bit variables to be summed
+**
+** Output:
+**   Sum of var and var2, see description above
+**  
+** Return value:
+**   See above
+*/
+int2 sub( int2 var1, int2 var2 )
+{
+  int4 L_temp;
+  
+  L_temp = (int4) var1 - var2;
+  
+  if ( L_temp < MININT2 )
+    return MININT2;
+  else if ( L_temp > MAXINT2 )
+    return MAXINT2;
+  else
+    return (int2) L_temp;
+}
+
+
+
+/*
+** int2 mult( int2 var1, int2 var2 )
+**
+** Function performs the multiplication of var1 by var2 and gives a
+** 16-bit result which is scaled ie
+**   mult( var1, var2 ) = (var1 times var2) >> 15
+** and
+**   mult( -32768, -32768 ) = 32767 
+**
+** Input:
+**   var1, var2
+**     16-bit variables to be multiplied
+**
+** Output:
+**   Scaled result of multiplication
+**  
+** Return value:
+**   See above
+*/
+int2 mult( int2 var1, int2 var2 )
+{
+  if ( ( var1 == MININT2 ) && ( var1 == var2 ) )
+    return MAXINT2;
+  else
+    /* Note int4 cast of var1 to force 32-bit arithmetic */
+   return( (int2) ( ( (int4) var1 * var2 ) >> 15 ) );
+}
+
+
+/*
+** int2 abs_s( int2 var1 )
+**
+** Function returns absolute value of var1 with possible saturation:
+**   abs( -32768 ) = 32767
+**
+** Input:
+**   var1
+**     16-bit variable
+**
+** Output:
+**   absolute value of var1
+**  
+** Return value:
+**   See above
+*/
+int2 abs_s( int2 var1 )
+{
+  if ( var1 == MININT2 )
+    return MAXINT2;
+  else
+    return ( var1 > 0 ) ? var1 : int2 (-var1);
+}
+
+
+#ifdef L_MULTF
+/* else implemented using macro (basicop.h) */
+
+/*
+** int4 L_mult( int2 var1, int2 var2 )
+**
+** Function performs the multiplication of var1 by var2 and gives a
+** 32-bit result which is scaled by shifting result one bit left ie
+**   L_mult( var1, var2 ) = (var1 times var2) << 1
+**
+**   L_mult( -32768, -32768 ) does not occur in algorithm
+**
+** Input:
+**   var1, var2
+**     16-bit variables to be multiplied
+**
+** Output:
+**   Scaled result of multiplication
+**  
+** Return value:
+**   See above
+*/
+int4 L_mult( int2 var1, int2 var2 )
+{
+  /* Note int4 cast of var1 to force 32-bit arithmetic */
+  return ( L_shl( (int4) var1 * var2 ), 1 );
+}
+#endif /* L_MULTF */
+
+
+
+/*
+** int2 shr( int2 var1, int2 var2 )
+**
+** Function makes arithmetic var2-bit shift right of var1. If var2 is
+** less than 0, this operation becomes arithmetic left shift of -var2
+**
+** Input:
+**   var1
+**     16-bit variable to be shifted
+**   var2
+**     amount of bits to be shifted
+**
+** Output:
+**   16-bit value of shifted var1 is returned 
+**  
+** Return value:
+**   See above
+*/
+int2 shr( int2 var1, int2 var2 )
+{
+  return shl( var1, int2 (-var2) );
+}
+
+
+/*
+** int2 negate( int2 var1 )
+**
+** Function negates 16-bit variable var1. 
+**   negate( -32768 ) = 32767
+**
+** Input:
+**   var1
+**     16-bit variable to be negated
+**
+** Output:
+**   negated var1
+**  
+** Return value:
+**   See above
+*/
+int2 negate( int2 var1 )
+{
+  if ( var1 == MININT2 )
+    return MAXINT2;
+  else
+    return int2 (-var1);
+}
+
+
+/*
+** int2 extract_h( int4 L_var1 )
+**
+** Function returns upper word (16 most significat bits) of the 
+** 32-bit variable L_var1
+**
+** Input:
+**   L_var1
+**     32-bit variable
+**
+** Output:
+**   upper word of the L_var1
+**  
+** Return value:
+**   See above
+*/
+int2 extract_h( int4 L_var1 )
+{
+  return (int2) ( L_var1 >> 16 );
+}
+
+
+/*
+** int2 extract_l( int4 L_var1 )
+**
+** Function returns lower word (16 least significat bits) of the
+** 32-bit variable L_var1
+**
+** Input:
+**   L_var1
+**     32-bit variable
+**
+** Output:
+**   lower word of L_var1
+**  
+** Return value:
+**   See above
+*/
+int2 extract_l( int4 L_var1 )
+{
+  return (int2) (L_var1 & 0x0000ffff);
+}
+
+
+/*
+** int4 L_mac( int4 L_var3, int2 var1, int2 var2 )
+**
+** Function multiplies var1 by var2 and shifts result left by one bit.
+** Shifted result of multiplication is then added to L_var3 and result
+** is returned. Summation is done with overflow control and saturation;
+** the result is set at 2147483647 when overflow occurs and at
+** -2147483648 when underflow occurs
+**
+** Input:
+**   var1
+**     16-bit multiplicant
+**   var2
+**     16-bit multiplier
+**
+**   L_var3
+**     32-bit number that is summed with (var1*var2)<<1
+**
+** Output:
+**   See description above
+**  
+** Return value:
+**   See above
+*/
+int4 L_mac( int4 L_var3, int2 var1, int2 var2 )
+{
+  int4 L_temp;
+
+  L_temp = ( (int4) var1 * var2 ) << 1;
+  return L_add( L_var3, L_temp );
+}
+
+
+/*
+** int4 L_add( int4 L_var1, int4 L_var2 )
+**
+** Function performs 32-bit addition of two 32-bit variables
+** (L_var1 + L_var2) with overflow control and saturation; the
+** result is set at 2147483647 when overflow occurs and at
+** -2147483648 when underflow occurs
+**
+** Input:
+**   L_var1, L_var2
+**     32-bit variables to be summed
+**
+** Output:
+**   32-bit result, see description above
+**  
+** Return value:
+**   See above
+*/
+int4 L_add( int4 L_var1, int4 L_var2 )
+{
+  int4 L_temp1;
+  int temp2; /* used for storing sign of L_var1 */
+  
+  L_temp1 = L_var1 + L_var2;
+
+  /*
+   * Overflow
+   *   if sign(L_var1)==sign(L_var2) && sign(L_var1)!=sign(L_temp1).
+   */
+
+  if ( ( temp2 = (L_var1 < 0) ) == ( L_var2 < 0 ) 
+    && ( temp2 != ( L_temp1 < 0 ) ) ) {
+      L_temp1 = temp2 ? MININT4 : MAXINT4;
+  }
+
+  return L_temp1;
+}
+
+
+/*
+** int4 L_sub( int4 L_var1, int4 L_var2 )
+**
+** Function performs 32-bit subtraction of two 32-bit variables
+** (L_var1 - L_var2) with overflow control and saturation; the
+** result is set at 2147483647 when overflow occurs and at
+** -2147483648 when underflow occurs
+**
+** Input:
+**   L_var1, L_var2
+**     32-bit variables to be summed
+**
+** Output:
+**   32-bit result, see description above
+**  
+** Return value:
+**   See above
+*/
+int4 L_sub( int4 L_var1, int4 L_var2 )
+{
+  int4 L_temp1;
+  int temp2;
+
+  L_temp1 = L_var1 - L_var2;
+
+  /*
+   * Overflow
+   *   if sign(L_var1)!=sign(L_var2) && sign(L_var1)!=sign(L_temp).
+   */
+
+  if ( ( temp2 = ( L_var1 < 0 ) ) != ( L_var2 < 0 ) 
+    && ( temp2 != ( L_temp1 < 0 ) ) ) {
+      L_temp1 = temp2 ? MININT4 : MAXINT4;
+  }
+
+  return L_temp1;
+}
+
+
+/*
+** int2 mult_r( int2 var1, int2 var2 )
+**
+** Function performs the multiplication of var1 by var2 and gives a
+** 16-bit result which is scaled with rounding ie
+**   mult_r(var1, var2) = ((var1 times var2) + 16384) >> 15
+** and
+**   mult_r( -32768, -32768 ) = 32767 
+**
+** Input:
+**   var1, var2
+**     16-bit variables to be multiplied
+**
+** Output:
+**   16-bit scaled result of multiplication
+**  
+** Return value:
+**   See above
+*/
+int2 mult_r( int2 var1, int2 var2 )
+{
+  if ( ( var1 == MININT2 ) && ( var1 == var2 ) )
+    return MAXINT2;
+  else
+    /* Note int4 cast of var1 to force 32-bit arithmetic */
+    return( (int2) ( ( (int4) var1 * var2 + (int4) 16384 ) >> 15 ) );
+}
+
+/*
+** int4 L_shr( int4 L_var1, int2 var2 )
+**
+** Function makes arithmetic var2-bit shift right of var1. If var2 is
+** less than 0, this operation becomes arithmetic left shift of -var2
+**
+** Input:
+**   L_var1
+**     32-bit variable to be shifted
+**   var2
+**     amount of bits to be shifted
+**
+** Output:
+**   16-bit value of shifted var1
+**  
+** Return value:
+**   See above
+*/
+int4 L_shr( int4 L_var1, int2 var2 )
+{
+  return L_shl( L_var1, int2 (-var2) );
+}
+
+
+/*
+** int4 L_deposit_h( int2 var1 )
+**
+** Function deposits the 16-bit variable var1 into the 16 most
+** significant bits of the 32-bit word. The 16 least significant
+** bits of the result are zeroed.
+**
+** Input:
+**   var1
+**     16-bit variable to be loaded to the upper 16 bits of
+**     of the 32-bit variable
+**
+** Output:
+**   32-bit number, see description above
+**  
+** Return value:
+**   See above
+*/
+int4 L_deposit_h( int2 var1 )
+{
+  return ( (int4) var1 ) << 16;
+}
+
+
+/*
+** int4 L_deposit_l( int2 var1 )
+**
+** Function deposits the 16-bit variable var1 into the 16 least
+** significant bits of the 32-bit word. The 16 most significant bits
+** of the result are sign extended.
+**
+** Input:
+**   var1
+**     16-bit variable to be converted to 32-bit variable
+**
+** Output:
+**   32-bit variable that has same magnitude than var1
+**  
+** Return value:
+**   See above
+*/
+int4 L_deposit_l( int2 var1 )
+{
+  return (int4) var1;
+}
+
+
+/*
+** int2 norm_s( int2 var1 )
+**
+** Function produces number of left shifts needed to normalize the
+** 16-bit variable var1 for positive values on the interval with
+** minimum of 16384 and maximum of 32767 and for negative
+** values on the interval with minimum of -32768 and maximum of
+** -16384; in order to normalize the result, the following
+** operation must be done:
+**   norm_var1 = var1 << norm_s(var1)
+**
+** Input:
+**   var1
+**     16-bit variable which normalization factor is solved
+**
+** Output:
+**   see description above
+**  
+** Return value:
+**   See above
+*/
+int2 norm_s( int2 var1 )
+{
+  int2 cntr = 0;
+
+  /* Special case when L_var1 == -32768: shift leads to underflow */
+  if ( var1 == MININT2 )
+    return 0;
+  /* Special case when var1 == 0: shift does not change the value */
+  else if ( var1 == 0 )
+    return 0;
+  else {
+    if ( var1 < 0 ) {
+      for ( ; var1 >= -16384; var1 *= 2 )
+	cntr++;      
+    }
+    else {
+      for ( ; var1 < 16384; var1 <<= 1 )
+	cntr++;
+    }
+
+    return cntr;
+  }
+}
+
+
+/*
+** int2 norm_l( int4 L_var1 )
+**
+** Function produces number of left shifts needed to normalize the
+** 32-bit variable L_var1 for positive values on the interval with
+** minimum of 1073741824 and maximum of 2147483647 and for negative
+** values on the interval with minimum of -2147483648 and maximum of
+** -1073741824; in order to normalize the result, the following
+** operation must be done:
+**   L_norm_var1 = L_var1 << norm_l(L_var1)
+**
+** Input:
+**   L_var1
+**     32-bit variable which normalization factor is solved
+**
+** Output:
+**   see description above
+**  
+** Return value:
+**   See above
+*/
+int2 norm_l( int4 L_var1 )
+{
+  int2 cntr = 0;
+
+  /* Special case when L_var1 == -2147483648: shift leads to underflow */
+  if ( L_var1 == MININT4 )
+    return 0;
+  /* Special case when L_var1 == 0: shift does not change the value */
+  else if ( L_var1 == 0 )
+    return 0;
+  else {
+    if ( L_var1 < 0 ) {
+      for ( ; L_var1 >= (int4) -1073741824L; L_var1 *= 2 )
+	cntr++;
+    }
+    else {
+      for ( ; L_var1 < (int4) 1073741824L; L_var1 <<= 1 )
+	cntr++;
+    }
+
+    return cntr;
+  }
+}
+
+
+/*
+** int2 div_s( int2 num, int2 denum )
+**
+** Function produces a result which is the fractional integer division
+** of var1 by var2; var1 and var2 must be positive and var2 must be
+** greater or equal to var1; The result is positive (leading bit equal
+** to 0) and truncated to 16 bits. If var1 == var2 then
+**   div_s( var1, var2 ) = 32767
+**
+** Input:
+**   L_var1
+**     32-bit variable which normalization factor is solved
+**
+** Output:
+**   16-bit result, see description above
+**  
+** Return value:
+**   See above
+*/
+int2 div_s( int2 num, int2 denum )
+{
+  if ( num == denum )
+    return MAXINT2;
+  else
+    return (int2) ( ( ( (int4) num ) << 15 ) / denum );
+}
+
+
+/*
+** int2 shl( int2 var1, int2 var2 )
+**
+** Function makes arithmetic var2-bit shift left of var1. If var2 is
+** less than 0, this operation becomes arithmetic right shift of -var2
+**
+** Input:
+**   var1
+**     16-bit variable to be shifted
+**   var2
+**     amount of bits to be shifted
+**
+** Output:
+**   16-bit value of shifted var1 is retuned 
+**  
+** Return value:
+**   See above
+**
+** Notes:
+**   ANSI C does not guarantee that right shift is arithmetical
+**   (that sign extension is done during shifting). That is why in this
+**   routine negative values are complemented before shifting.
+*/
+int2 shl( int2 var1, int2 var2 )
+{
+  int2 result;
+
+  if ( ( var1 == 0 ) || ( var2 == 0 ) ) {
+    result = var1;
+  }
+  
+  /* var2 > 0: Perform left shift */
+  else if ( var2 > 0 ) {
+    if ( var2 >= 15 ) {
+      result = ( var1 < 0 ) ? int2(MININT2) : int2(MAXINT2);
+    }
+    else {
+
+      int4 L_temp;
+      
+      L_temp = (int4) var1 << var2;
+      if ( L_temp < MININT2 ) {
+	result = MININT2;
+      }
+      else if ( L_temp > MAXINT2 ) {
+	result = MAXINT2;
+      }
+      else {
+	result = (int2) L_temp;
+      }
+    }
+  }
+  /* var2 < 0: Perform right shift */
+  else {
+    if ( -var2 >= 15 ) {
+      result = ( var1 < 0 ) ? int2 (-1) : int2 (0);
+    }
+    else if ( var1 < 0 ) {
+      result = int2 (~( (~var1) >> -var2 )); /* ~ used to ensure arith. shift */
+    }
+    else {
+      result = int2 (var1 >> -var2);
+    }
+  }
+
+  return result;
+  
+}
+
+
+/*
+** int4 L_shl( int4 L_var1, int2 var2 )
+**
+** Function makes arithmetic var2-bit shift left of var1. If var2 is
+** less than 0, this operation becomes arithmetic right shift of -var2
+**
+** Input:
+**   L_var1
+**     32-bit variable to be shifted
+**   var2
+**     amount of bits to be shifted
+**
+** Output:
+**   32-bit value of shifted var1 is retuned 
+**  
+** Return value:
+**   See above
+**
+** Notes:
+**   ANSI C does not guarantee that right shift is arithmetical
+**   (that sign extension is done during shifting). That is why in this
+**   routine negative values are complemented before shifting.
+*/
+
+int4 L_shl(int4 L_var1, int2 var2 )
+{
+  if ( ( L_var1 == 0L ) || ( var2 == 0 ) ) {
+    return L_var1;
+  }
+  /* var2 > 0: Perform left shift */
+  else if ( var2 > 0 ) {
+    if ( var2 >= 31 ) {
+      return ( L_var1 < 0 ) ? MININT4 : MAXINT4;
+    }
+    else {
+      for( ; var2 > 0; var2-- ) {
+	if ( L_var1 > (MAXINT4 >> 1) )
+	  return MAXINT4;
+	else if ( L_var1 < (MININT4 / 2) )
+	  return MININT4;
+	else
+	  L_var1 *= 2;
+      }
+      return L_var1;
+    }
+  }
+  /* var2 < 0: Perform right shift */
+  else {
+    if ( -var2 >= 31 ) {
+      return ( L_var1 < 0 ) ? -1L : 0L;
+    }
+    else if ( L_var1 < 0 ) {
+      return ~( (~L_var1) >> -var2 ); /* ~ used to ensure arith. shift */
+    }
+    else {
+      return L_var1 >> -var2;
+    }
+  }
+
+}
+