Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2  *                                                                            *
      3  * Copyright (C) 2018 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at:
      8  *
      9  * http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  *****************************************************************************
     18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
     19 */
     20 #ifndef IXHEAACD_BASIC_OPS16_H
     21 #define IXHEAACD_BASIC_OPS16_H
     22 
     23 static PLATFORM_INLINE WORD16 ixheaacd_sat16(WORD32 op1) {
     24   WORD16 var_out;
     25 
     26   if (op1 > 0X00007fffL) {
     27     var_out = MAX_16;
     28   } else if (op1 < (WORD32)0xffff8000L) {
     29     var_out = (WORD16)(-32768);
     30   } else {
     31     var_out = (WORD16)(op1);
     32   }
     33   return (var_out);
     34 }
     35 
     36 static PLATFORM_INLINE WORD16 ixheaacd_add16(WORD16 op1, WORD16 op2) {
     37   WORD16 var_out;
     38 
     39   var_out = ((WORD16)(op1 + op2));
     40   return (var_out);
     41 }
     42 
     43 static PLATFORM_INLINE WORD16 ixheaacd_add16_sat(WORD16 op1, WORD16 op2) {
     44   WORD16 var_out;
     45   WORD32 sum;
     46 
     47   sum = (WORD32)op1 + (WORD32)op2;
     48   var_out = ixheaacd_sat16(sum);
     49   return (var_out);
     50 }
     51 
     52 static PLATFORM_INLINE WORD16 ixheaacd_sub16(WORD16 op1, WORD16 op2) {
     53   WORD16 var_out;
     54 
     55   var_out = ((WORD16)(op1 - op2));
     56   return (var_out);
     57 }
     58 
     59 static PLATFORM_INLINE WORD16 ixheaacd_sub16_sat(WORD16 op1, WORD16 op2) {
     60   WORD16 var_out;
     61   WORD32 diff;
     62 
     63   diff = (WORD32)op1 - op2;
     64   var_out = ixheaacd_sat16(diff);
     65   return (var_out);
     66 }
     67 
     68 static PLATFORM_INLINE WORD16 ixheaacd_mult16(WORD16 op1, WORD16 op2) {
     69   WORD16 var_out;
     70 
     71   var_out = ((WORD16)(((WORD32)op1 * (WORD32)op2) >> 16));
     72   return (var_out);
     73 }
     74 
     75 static PLATFORM_INLINE WORD16 ixheaacd_mult16_shl(WORD16 op1, WORD16 op2) {
     76   WORD16 var_out;
     77 
     78   var_out = ((WORD16)(((WORD32)op1 * (WORD32)op2) >> 15));
     79   return (var_out);
     80 }
     81 
     82 static PLATFORM_INLINE WORD16 ixheaacd_mult16_shl_sat(WORD16 op1, WORD16 op2) {
     83   WORD16 var_out;
     84   WORD32 temp;
     85 
     86   temp = ((WORD32)(((WORD32)op1 * (WORD32)op2) >> 15));
     87   var_out = ixheaacd_sat16(temp);
     88   return (var_out);
     89 }
     90 
     91 static PLATFORM_INLINE WORD16 ixheaacd_shl16(WORD16 op1, WORD16 shift) {
     92   WORD16 var_out;
     93 
     94   var_out = (WORD16)(op1 << shift);
     95   return (var_out);
     96 }
     97 
     98 static PLATFORM_INLINE WORD16 ixheaacd_shl16_sat(WORD16 op1, WORD16 shift) {
     99   WORD16 var_out;
    100   WORD32 temp;
    101 
    102   if (shift > 15) {
    103     shift = 15;
    104   }
    105   temp = (WORD32)(op1 << shift);
    106   var_out = ixheaacd_sat16(temp);
    107   return (var_out);
    108 }
    109 
    110 static PLATFORM_INLINE WORD16 ixheaacd_shr16(WORD16 op1, WORD16 shift) {
    111   WORD16 var_out;
    112 
    113   var_out = ((WORD16)(op1 >> shift));
    114   return (var_out);
    115 }
    116 
    117 static PLATFORM_INLINE WORD16 shl16_dir(WORD16 op1, WORD16 shift) {
    118   WORD16 var_out;
    119   if (shift > 0) {
    120     var_out = ixheaacd_shl16(op1, shift);
    121   } else {
    122     var_out = ixheaacd_shr16(op1, (WORD16)(-shift));
    123   }
    124   return (var_out);
    125 }
    126 
    127 static PLATFORM_INLINE WORD16 shr16_dir(WORD16 op1, WORD16 shift) {
    128   WORD16 var_out;
    129 
    130   if (shift < 0) {
    131     var_out = ixheaacd_shl16(op1, (WORD16)(-shift));
    132   } else {
    133     var_out = ixheaacd_shr16(op1, shift);
    134   }
    135   return (var_out);
    136 }
    137 
    138 static PLATFORM_INLINE WORD16 shl16_dir_sat(WORD16 op1, WORD16 shift) {
    139   WORD16 var_out;
    140   if (shift > 0) {
    141     var_out = ixheaacd_shl16_sat(op1, shift);
    142   } else {
    143     var_out = ixheaacd_shr16(op1, (WORD16)(-shift));
    144   }
    145   return (var_out);
    146 }
    147 
    148 static PLATFORM_INLINE WORD16 ixheaacd_shr16_dir_sat(WORD16 op1, WORD16 shift) {
    149   WORD16 var_out;
    150 
    151   if (shift < 0) {
    152     var_out = ixheaacd_shl16_sat(op1, (WORD16)(-shift));
    153   } else {
    154     var_out = ixheaacd_shr16(op1, shift);
    155   }
    156   return (var_out);
    157 }
    158 
    159 static PLATFORM_INLINE WORD16 norm16(WORD16 op1) {
    160   WORD16 var_out;
    161 
    162   if (0 == op1) {
    163     var_out = 0;
    164   } else {
    165     if ((WORD16)0xffff == op1) {
    166       var_out = 15;
    167     } else {
    168       if (op1 < 0) {
    169         op1 = (WORD16)(~op1);
    170       }
    171       for (var_out = 0; op1 < 0x4000; var_out++) {
    172         op1 <<= 1;
    173       }
    174     }
    175   }
    176 
    177   return (var_out);
    178 }
    179 
    180 static PLATFORM_INLINE WORD16 bin_expo16(WORD16 op1) {
    181   WORD16 var_out;
    182 
    183   var_out = ((WORD16)(15 - norm16(op1)));
    184   return (var_out);
    185 }
    186 
    187 static PLATFORM_INLINE WORD16 ixheaacd_abs16(WORD16 op1) {
    188   WORD16 var_out;
    189 
    190   if (op1 < 0) {
    191     var_out = (WORD16)(-op1);
    192   } else {
    193     var_out = op1;
    194   }
    195   return (var_out);
    196 }
    197 
    198 static PLATFORM_INLINE WORD16 ixheaacd_abs16_sat(WORD16 op1) {
    199   WORD16 var_out;
    200 
    201   if (-32768 == op1) {
    202     var_out = MAX_16;
    203   } else {
    204     if (op1 < 0) {
    205       var_out = (WORD16)(-op1);
    206     } else {
    207       var_out = op1;
    208     }
    209   }
    210   return (var_out);
    211 }
    212 
    213 static PLATFORM_INLINE WORD16 ixheaacd_negate16(WORD16 op1) {
    214   WORD16 var_out;
    215 
    216   if (-32768 == op1) {
    217     var_out = MAX_16;
    218   } else {
    219     var_out = (WORD16)(-op1);
    220   }
    221   return (var_out);
    222 }
    223 
    224 static PLATFORM_INLINE WORD16 ixheaacd_min16(WORD16 op1, WORD16 op2) {
    225   WORD16 var_out;
    226 
    227   var_out = op1 < op2 ? op1 : op2;
    228   return (var_out);
    229 }
    230 
    231 static PLATFORM_INLINE WORD16 ixheaacd_max16(WORD16 op1, WORD16 op2) {
    232   WORD16 var_out;
    233 
    234   var_out = op1 > op2 ? op1 : op2;
    235   return (var_out);
    236 }
    237 
    238 static PLATFORM_INLINE WORD16 div16(WORD16 op1, WORD16 op2, WORD16 *q_format) {
    239   WORD32 quotient;
    240   UWORD16 mantissa_nr, mantissa_dr;
    241   WORD16 sign = 0;
    242 
    243   LOOPIDX i;
    244   WORD16 q_nr, q_dr;
    245 
    246   mantissa_nr = op1;
    247   mantissa_dr = op2;
    248   quotient = 0;
    249 
    250   if (op1 < 0 && op2 != 0) {
    251     op1 = -op1;
    252     sign = (WORD16)(sign ^ -1);
    253   }
    254 
    255   if (op2 < 0) {
    256     op2 = -op2;
    257     sign = (WORD16)(sign ^ -1);
    258   }
    259 
    260   if (op2 == 0) {
    261     *q_format = 0;
    262     return (op1);
    263   }
    264 
    265   quotient = 0;
    266 
    267   q_nr = norm16(op1);
    268   mantissa_nr = (UWORD16)op1 << (q_nr);
    269   q_dr = norm16(op2);
    270   mantissa_dr = (UWORD16)op2 << (q_dr);
    271   *q_format = (WORD16)(14 + q_nr - q_dr);
    272 
    273   for (i = 0; i < 15; i++) {
    274     quotient = quotient << 1;
    275 
    276     if (mantissa_nr >= mantissa_dr) {
    277       mantissa_nr = mantissa_nr - mantissa_dr;
    278       quotient += 1;
    279     }
    280 
    281     mantissa_nr = (UWORD32)mantissa_nr << 1;
    282   }
    283 
    284   if (sign < 0) {
    285     quotient = -quotient;
    286   }
    287 
    288   return (WORD16)quotient;
    289 }
    290 
    291 static PLATFORM_INLINE WORD16 mac16(WORD16 c, WORD16 op1, WORD16 op2) {
    292   WORD16 var_out;
    293 
    294   var_out = ixheaacd_mult16(op1, op2);
    295   var_out = ixheaacd_add16(c, var_out);
    296   return (var_out);
    297 }
    298 
    299 static PLATFORM_INLINE WORD16 mac16_sat(WORD16 c, WORD16 op1, WORD16 op2) {
    300   WORD16 var_out;
    301 
    302   var_out = ixheaacd_mult16(op1, op2);
    303   var_out = ixheaacd_add16_sat(c, var_out);
    304   return (var_out);
    305 }
    306 
    307 static PLATFORM_INLINE WORD16 mac16_shl(WORD16 c, WORD16 op1, WORD16 op2) {
    308   WORD16 var_out;
    309 
    310   var_out = ixheaacd_mult16_shl(op1, op2);
    311   var_out = ixheaacd_add16(c, var_out);
    312   return (var_out);
    313 }
    314 
    315 static PLATFORM_INLINE WORD16 mac16_shl_sat(WORD16 c, WORD16 op1, WORD16 op2) {
    316   WORD16 var_out;
    317   WORD32 temp;
    318 
    319   temp = ((WORD32)op1 * (WORD32)op2) >> 15;
    320   temp += c;
    321   var_out = ixheaacd_sat16(temp);
    322   return (var_out);
    323 }
    324 
    325 static PLATFORM_INLINE WORD16 ixheaacd_round16(WORD32 op1) {
    326   WORD16 var_out;
    327 
    328   var_out = (WORD16)(ixheaacd_add32_sat(op1, 0x8000) >> 16);
    329   return (var_out);
    330 }
    331 #endif
    332