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