Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / common / src / mult_r.cpp
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: mult_r.cpp
32
33 ------------------------------------------------------------------------------
34  MODULE DESCRIPTION
35
36  Multiplication function with rounding and overflow control
37
38 ------------------------------------------------------------------------------
39 */
40
41 /*----------------------------------------------------------------------------
42 ; INCLUDES
43 ----------------------------------------------------------------------------*/
44 #include    "basic_op.h"
45
46 /*----------------------------------------------------------------------------
47 ; MACROS
48 ; [Define module specific macros here]
49 ----------------------------------------------------------------------------*/
50
51 /*----------------------------------------------------------------------------
52 ; DEFINES
53 ; [Include all pre-processor statements here. Include conditional
54 ; compile variables also.]
55 ----------------------------------------------------------------------------*/
56
57 /*----------------------------------------------------------------------------
58 ; LOCAL FUNCTION DEFINITIONS
59 ; [List function prototypes here]
60 ----------------------------------------------------------------------------*/
61
62 /*----------------------------------------------------------------------------
63 ; LOCAL VARIABLE DEFINITIONS
64 ; [Variable declaration - defined here and used outside this module]
65 ----------------------------------------------------------------------------*/
66
67
68 /*
69 ------------------------------------------------------------------------------
70  FUNCTION NAME: mult_r
71 ------------------------------------------------------------------------------
72  INPUT AND OUTPUT DEFINITIONS
73
74  Inputs:
75     var1 = 16 bit short signed integer (Word16) whose value falls in
76            the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
77
78     var2 = 16 bit short signed integer (Word16) whose value falls in
79            the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
80
81     pOverflow = pointer to overflow (Flag)
82
83  Outputs:
84     pOverflow -> 1 if the add operation resulted in overflow
85
86  Returns:
87     L_product_arr = 16-bit limited product of var1 and var2 (Word16)
88
89  Global Variables Used:
90     None
91
92  Local Variables Needed:
93     None
94
95 ------------------------------------------------------------------------------
96  FUNCTION DESCRIPTION
97
98  This function performs the multiplication of var1 by var2 with rounding, and
99  gives a 16 bit result which is scaled, i.e.:
100     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
101     mult_r(-32768,-32768) = 32767
102
103 ------------------------------------------------------------------------------
104  REQUIREMENTS
105
106  None
107
108 ------------------------------------------------------------------------------
109  REFERENCES
110
111  [1] mult_r() function in basicop2.c, UMTS GSM AMR speech codec, R99 -
112  Version 3.2.0, March 2, 2001
113
114 ------------------------------------------------------------------------------
115  PSEUDO-CODE
116
117 Word16 mult_r (Word16 var1, Word16 var2)
118 {
119     Word16 var_out;
120     Word32 L_product_arr;
121
122     L_product_arr = (Word32) var1 *(Word32) var2;
123     L_product_arr += (Word32) 0x00004000L;
124     L_product_arr &= (Word32) 0xffff8000L;
125     L_product_arr >>= 15;
126
127     if (L_product_arr & (Word32) 0x00010000L)
128     {
129         L_product_arr |= (Word32) 0xffff0000L;
130     }
131 * The reference ETSI code uses a global flag for Overflow inside the function
132 * saturate(). In the actual implementation a pointer to Overflow flag is passed in
133 * as a parameter to the function
134
135     var_out = saturate (L_product_arr);
136
137 #if (WMOPS)
138     multiCounter[currCounter].mult_r++;
139 #endif
140
141     return (var_out);
142 }
143
144 ------------------------------------------------------------------------------
145  CAUTION [optional]
146  [State any special notes, constraints or cautions for users of this function]
147
148 ------------------------------------------------------------------------------
149 */
150
151 /*----------------------------------------------------------------------------
152 ; FUNCTION CODE
153 ----------------------------------------------------------------------------*/
154
155 OSCL_EXPORT_REF Word16 mult_r(Word16 var1, Word16 var2, Flag *pOverflow)
156 {
157
158     register Word32 L_product_arr;
159
160     L_product_arr = ((Word32) var1) * var2;              /* product */
161     L_product_arr += (Word32) 0x00004000L;               /* round */
162     L_product_arr >>= 15;                                /* shift */
163
164     /* sign extend when necessary */
165     L_product_arr |= (Word32) - (L_product_arr & (Word32) 0x00010000L);
166
167     /* Saturate result (if necessary). */
168     /* Replaced function call with in-line code to conserve MIPS, */
169     /* i.e., var_out = saturate (L_product_arr)  */
170
171     if (L_product_arr > 0X00007fffL)
172     {
173         *pOverflow = 1;
174         L_product_arr = MAX_16;
175     }
176     else if (L_product_arr < (Word32) - 32768)
177     {
178         *pOverflow = 1;
179         L_product_arr = MIN_16;
180     }
181
182     return ((Word16) L_product_arr);
183 }