FreeCalypso > hg > gsm-codec-lib
diff libgsmefr/basic_op.h @ 349:ed8762eea8a1
libgsmefr: use some inline functions from PacketVideo
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 22 Apr 2024 08:14:20 +0000 |
parents | 1c514150c033 |
children | 9b05bbc23b8a |
line wrap: on
line diff
--- a/libgsmefr/basic_op.h Mon Apr 22 00:05:01 2024 +0000 +++ b/libgsmefr/basic_op.h Mon Apr 22 08:14:20 2024 +0000 @@ -4,7 +4,9 @@ * The original version contained only function declarations, * resulting in a function call for every elementary operation; * the present version implements most of these operations as inline - * functions. + * functions. (Further update: for extra speed-up, the some inline + * function implementations have been lifted from PacketVideo AMR + * version, aka libopencore-amrnb.) * * Elimination of Overflow flag: examination of EFR code reveals that * both Carry and Overflow flags are accessed outside of basicop2.c @@ -159,24 +161,9 @@ static inline Word16 abs_s (Word16 var1) { - Word16 var_out; - - if (unlikely(var1 == (Word16) 0X8000)) - { - var_out = MAX_16; - } - else - { - if (var1 < 0) - { - var_out = -var1; - } - else - { - var_out = var1; - } - } - return (var_out); + Word16 y = var1 - (var1 < 0); + y = y ^ (y >> 15); + return (y); } /*___________________________________________________________________________ @@ -216,29 +203,23 @@ static inline Word16 shl (Word16 var1, Word16 var2) { - Word32 result; + Word16 var_out; - if (var2 < 0) { + if (unlikely(var2 < 0)) { var2 = -var2; - if (unlikely(var2 >= 15)) - return (var1 < 0) ? -1 : 0; - else - return var1 >> var2; + if (unlikely(var2 > 15)) + var2 = 15; + var_out = var1 >> var2; } else { - result = (Word32) var1 << var2; - if (var1 > 0) { - if (unlikely((var2 >= 15) || (result & 0xFFFF8000))) - return MAX_16; - else - return (Word16) result; - } else if (var1 < 0) { - if (unlikely((var2 >= 16) || ((result & 0xFFFF8000) != 0xFFFF8000))) - return MIN_16; - else - return (Word16) result; - } else - return 0; + if (unlikely(var2 > 15)) + var2 = 15; + var_out = var1 << var2; + if (unlikely(var_out >> var2 != var1)) + { + var_out = (var1 >> 15) ^ MAX_16; + } } + return var_out; } /*___________________________________________________________________________ @@ -278,29 +259,23 @@ static inline Word16 shr (Word16 var1, Word16 var2) { - Word32 result; + Word16 var_out; - if (var2 < 0) { + if (unlikely(var2 < 0)) { var2 = -var2; - result = (Word32) var1 << var2; - if (var1 > 0) { - if (unlikely((var2 >= 15) || (result & 0xFFFF8000))) - return MAX_16; - else - return (Word16) result; - } else if (var1 < 0) { - if (unlikely((var2 >= 16) || ((result & 0xFFFF8000) != 0xFFFF8000))) - return MIN_16; - else - return (Word16) result; - } else - return 0; + if (unlikely(var2 > 15)) + var2 = 15; + var_out = var1 << var2; + if (unlikely(var_out >> var2 != var1)) + { + var_out = (var1 >> 15) ^ MAX_16; + } } else { - if (unlikely(var2 >= 15)) - return (var1 < 0) ? -1 : 0; - else - return var1 >> var2; + if (unlikely(var2 > 15)) + var2 = 15; + var_out = var1 >> var2; } + return var_out; } /*___________________________________________________________________________ @@ -340,10 +315,20 @@ static inline Word16 mult (Word16 var1, Word16 var2) { - if (unlikely(var1 == MIN_16 && var2 == MIN_16)) - return MAX_16; - else - return ((Word32) var1 * var2) >> 15; + register Word32 product; + + product = ((Word32) var1 * var2) >> 15; + + /* Saturate result (if necessary). */ + /* var1 * var2 >0x00007fff is the only case */ + /* that saturation occurs. */ + + if (unlikely(product > 0x00007fff)) + product = (Word32) MAX_16; + + /* Return the product as a 16 bit value by type casting Word32 to Word16 */ + + return ((Word16) product); } /*___________________________________________________________________________ @@ -629,11 +614,21 @@ static inline Word32 L_mult (Word16 var1, Word16 var2) { - if (unlikely(var1 == MIN_16 && var2 == MIN_16)) { + register Word32 L_product; + + L_product = (Word32) var1 * var2; + + if (likely(L_product != (Word32) 0x40000000)) + { + L_product <<= 1; /* Multiply by 2 */ + } + else + { Overflow = 1; - return MAX_32; - } else - return ((Word32) var1 * var2) << 1; + L_product = MAX_32; + } + + return (L_product); } /*___________________________________________________________________________ @@ -804,13 +799,14 @@ { Word32 L_var_out; - if (var2 < 0) { + if (unlikely(var2 < 0)) { var2 = -var2; - if (unlikely(var2 >= 31)) - L_var_out = (L_var1 < 0) ? -1 : 0; - else - L_var_out = L_var1 >> var2; + if (unlikely(var2 > 31)) + var2 = 31; + L_var_out = L_var1 >> var2; } else { + if (unlikely(var2 > 31)) + var2 = 31; L_var_out = L_var1 << var2; if (unlikely(L_var_out >> var2 != L_var1)) L_var_out = (L_var1 >> 31) ^ MAX_32; @@ -856,16 +852,17 @@ { Word32 L_var_out; - if (var2 < 0) { + if (unlikely(var2 < 0)) { var2 = -var2; + if (unlikely(var2 > 31)) + var2 = 31; L_var_out = L_var1 << var2; if (unlikely(L_var_out >> var2 != L_var1)) L_var_out = (L_var1 >> 31) ^ MAX_32; } else { - if (unlikely(var2 >= 31)) - L_var_out = (L_var1 < 0) ? -1 : 0; - else - L_var_out = L_var1 >> var2; + if (unlikely(var2 > 31)) + var2 = 31; + L_var_out = L_var1 >> var2; } return (L_var_out); }