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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
51extern "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     ----------------------------------------------------------------------------*/
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     ----------------------------------------------------------------------------*/
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
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
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
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
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
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
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     ----------------------------------------------------------------------------*/
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     ----------------------------------------------------------------------------*/
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
462    __inline int32 mul_32by16(int16 hi, int16 lo, int16 n)
463    {
464        return (((((int32)hi*n)) + ((((int32)lo*n) >> 15))) << 1);
465    }
466
467    __inline  int32 fxp_mac_16by16(int16 var1,  int16 var2, int32 L_add)
468    {
469
470        L_add += (int32)var1 * var2;
471
472        return L_add;
473    }
474
475    __inline  int32 fxp_mul_16by16(int16 var1, const int16 var2)
476    {
477        int32 L_mul = (int32)var1 * var2;
478
479        return L_mul;
480    }
481
482    __inline  int32 fxp_mul32_by_16b(int32 L_var1, const int32 L_var2)
483    {
484
485        int32 L_mul = (int32)(((int64)L_var1 * (L_var2 << 16)) >> 32);
486
487        return L_mul;
488    }
489
490
491#ifdef __cplusplus
492}
493#endif
494
495#endif
496
497#endif   /*  PVAMRWBDECODER_BASIC_OP_CEQUIVALENT_H  */
498
499