Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /****************************************************************************************
     19 Portions of this file are derived from the following 3GPP standard:
     20 
     21     3GPP TS 26.073
     22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
     23     Available from http://www.3gpp.org
     24 
     25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
     26 Permission to distribute, modify and use this file under the standard license
     27 terms listed above has been obtained from the copyright holder.
     28 ****************************************************************************************/
     29 /*
     30 
     31  Filename: /audio/gsm_amr/c/src/mult_r.c
     32 
     33 ------------------------------------------------------------------------------
     34  REVISION HISTORY
     35 
     36  Description: Created separate file for the mult_r function. Sync'ed up
     37           with the current template and fixed tabs.
     38 
     39  Description: Passing in a pointer to the overflow flag instead of using
     40           a global flag.
     41 
     42  Description: Made the following changes based on P2/P3 review:
     43               1) Simplified test to determine if sign extension is necessary
     44               2) Changed the name of pointer "overflow" to "Poverflow"
     45               3) Removed code that updates MOPS counter
     46               4) Updated template and reference section
     47 
     48  Who:                       Date:
     49  Description:
     50 
     51 
     52 ------------------------------------------------------------------------------
     53  MODULE DESCRIPTION
     54 
     55  Multiplication function with rounding and overflow control
     56 
     57 ------------------------------------------------------------------------------
     58 */
     59 
     60 /*----------------------------------------------------------------------------
     61 ; INCLUDES
     62 ----------------------------------------------------------------------------*/
     63 #include    "basic_op.h"
     64 
     65 /*----------------------------------------------------------------------------
     66 ; MACROS
     67 ; [Define module specific macros here]
     68 ----------------------------------------------------------------------------*/
     69 
     70 /*----------------------------------------------------------------------------
     71 ; DEFINES
     72 ; [Include all pre-processor statements here. Include conditional
     73 ; compile variables also.]
     74 ----------------------------------------------------------------------------*/
     75 
     76 /*----------------------------------------------------------------------------
     77 ; LOCAL FUNCTION DEFINITIONS
     78 ; [List function prototypes here]
     79 ----------------------------------------------------------------------------*/
     80 
     81 /*----------------------------------------------------------------------------
     82 ; LOCAL VARIABLE DEFINITIONS
     83 ; [Variable declaration - defined here and used outside this module]
     84 ----------------------------------------------------------------------------*/
     85 
     86 
     87 /*
     88 ------------------------------------------------------------------------------
     89  FUNCTION NAME: mult_r
     90 ------------------------------------------------------------------------------
     91  INPUT AND OUTPUT DEFINITIONS
     92 
     93  Inputs:
     94     var1 = 16 bit short signed integer (Word16) whose value falls in
     95            the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
     96 
     97     var2 = 16 bit short signed integer (Word16) whose value falls in
     98            the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
     99 
    100     pOverflow = pointer to overflow (Flag)
    101 
    102  Outputs:
    103     pOverflow -> 1 if the add operation resulted in overflow
    104 
    105  Returns:
    106     L_product_arr = 16-bit limited product of var1 and var2 (Word16)
    107 
    108  Global Variables Used:
    109     None
    110 
    111  Local Variables Needed:
    112     None
    113 
    114 ------------------------------------------------------------------------------
    115  FUNCTION DESCRIPTION
    116 
    117  This function performs the multiplication of var1 by var2 with rounding, and
    118  gives a 16 bit result which is scaled, i.e.:
    119     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
    120     mult_r(-32768,-32768) = 32767
    121 
    122 ------------------------------------------------------------------------------
    123  REQUIREMENTS
    124 
    125  None
    126 
    127 ------------------------------------------------------------------------------
    128  REFERENCES
    129 
    130  [1] mult_r() function in basicop2.c, UMTS GSM AMR speech codec, R99 -
    131  Version 3.2.0, March 2, 2001
    132 
    133 ------------------------------------------------------------------------------
    134  PSEUDO-CODE
    135 
    136 Word16 mult_r (Word16 var1, Word16 var2)
    137 {
    138     Word16 var_out;
    139     Word32 L_product_arr;
    140 
    141     L_product_arr = (Word32) var1 *(Word32) var2;
    142     L_product_arr += (Word32) 0x00004000L;
    143     L_product_arr &= (Word32) 0xffff8000L;
    144     L_product_arr >>= 15;
    145 
    146     if (L_product_arr & (Word32) 0x00010000L)
    147     {
    148         L_product_arr |= (Word32) 0xffff0000L;
    149     }
    150 * The reference ETSI code uses a global flag for Overflow inside the function
    151 * saturate(). In the actual implementation a pointer to Overflow flag is passed in
    152 * as a parameter to the function
    153 
    154     var_out = saturate (L_product_arr);
    155 
    156 #if (WMOPS)
    157     multiCounter[currCounter].mult_r++;
    158 #endif
    159 
    160     return (var_out);
    161 }
    162 
    163 ------------------------------------------------------------------------------
    164  RESOURCES USED [optional]
    165 
    166  When the code is written for a specific target processor the
    167  the resources used should be documented below.
    168 
    169  HEAP MEMORY USED: x bytes
    170 
    171  STACK MEMORY USED: x bytes
    172 
    173  CLOCK CYCLES: (cycle count equation for this function) + (variable
    174                 used to represent cycle count for each subroutine
    175                 called)
    176      where: (cycle count variable) = cycle count for [subroutine
    177                                      name]
    178 
    179 ------------------------------------------------------------------------------
    180  CAUTION [optional]
    181  [State any special notes, constraints or cautions for users of this function]
    182 
    183 ------------------------------------------------------------------------------
    184 */
    185 
    186 /*----------------------------------------------------------------------------
    187 ; FUNCTION CODE
    188 ----------------------------------------------------------------------------*/
    189 
    190 Word16 mult_r(Word16 var1, Word16 var2, Flag *pOverflow)
    191 {
    192 
    193     Word32 L_product_arr;
    194 
    195     L_product_arr = ((Word32) var1) * var2;              /* product */
    196     L_product_arr += (Word32) 0x00004000L;               /* round */
    197     L_product_arr >>= 15;                                /* shift */
    198 
    199     /* sign extend when necessary */
    200     L_product_arr |= (Word32) - (L_product_arr & (Word32) 0x00010000L);
    201 
    202     /* Saturate result (if necessary). */
    203     /* Replaced function call with in-line code to conserve MIPS, */
    204     /* i.e., var_out = saturate (L_product_arr)  */
    205 
    206     if (L_product_arr > 0X00007fffL)
    207     {
    208         *pOverflow = 1;
    209         L_product_arr = MAX_16;
    210     }
    211     else if (L_product_arr < (Word32) 0xffff8000L)
    212     {
    213         *pOverflow = 1;
    214         L_product_arr = MIN_16;
    215     }
    216 
    217     return ((Word16) L_product_arr);
    218 }
    219