fixed.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:8k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /*
  2. ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
  3. ** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com
  4. **  
  5. ** This program is free software; you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation; either version 2 of the License, or
  8. ** (at your option) any later version.
  9. ** 
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU General Public License for more details.
  14. ** 
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software 
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. **
  19. ** Any non-GPL usage of this software or parts of this software is strictly
  20. ** forbidden.
  21. **
  22. ** Software using this code must display the following message visibly in the
  23. ** software:
  24. ** "FAAD2 AAC/HE-AAC/HE-AACv2/DRM decoder (c) Ahead Software, www.nero.com"
  25. ** in, for example, the about-box or help/startup screen.
  26. **
  27. ** Commercial non-GPL licensing of this software is possible.
  28. ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
  29. **
  30. ** $Id: fixed.h,v 1.2 2005/11/01 21:41:43 gabest Exp $
  31. **/
  32. #ifndef __FIXED_H__
  33. #define __FIXED_H__
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37. #if defined(_WIN32_WCE) && defined(_ARM_)
  38. #include <cmnintrin.h>
  39. #endif
  40. #define COEF_BITS 28
  41. #define COEF_PRECISION (1 << COEF_BITS)
  42. #define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR
  43. #define REAL_PRECISION (1 << REAL_BITS)
  44. /* FRAC is the fractional only part of the fixed point number [0.0..1.0) */
  45. #define FRAC_SIZE 32 /* frac is a 32 bit integer */
  46. #define FRAC_BITS 31
  47. #define FRAC_PRECISION ((uint32_t)(1 << FRAC_BITS))
  48. #define FRAC_MAX 0x7FFFFFFF
  49. typedef int32_t real_t;
  50. #define REAL_CONST(A) (((A) >= 0) ? ((real_t)((A)*(REAL_PRECISION)+0.5)) : ((real_t)((A)*(REAL_PRECISION)-0.5)))
  51. #define COEF_CONST(A) (((A) >= 0) ? ((real_t)((A)*(COEF_PRECISION)+0.5)) : ((real_t)((A)*(COEF_PRECISION)-0.5)))
  52. #define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5))))
  53. //#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5)))
  54. #define Q2_BITS 22
  55. #define Q2_PRECISION (1 << Q2_BITS)
  56. #define Q2_CONST(A) (((A) >= 0) ? ((real_t)((A)*(Q2_PRECISION)+0.5)) : ((real_t)((A)*(Q2_PRECISION)-0.5)))
  57. #if defined(_WIN32) && !defined(_WIN32_WCE)
  58. /* multiply with real shift */
  59. static INLINE real_t MUL_R(real_t A, real_t B)
  60. {
  61.     _asm {
  62.         mov eax,A
  63.         imul B
  64.         shrd eax,edx,REAL_BITS
  65.     }
  66. }
  67. /* multiply with coef shift */
  68. static INLINE real_t MUL_C(real_t A, real_t B)
  69. {
  70.     _asm {
  71.         mov eax,A
  72.         imul B
  73.         shrd eax,edx,COEF_BITS
  74.     }
  75. }
  76. static INLINE real_t MUL_Q2(real_t A, real_t B)
  77. {
  78.     _asm {
  79.         mov eax,A
  80.         imul B
  81.         shrd eax,edx,Q2_BITS
  82.     }
  83. }
  84. static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
  85. {
  86.     _asm {
  87.         mov eax,A
  88.         imul B
  89.         shrd eax,edx,6
  90.     }
  91. }
  92. static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
  93. {
  94.     _asm {
  95.         mov eax,A
  96.         imul B
  97.         shrd eax,edx,23
  98.     }
  99. }
  100. #if 1
  101. static INLINE real_t _MulHigh(real_t A, real_t B)
  102. {
  103.     _asm {
  104.         mov eax,A
  105.         imul B
  106.         mov eax,edx
  107.     }
  108. }
  109. /* multiply with fractional shift */
  110. static INLINE real_t MUL_F(real_t A, real_t B)
  111. {
  112.     return _MulHigh(A,B) << (FRAC_SIZE-FRAC_BITS);
  113. }
  114. /* Complex multiplication */
  115. static INLINE void ComplexMult(real_t *y1, real_t *y2,
  116.     real_t x1, real_t x2, real_t c1, real_t c2)
  117. {
  118.     *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS);
  119.     *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS);
  120. }
  121. #else
  122. static INLINE real_t MUL_F(real_t A, real_t B)
  123. {
  124.     _asm {
  125.         mov eax,A
  126.         imul B
  127.         shrd eax,edx,FRAC_BITS
  128.     }
  129. }
  130. /* Complex multiplication */
  131. static INLINE void ComplexMult(real_t *y1, real_t *y2,
  132.     real_t x1, real_t x2, real_t c1, real_t c2)
  133. {
  134.     *y1 = MUL_F(x1, c1) + MUL_F(x2, c2);
  135.     *y2 = MUL_F(x2, c1) - MUL_F(x1, c2);
  136. }
  137. #endif
  138. #elif defined(__GNUC__) && defined (__arm__)
  139. /* taken from MAD */
  140. #define arm_mul(x, y, SCALEBITS) 
  141. ({ 
  142.     uint32_t __hi; 
  143.     uint32_t __lo; 
  144.     uint32_t __result; 
  145.     asm("smull  %0, %1, %3, %4nt" 
  146.         "movs   %0, %0, lsr %5nt" 
  147.         "adc    %2, %0, %1, lsl %6" 
  148.         : "=&r" (__lo), "=&r" (__hi), "=r" (__result) 
  149.         : "%r" (x), "r" (y), 
  150.         "M" (SCALEBITS), "M" (32 - (SCALEBITS)) 
  151.         : "cc"); 
  152.         __result; 
  153. })
  154. static INLINE real_t MUL_R(real_t A, real_t B)
  155. {
  156.     return arm_mul(A, B, REAL_BITS);
  157. }
  158. static INLINE real_t MUL_C(real_t A, real_t B)
  159. {
  160.     return arm_mul(A, B, COEF_BITS);
  161. }
  162. static INLINE real_t MUL_Q2(real_t A, real_t B)
  163. {
  164.     return arm_mul(A, B, Q2_BITS);
  165. }
  166. static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
  167. {
  168.     return arm_mul(A, B, 6);
  169. }
  170. static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
  171. {
  172.     return arm_mul(A, B, 23);
  173. }
  174. static INLINE real_t _MulHigh(real_t x, real_t y)
  175. {
  176.     uint32_t __lo;
  177.     uint32_t __hi;
  178.     asm("smullt%0, %1, %2, %3"
  179.         : "=&r"(__lo),"=&r"(__hi)
  180.         : "%r"(x),"r"(y)
  181.         : "cc");
  182.     return __hi;
  183. }
  184. static INLINE real_t MUL_F(real_t A, real_t B)
  185. {
  186.     return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS);
  187. }
  188. /* Complex multiplication */
  189. static INLINE void ComplexMult(real_t *y1, real_t *y2,
  190.     real_t x1, real_t x2, real_t c1, real_t c2)
  191. {
  192.     int32_t tmp, yt1, yt2;
  193.     asm("smull %0, %1, %4, %6nt"
  194.         "smlal %0, %1, %5, %7nt"
  195.         "rsb   %3, %4, #0nt"
  196.         "smull %0, %2, %5, %6nt"
  197.         "smlal %0, %2, %3, %7"
  198.         : "=&r" (tmp), "=&r" (yt1), "=&r" (yt2), "=r" (x1)
  199.         : "3" (x1), "r" (x2), "r" (c1), "r" (c2)
  200.         : "cc" );
  201.     *y1 = yt1 << (FRAC_SIZE-FRAC_BITS);
  202.     *y2 = yt2 << (FRAC_SIZE-FRAC_BITS);
  203. }
  204. #else
  205.   /* multiply with real shift */
  206.   #define MUL_R(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS)
  207.   /* multiply with coef shift */
  208.   #define MUL_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS)
  209.   /* multiply with fractional shift */
  210. #if defined(_WIN32_WCE) && defined(_ARM_)
  211.   /* eVC for PocketPC has an intrinsic function that returns only the high 32 bits of a 32x32 bit multiply */
  212.   static INLINE real_t MUL_F(real_t A, real_t B)
  213.   {
  214.       return _MulHigh(A,B) << (32-FRAC_BITS);
  215.   }
  216. #else
  217.   #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE)
  218.   #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS)
  219. #endif
  220.   #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
  221.   #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
  222.   #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
  223. /* Complex multiplication */
  224. static INLINE void ComplexMult(real_t *y1, real_t *y2,
  225.     real_t x1, real_t x2, real_t c1, real_t c2)
  226. {
  227.     *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS);
  228.     *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS);
  229. }
  230. #endif
  231. #ifdef __cplusplus
  232. }
  233. #endif
  234. #endif