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

📄 enh40.c

📁 Reference Implementation of G.711 standard and other voice codecs
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
  ===========================================================================
   File: ENH40.C                                         v.2.0 - 15.Nov.2004
  ===========================================================================

            ITU-T  STL  BASIC OPERATORS

            40-BIT ARITHMETIC OPERATORS

   History:
   07 Nov 04   v2.0     Incorporation of new 32-bit / 40-bit / control
                        operators for the ITU-T Standard Tool Library as 
                        described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
                        TD 11 document and subsequent discussions on the
                        wp3audio@yahoogroups.com email reflector.

  ============================================================================
*/


/*****************************************************************************
 *
 *  Enhanced 40 bit operators :
 *
 *    L40_add()
 *    L40_sub()
 *    L40_abs()
 *    L40_negate()
 *    L40_max()
 *    L40_min()
 *    L40_shr()
 *    L40_shr_r()
 *    L40_shl()
 *    L40_shl_r()
 *    norm_L40()
 *    L40_mult()
 *    L40_mac()
 *    L40_msu()
 *    mac_r40()
 *    msu_r40()
 *    Mpy_32_16_ss()
 *    Mpy_32_32_ss()
 *    L40_lshl()
 *    L40_lshr()
 *    L40_round()
 *    L_saturate40()
 *    L40_set() 
 *    Extract40_H()
 *    Extract40_L()
 *    L_Extract40()
 *    L40_deposit_h()
 *    L40_deposit_l()
 *    L40_deposit32()
 *
 *****************************************************************************/


/*****************************************************************************
 *
 *  Include-Files
 *
 *****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "stl.h"

#if (WMOPS)
extern BASIC_OP multiCounter[MAXCOUNTERS];
extern int currCounter;
#endif /* ifdef WMOPS */


/*****************************************************************************
 *
 *  Local Functions
 *
 *****************************************************************************/


/*****************************************************************************
 *
 *  Constants and Globals
 *
 *****************************************************************************/


/*****************************************************************************
 *
 *  Functions
 *
 *****************************************************************************/

/*****************************************************************************
 *
 *  Function Name : L40_shl
 *
 *  Purpose :
 *
 *    Arithmetically shifts left L40_var1 by var2 positions.
 *    - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2)
 *      positions with extension of the sign bit.
 *    - If var2 is positive, L40_var1 is shifted to the MSBits by (var2)
 *      positions.
 *    Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
 *    Calls the macro L40_OVERFLOW_OCCURED()  in case of overflow  on 40-bit.
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *    var2        16 bit short signed integer (Word16) whose value falls in
 *                the range : MIN_16 <= var2 <= MAX_16.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : MIN_40 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_shl( Word40 L40_var1, Word16 var2) {

   Word40 L40_var_out;
	Word40 L40_constant = L40_set( 0xc000000000);

   if( var2 < 0) {
      var2 = -var2;
      L40_var_out = L40_shr( L40_var1, var2);

      #if (WMOPS)
      multiCounter[currCounter].L40_shr--;
      #endif /* ifdef WMOPS */
   }

    else {
      L40_var_out = L40_var1;

      for ( ; var2 > 0; var2--) {
         if( L40_var_out > 0x003fffffffff) {
            L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out);
            break;
         }

         else if ( L40_var_out < L40_constant) {
            L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out);
            break;
         }

         else {
            L40_var_out = L40_var_out << 1;
         }
      }
   }

   #if (WMOPS)
   multiCounter[currCounter].L40_set--;
   multiCounter[currCounter].L40_shl++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L40_shr
 *
 *  Purpose :
 *
 *    Arithmetically shifts right L40_var1 by var2 positions.
 *    - If var2 is positive, L40_var1 is shifted to the LSBits by (var2)
 *      positions with extension of the sign bit.
 *    - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2)
 *      positions.
 *    Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
 *    Calls the macro L40_OVERFLOW_OCCURED()  in case of overflow  on 40-bit.
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *    var2        16 bit short signed integer (Word16) whose value falls in
 *                the range : MIN_16 <= var2 <= MAX_16.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : MIN_40 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_shr( Word40 L40_var1, Word16 var2) {
   Word40 L40_var_out;

   if( var2 < 0) {
      var2 = -var2;
      L40_var_out  = L40_shl ( L40_var1, var2);

      #if (WMOPS)
      multiCounter[currCounter].L40_shl--;
      #endif /* ifdef WMOPS */

   } else {
      L40_var_out = L40_var1 >> var2;
   }

   #if (WMOPS)
   multiCounter[currCounter].L40_shr++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L40_negate
 *
 *  Purpose :
 *
 *    Negates L40_var1.
 *    Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
 *    Calls the macro L40_OVERFLOW_OCCURED()  in case of overflow  on 40-bit.
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : MIN_40 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_negate( Word40 L40_var1) {
   Word40 L40_var_out;

   L40_var_out = L40_add( ~L40_var1, 0x01);

   #if (WMOPS)
   multiCounter[currCounter].L40_add--;
   multiCounter[currCounter].L40_negate++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L40_add
 *
 *  Purpose :
 *
 *    Adds L40_var1 and L40_var2 and returns the 40-bit result.
 *    Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
 *    Calls the macro L40_OVERFLOW_OCCURED()  in case of overflow  on 40-bit.
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *    L40_var2    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var2 <= MAX_40.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : MIN_40 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_add( Word40 L40_var1, Word40 L40_var2) {
   Word40 L40_var_out;

   L40_var_out = L40_var1 + L40_var2;

   if(  ((( L40_var1    & 0x8000000000) >> 39) != 0)
     && ((( L40_var2    & 0x8000000000) >> 39) != 0)
     && ((( L40_var_out & 0x8000000000) >> 39) == 0)) {
      L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out);

   } else if( (((L40_var1    & 0x8000000000) >> 39) == 0)
           && (((L40_var2    & 0x8000000000) >> 39) == 0)
           && (((L40_var_out & 0x8000000000) >> 39) != 0)) {
      L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out);
   }

   #if (WMOPS)
   multiCounter[currCounter].L40_add++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L40_sub
 *
 *  Purpose :
 *
 *    Subtracts L40_var2 from L40_var1.
 *    Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
 *    Calls the macro L40_OVERFLOW_OCCURED()  in case of overflow  on 40-bit.
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *    L40_var2    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var2 <= MAX_40.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : MIN_40 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_sub( Word40 L40_var1, Word40 L40_var2) {
   Word40 L40_var_out;

   L40_var_out = L40_var1 - L40_var2;

   if( (((L40_var1    & 0x8000000000) >> 39) != 0)
    && (((L40_var2    & 0x8000000000) >> 39) == 0)
    && (((L40_var_out & 0x8000000000) >> 39) == 0)) {
      L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out);

   } else if( (((L40_var1    & 0x8000000000) >> 39) == 0)
           && (((L40_var2    & 0x8000000000) >> 39) != 0)
           && (((L40_var_out & 0x8000000000) >> 39) != 0)) {
      L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out);
   }
   #if (WMOPS)
    multiCounter[currCounter].L40_sub++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L40_abs
 *
 *  Purpose :
 *
 *    Returns the absolute value of L40_var1.
 *    Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
 *    Calls the macro L40_OVERFLOW_OCCURED()  in case of overflow  on 40-bit.
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : 0x00 0000 0000 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_abs( Word40 L40_var1) {
   Word40 L40_var_out;

   if( L40_var1 < 0) {
      L40_var_out = L40_negate ( L40_var1);

      #if (WMOPS)
      multiCounter[currCounter].L40_negate--;
      #endif /* ifdef WMOPS */

   } else {
      L40_var_out = L40_var1;
   }

   #if (WMOPS)
   multiCounter[currCounter].L40_abs++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L40_max
 *
 *  Purpose :
 *
 *    Compares L40_var1 and L40_var2 and returns the maximum value.
 *
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *    L40_var2    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var2 <= MAX_40.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : MIN_40 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_max( Word40 L40_var1, Word40 L40_var2) {
   Word40 L40_var_out;

   if( L40_var1 < L40_var2)
      L40_var_out = L40_var2;
   else
      L40_var_out = L40_var1;

   #if (WMOPS)
   multiCounter[currCounter].L40_max++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L40_min
 *
 *  Purpose :
 *
 *    Compares L40_var1 and L40_var2 and returns the minimum value.
 *
 *
 *  Complexity weight : 1
 *
 *  Inputs :
 *
 *    L40_var1    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var1 <= MAX_40.
 *
 *    L40_var2    40 bit long signed integer (Word40) whose value falls in the
 *                range : MIN_40 <= L40_var2 <= MAX_40.
 *
 *  Outputs :
 *
 *    none
 *
 *  Return Value :
 *
 *    L40_var_out 40 bit long signed integer (Word40) whose value falls in
 *                the range : MIN_40 <= L40_var_out <= MAX_40.
 *
 *****************************************************************************/
Word40 L40_min( Word40 L40_var1, Word40 L40_var2) {
   Word40 L40_var_out;

   if( L40_var1 < L40_var2)
      L40_var_out = L40_var1;
   else
      L40_var_out = L40_var2;

   #if (WMOPS)
   multiCounter[currCounter].L40_min++;
   #endif /* ifdef WMOPS */

   return( L40_var_out);
}


/*****************************************************************************
 *
 *  Function Name : L_saturate40
 *
 *  Purpose :
 *
 *    If L40_var1 is greater than MAX_32, returns MAX_32.
 *    If L40_var1 is lower   than MIN_32, returns MIN_32.
 *    If not,                             returns L_Extract40( L40_var1).
 *
 *  Complexity weight : 1

⌨️ 快捷键说明

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