00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __FIXED_H__
00034 #define __FIXED_H__
00035
00036 #ifdef __cplusplus
00037 extern "C" {
00038 #endif
00039
00040 #if defined(_WIN32_WCE) && defined(_ARM_)
00041 #include <cmnintrin.h>
00042 #endif
00043
00044
00045 #define COEF_BITS 28
00046 #define COEF_PRECISION (1 << COEF_BITS)
00047 #define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR
00048 #define REAL_PRECISION (1 << REAL_BITS)
00049
00050
00051 #define FRAC_SIZE 32
00052 #define FRAC_BITS 31
00053 #define FRAC_PRECISION ((uint32_t)(1 << FRAC_BITS))
00054 #define FRAC_MAX 0x7FFFFFFF
00055
00056 typedef int32_t real_t;
00057
00058
00059 #define REAL_CONST(A) (((A) >= 0) ? ((real_t)((A)*(REAL_PRECISION)+0.5)) : ((real_t)((A)*(REAL_PRECISION)-0.5)))
00060 #define COEF_CONST(A) (((A) >= 0) ? ((real_t)((A)*(COEF_PRECISION)+0.5)) : ((real_t)((A)*(COEF_PRECISION)-0.5)))
00061 #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))))
00062
00063
00064 #define Q2_BITS 22
00065 #define Q2_PRECISION (1 << Q2_BITS)
00066 #define Q2_CONST(A) (((A) >= 0) ? ((real_t)((A)*(Q2_PRECISION)+0.5)) : ((real_t)((A)*(Q2_PRECISION)-0.5)))
00067
00068 #if defined(_WIN32) && !defined(_WIN32_WCE)
00069
00070
00071 static INLINE real_t MUL_R(real_t A, real_t B)
00072 {
00073 _asm {
00074 mov eax,A
00075 imul B
00076 shrd eax,edx,REAL_BITS
00077 }
00078 }
00079
00080
00081 static INLINE real_t MUL_C(real_t A, real_t B)
00082 {
00083 _asm {
00084 mov eax,A
00085 imul B
00086 shrd eax,edx,COEF_BITS
00087 }
00088 }
00089
00090 static INLINE real_t MUL_Q2(real_t A, real_t B)
00091 {
00092 _asm {
00093 mov eax,A
00094 imul B
00095 shrd eax,edx,Q2_BITS
00096 }
00097 }
00098
00099 static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
00100 {
00101 _asm {
00102 mov eax,A
00103 imul B
00104 shrd eax,edx,6
00105 }
00106 }
00107
00108 static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
00109 {
00110 _asm {
00111 mov eax,A
00112 imul B
00113 shrd eax,edx,23
00114 }
00115 }
00116
00117 #if 1
00118 static INLINE real_t _MulHigh(real_t A, real_t B)
00119 {
00120 _asm {
00121 mov eax,A
00122 imul B
00123 mov eax,edx
00124 }
00125 }
00126
00127
00128 static INLINE real_t MUL_F(real_t A, real_t B)
00129 {
00130 return _MulHigh(A,B) << (FRAC_SIZE-FRAC_BITS);
00131 }
00132
00133
00134 static INLINE void ComplexMult(real_t *y1, real_t *y2,
00135 real_t x1, real_t x2, real_t c1, real_t c2)
00136 {
00137 *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS);
00138 *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS);
00139 }
00140 #else
00141 static INLINE real_t MUL_F(real_t A, real_t B)
00142 {
00143 _asm {
00144 mov eax,A
00145 imul B
00146 shrd eax,edx,FRAC_BITS
00147 }
00148 }
00149
00150
00151 static INLINE void ComplexMult(real_t *y1, real_t *y2,
00152 real_t x1, real_t x2, real_t c1, real_t c2)
00153 {
00154 *y1 = MUL_F(x1, c1) + MUL_F(x2, c2);
00155 *y2 = MUL_F(x2, c1) - MUL_F(x1, c2);
00156 }
00157 #endif
00158
00159 #elif defined(__GNUC__) && defined (__arm__)
00160
00161
00162 #define arm_mul(x, y, SCALEBITS) \
00163 ({ \
00164 uint32_t __hi; \
00165 uint32_t __lo; \
00166 uint32_t __result; \
00167 asm("smull %0, %1, %3, %4\n\t" \
00168 "movs %0, %0, lsr %5\n\t" \
00169 "adc %2, %0, %1, lsl %6" \
00170 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
00171 : "%r" (x), "r" (y), \
00172 "M" (SCALEBITS), "M" (32 - (SCALEBITS)) \
00173 : "cc"); \
00174 __result; \
00175 })
00176
00177 static INLINE real_t MUL_R(real_t A, real_t B)
00178 {
00179 return arm_mul(A, B, REAL_BITS);
00180 }
00181
00182 static INLINE real_t MUL_C(real_t A, real_t B)
00183 {
00184 return arm_mul(A, B, COEF_BITS);
00185 }
00186
00187 static INLINE real_t MUL_Q2(real_t A, real_t B)
00188 {
00189 return arm_mul(A, B, Q2_BITS);
00190 }
00191
00192 static INLINE real_t MUL_SHIFT6(real_t A, real_t B)
00193 {
00194 return arm_mul(A, B, 6);
00195 }
00196
00197 static INLINE real_t MUL_SHIFT23(real_t A, real_t B)
00198 {
00199 return arm_mul(A, B, 23);
00200 }
00201
00202 static INLINE real_t _MulHigh(real_t x, real_t y)
00203 {
00204 uint32_t __lo;
00205 uint32_t __hi;
00206 asm("smull\t%0, %1, %2, %3"
00207 : "=&r"(__lo),"=&r"(__hi)
00208 : "%r"(x),"r"(y)
00209 : "cc");
00210 return __hi;
00211 }
00212
00213 static INLINE real_t MUL_F(real_t A, real_t B)
00214 {
00215 return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS);
00216 }
00217
00218
00219 static INLINE void ComplexMult(real_t *y1, real_t *y2,
00220 real_t x1, real_t x2, real_t c1, real_t c2)
00221 {
00222 int32_t tmp, yt1, yt2;
00223 asm("smull %0, %1, %4, %6\n\t"
00224 "smlal %0, %1, %5, %7\n\t"
00225 "rsb %3, %4, #0\n\t"
00226 "smull %0, %2, %5, %6\n\t"
00227 "smlal %0, %2, %3, %7"
00228 : "=&r" (tmp), "=&r" (yt1), "=&r" (yt2), "=r" (x1)
00229 : "3" (x1), "r" (x2), "r" (c1), "r" (c2)
00230 : "cc" );
00231 *y1 = yt1 << (FRAC_SIZE-FRAC_BITS);
00232 *y2 = yt2 << (FRAC_SIZE-FRAC_BITS);
00233 }
00234
00235 #else
00236
00237
00238 #define MUL_R(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS)
00239
00240 #define MUL_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS)
00241
00242 #if defined(_WIN32_WCE) && defined(_ARM_)
00243
00244 static INLINE real_t MUL_F(real_t A, real_t B)
00245 {
00246 return _MulHigh(A,B) << (32-FRAC_BITS);
00247 }
00248 #else
00249 #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE)
00250 #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS)
00251 #endif
00252 #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
00253 #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
00254 #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
00255
00256
00257 static INLINE void ComplexMult(real_t *y1, real_t *y2,
00258 real_t x1, real_t x2, real_t c1, real_t c2)
00259 {
00260 *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS);
00261 *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS);
00262 }
00263
00264 #endif
00265
00266
00267
00268 #ifdef __cplusplus
00269 }
00270 #endif
00271 #endif