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.173
22     ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23     Available from http://www.3gpp.org
24 
25 (C) 2007, 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 
32 
33 
34  Pathname: ./src/pvamrwbdecoder_basic_op_cequivalent.h
35 
36      Date: 05/07/2007
37 
38 ------------------------------------------------------------------------------
39  REVISION HISTORY
40 
41  Description:
42 ------------------------------------------------------------------------------
43  INCLUDE DESCRIPTION
44 
45 ------------------------------------------------------------------------------
46 */
47 #ifndef PVAMRWBDECODER_BASIC_OP_CEQUIVALENT_H
48 #define PVAMRWBDECODER_BASIC_OP_CEQUIVALENT_H
49 
50 #ifdef __cplusplus
51 extern "C"
52 {
53 #endif
54 
55 
56 #include "normalize_amr_wb.h"
57 
58 #if defined(C_EQUIVALENT)
59 
60 
61     /*----------------------------------------------------------------------------
62 
63          Function Name : add_int16
64 
65          Purpose :
66 
67           Performs the addition (var1+var2) with overflow control and saturation;
68           the 16 bit result is set at +32767 when overflow occurs or at -32768
69           when underflow occurs.
70 
71          Inputs :
72           var1
73                    16 bit short signed integer (int16) whose value falls in the
74                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
75 
76           var2
77                    16 bit short signed integer (int16) whose value falls in the
78                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
79 
80          Outputs :
81           none
82 
83          Return Value :
84                    16 bit short signed integer (int16) whose value falls in the
85                    range : 0xffff 8000 <= var_out <= 0x0000 7fff.
86 
87      ----------------------------------------------------------------------------*/
add_int16(int16 var1,int16 var2)88     __inline int16 add_int16(int16 var1, int16 var2)
89     {
90         int32 L_sum;
91 
92         L_sum = (int32) var1 + var2;
93         if ((L_sum >> 15) != (L_sum >> 31))
94         {
95             L_sum = (L_sum >> 31) ^ MAX_16;
96         }
97         return ((int16)(L_sum));
98     }
99 
100 
101     /*----------------------------------------------------------------------------
102 
103          Function Name : sub_int16
104 
105           Performs the subtraction (var1+var2) with overflow control and satu-
106           ration; the 16 bit result is set at +32767 when overflow occurs or at
107           -32768 when underflow occurs.
108 
109          Inputs :
110 
111           var1
112                    16 bit short signed integer (int16) whose value falls in the
113                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
114 
115           var2
116                    16 bit short signed integer (int16) whose value falls in the
117                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
118 
119          Outputs :
120           none
121 
122          Return Value :
123                    16 bit short signed integer (int16) whose value falls in the
124                    range : 0xffff 8000 <= var_out <= 0x0000 7fff.
125 
126      ----------------------------------------------------------------------------*/
sub_int16(int16 var1,int16 var2)127     __inline int16 sub_int16(int16 var1, int16 var2)
128     {
129         int32 L_diff;
130 
131         L_diff = (int32) var1 - var2;
132         if ((L_diff >> 15) != (L_diff >> 31))
133         {
134             L_diff = (L_diff >> 31) ^ MAX_16;
135         }
136         return ((int16)(L_diff));
137     }
138 
139 
140     /*----------------------------------------------------------------------------
141 
142          Function Name : mult_int16
143 
144           Performs the multiplication of var1 by var2 and gives a 16 bit result
145           which is scaled i.e.:
146                    mult_int16(var1,var2) = extract_l(L_shr((var1 times var2),15)) and
147                    mult_int16(-32768,-32768) = 32767.
148 
149          Inputs :
150           var1
151                    16 bit short signed integer (int16) whose value falls in the
152                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
153 
154           var2
155                    16 bit short signed integer (int16) whose value falls in the
156                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
157 
158 
159          Return Value :
160                    16 bit short signed integer (int16) whose value falls in the
161                    range : 0xffff 8000 <= var_out <= 0x0000 7fff.
162 
163      ----------------------------------------------------------------------------*/
164 
mult_int16(int16 var1,int16 var2)165     __inline int16 mult_int16(int16 var1, int16 var2)
166     {
167         int32 L_product;
168 
169         L_product = ((int32) var1 * (int32) var2) >> 15;
170 
171         if ((L_product >> 15) != (L_product >> 31))
172         {
173             L_product = (L_product >> 31) ^ MAX_16;
174         }
175 
176         return ((int16)L_product);
177     }
178 
179 
180     /*----------------------------------------------------------------------------
181 
182          Function Name : add_int32
183 
184          32 bits addition of the two 32 bits variables (L_var1+L_var2) with
185          overflow control and saturation; the result is set at +2147483647 when
186          overflow occurs or at -2147483648 when underflow occurs.
187 
188          Inputs :
189 
190           L_var1   32 bit long signed integer (int32) whose value falls in the
191                    range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
192 
193           L_var2   32 bit long signed integer (int32) whose value falls in the
194                    range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
195 
196 
197          Return Value :
198           L_var_out
199                    32 bit long signed integer (int32) whose value falls in the
200                    range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
201 
202      ----------------------------------------------------------------------------*/
203 
204 
add_int32(int32 L_var1,int32 L_var2)205     __inline  int32 add_int32(int32 L_var1, int32 L_var2)
206     {
207         int32 L_var_out;
208 
209         //L_var_out = L_var1 + L_var2;
210         if (L_var2 < 0) {
211             if (L_var1 < MIN_32 - L_var2) {
212                 return MIN_32;
213             }
214         } else {
215             if (L_var1 > MAX_32 - L_var2) {
216                 return MAX_32;
217             }
218         }
219 
220         return L_var1 + L_var2;
221     }
222 
223 
224 
225 
226     /*----------------------------------------------------------------------------
227 
228          Function Name : sub_int32
229 
230          32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with
231          overflow control and saturation; the result is set at +2147483647 when
232          overflow occurs or at -2147483648 when underflow occurs.
233 
234          Inputs :
235 
236           L_var1   32 bit long signed integer (int32) whose value falls in the
237                    range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
238 
239           L_var2   32 bit long signed integer (int32) whose value falls in the
240                    range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
241 
242 
243          Return Value :
244           L_var_out
245                    32 bit long signed integer (int32) whose value falls in the
246                    range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
247 
248      ----------------------------------------------------------------------------*/
249 
250 
sub_int32(int32 L_var1,int32 L_var2)251     __inline  int32 sub_int32(int32 L_var1, int32 L_var2)
252     {
253         //L_var_out = L_var1 - L_var2;
254         if (L_var2 < 0) {
255             if (L_var1 > MAX_32 + L_var2) {
256                 return  MAX_32;
257             }
258         } else {
259             if (L_var1 < MIN_32 + L_var2) {
260                 return MIN_32;
261             }
262         }
263 
264         return L_var1 - L_var2;
265     }
266 
267 
268 
269     /*----------------------------------------------------------------------------
270 
271          Function Name : mul_16by16_to_int32
272 
273          mul_16by16_to_int32 is the 32 bit result of the multiplication of var1
274          times var2 with one shift left i.e.:
275               L_mult(var1,var2) = L_shl((var1 times var2),1) and
276               L_mult(-32768,-32768) = 2147483647.
277 
278          Inputs :
279           var1
280                    16 bit short signed integer (int16) whose value falls in the
281                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
282 
283           var2
284                    16 bit short signed integer (int16) whose value falls in the
285                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
286 
287          Return Value :
288                    32 bit long signed integer (int32) whose value falls in the
289                    range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
290 
291      ----------------------------------------------------------------------------*/
292 
293 
mul_16by16_to_int32(int16 var1,int16 var2)294     __inline  int32 mul_16by16_to_int32(int16 var1, int16 var2)
295     {
296         int32 L_mul;
297 
298         L_mul  = ((int32) var1 * (int32) var2);
299 
300         if (L_mul != 0x40000000)
301         {
302             L_mul <<= 1;
303         }
304         else
305         {
306             L_mul = MAX_32;     /* saturation */
307         }
308 
309         return (L_mul);
310 
311     }
312 
313     /*----------------------------------------------------------------------------
314 
315          Function Name : mac_16by16_to_int32
316 
317          Multiply var1 by var2 and shift the result left by 1. Add the 32 bit
318          result to L_var3 with saturation, return a 32 bit result:
319               L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).
320 
321          Inputs :
322 
323           L_var3   32 bit long signed integer (int32) whose value falls in the
324                    range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
325 
326           var1
327                    16 bit short signed integer (int16) whose value falls in the
328                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
329 
330           var2
331                    16 bit short signed integer (int16) whose value falls in the
332                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
333 
334 
335          Return Value :
336                    32 bit long signed integer (int32) whose value falls in the
337                    range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
338 
339      ----------------------------------------------------------------------------*/
340 
341 
mac_16by16_to_int32(int32 L_var3,int16 var1,int16 var2)342     __inline  int32 mac_16by16_to_int32(int32 L_var3, int16 var1, int16 var2)
343     {
344         return add_int32(L_var3, mul_16by16_to_int32(var1, var2));
345     }
346 
347 
348     /*----------------------------------------------------------------------------
349 
350          Function Name : msu_16by16_from_int32
351 
352          Multiply var1 by var2 and shift the result left by 1. Subtract the 32 bit
353          result to L_var3 with saturation, return a 32 bit result:
354               L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).
355 
356          Inputs :
357 
358           L_var3   32 bit long signed integer (int32) whose value falls in the
359                    range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
360 
361           var1
362                    16 bit short signed integer (int16) whose value falls in the
363                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
364 
365           var2
366                    16 bit short signed integer (int16) whose value falls in the
367                    range : 0xffff 8000 <= var1 <= 0x0000 7fff.
368 
369 
370          Return Value :
371                    32 bit long signed integer (int32) whose value falls in the
372                    range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
373 
374      ----------------------------------------------------------------------------*/
375 
msu_16by16_from_int32(int32 L_var3,int16 var1,int16 var2)376     __inline  int32 msu_16by16_from_int32(int32 L_var3, int16 var1, int16 var2)
377     {
378         return sub_int32(L_var3, mul_16by16_to_int32(var1, var2));
379     }
380 
381 
382     /*----------------------------------------------------------------------------
383 
384          Function Name : amr_wb_round
385 
386          Round the lower 16 bits of the 32 bit input number into the MS 16 bits
387          with saturation. Shift the resulting bits right by 16 and return the 16
388          bit number:
389                      round(L_var1) = extract_h(L_add(L_var1,32768))
390 
391          Inputs :
392           L_var1
393                    32 bit long signed integer (int32 ) whose value falls in the
394                    range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
395 
396          Return Value :
397                    16 bit short signed integer (int16) whose value falls in the
398                    range : 0xffff 8000 <= var_out <= 0x0000 7fff.
399 
400      ----------------------------------------------------------------------------*/
amr_wb_round(int32 L_var1)401     __inline int16 amr_wb_round(int32 L_var1)
402     {
403         if (L_var1 <= (MAX_32 - 0x00008000L))
404         {
405             L_var1 +=  0x00008000L;
406         }
407         return ((int16)(L_var1 >> 16));
408     }
409 
410 
411     /*----------------------------------------------------------------------------
412 
413          Function Name : amr_wb_shl1_round
414 
415          Shift the 32 bit input number to the left by 1, round up the result and
416          shift down by 16
417                      amr_wb_shl1_round(L_var1) = round(L_shl(L_var1,1))
418 
419          Inputs :
420           L_var1
421                    32 bit long signed integer (int32 ) whose value falls in the
422                    range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
423 
424          Return Value :
425                    16 bit short signed integer (int16) whose value falls in the
426                    range : 0xffff 8000 <= var_out <= 0x0000 7fff.
427 
428      ----------------------------------------------------------------------------*/
amr_wb_shl1_round(int32 L_var1)429     __inline int16 amr_wb_shl1_round(int32 L_var1)
430     {
431         int16 var_out;
432 
433         if ((L_var1 << 1) >> 1 == L_var1)
434         {
435             var_out = (int16)((L_var1 + 0x00004000) >> 15);
436         }
437         else
438         {
439             var_out = (int16)(((L_var1 >> 31) ^ MAX_32) >> 16);
440         }
441 
442         return (var_out);
443     }
444 
445     /*----------------------------------------------------------------------------
446              Function Name : mul_32by16
447 
448              Multiply a 16 bit integer by a 32 bit (DPF). The result is divided
449              by 2^15
450 
451                     L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1
452 
453              Inputs :
454 
455              hi          hi part of 32 bit number.
456              lo          lo part of 32 bit number.
457              n           16 bit number.
458 
459          ----------------------------------------------------------------------------*/
460 
461 
mul_32by16(int16 hi,int16 lo,int16 n)462     __inline int32 mul_32by16(int16 hi, int16 lo, int16 n)
463     {
464         return (((((int32)hi*n)) + ((((int32)lo*n) >> 15))) << 1);
465     }
466 
fxp_mac_16by16(int16 var1,int16 var2,int32 L_add)467     __inline  int32 fxp_mac_16by16(int16 var1,  int16 var2, int32 L_add)
468     {
469 
470         int32 l_orig = L_add;
471         if (__builtin_add_overflow( (int32)var1 * var2, l_orig, &L_add)) {
472             // needs saturation
473             if (l_orig > 0) L_add = MAX_32;
474             else            L_add = MIN_32;
475         }
476 
477         return L_add;
478     }
479 
fxp_mul_16by16(int16 var1,const int16 var2)480     __inline  int32 fxp_mul_16by16(int16 var1, const int16 var2)
481     {
482         int32 L_mul = (int32)var1 * var2;
483 
484         return L_mul;
485     }
486 
fxp_mul32_by_16b(int32 L_var1,const int32 L_var2)487     __inline  int32 fxp_mul32_by_16b(int32 L_var1, const int32 L_var2)
488     {
489 
490         int32 L_mul = (int32)(((int64)L_var1 * (L_var2 << 16)) >> 32);
491 
492         return L_mul;
493     }
494 
495 
496 #ifdef __cplusplus
497 }
498 #endif
499 
500 #endif
501 
502 #endif   /*  PVAMRWBDECODER_BASIC_OP_CEQUIVALENT_H  */
503 
504