00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kiss_fft.h"
00020 #include <limits.h>
00021
00022 #define MAXFACTORS 32
00023
00024
00025
00026
00027
00028 struct kiss_fft_state{
00029 int nfft;
00030 int inverse;
00031 int factors[2*MAXFACTORS];
00032 kiss_fft_cpx twiddles[1];
00033 };
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifdef FIXED_POINT
00045 #if (FIXED_POINT==32)
00046 # define FRACBITS 31
00047 # define SAMPPROD int64_t
00048 #define SAMP_MAX 2147483647
00049 #else
00050 # define FRACBITS 15
00051 # define SAMPPROD int32_t
00052 #define SAMP_MAX 32767
00053 #endif
00054
00055 #define SAMP_MIN -SAMP_MAX
00056
00057 #if defined(CHECK_OVERFLOW)
00058 # define CHECK_OVERFLOW_OP(a,op,b) \
00059 if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
00060 fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); }
00061 #endif
00062
00063
00064 # define smul(a,b) ( (SAMPPROD)(a)*(b) )
00065 # define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
00066
00067 # define S_MUL(a,b) sround( smul(a,b) )
00068
00069 # define C_MUL(m,a,b) \
00070 do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
00071 (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
00072
00073 # define DIVSCALAR(x,k) \
00074 (x) = sround( smul( x, SAMP_MAX/k ) )
00075
00076 # define C_FIXDIV(c,div) \
00077 do { DIVSCALAR( (c).r , div); \
00078 DIVSCALAR( (c).i , div); }while (0)
00079
00080 # define C_MULBYSCALAR( c, s ) \
00081 do{ (c).r = sround( smul( (c).r , s ) ) ;\
00082 (c).i = sround( smul( (c).i , s ) ) ; }while(0)
00083
00084 #else
00085
00086 # define S_MUL(a,b) ( (a)*(b) )
00087 #define C_MUL(m,a,b) \
00088 do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
00089 (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
00090 # define C_FIXDIV(c,div)
00091 # define C_MULBYSCALAR( c, s ) \
00092 do{ (c).r *= (s);\
00093 (c).i *= (s); }while(0)
00094 #endif
00095
00096 #ifndef CHECK_OVERFLOW_OP
00097 # define CHECK_OVERFLOW_OP(a,op,b)
00098 #endif
00099
00100 #define C_ADD( res, a,b)\
00101 do { \
00102 CHECK_OVERFLOW_OP((a).r,+,(b).r)\
00103 CHECK_OVERFLOW_OP((a).i,+,(b).i)\
00104 (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
00105 }while(0)
00106 #define C_SUB( res, a,b)\
00107 do { \
00108 CHECK_OVERFLOW_OP((a).r,-,(b).r)\
00109 CHECK_OVERFLOW_OP((a).i,-,(b).i)\
00110 (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
00111 }while(0)
00112 #define C_ADDTO( res , a)\
00113 do { \
00114 CHECK_OVERFLOW_OP((res).r,+,(a).r)\
00115 CHECK_OVERFLOW_OP((res).i,+,(a).i)\
00116 (res).r += (a).r; (res).i += (a).i;\
00117 }while(0)
00118
00119 #define C_SUBFROM( res , a)\
00120 do {\
00121 CHECK_OVERFLOW_OP((res).r,-,(a).r)\
00122 CHECK_OVERFLOW_OP((res).i,-,(a).i)\
00123 (res).r -= (a).r; (res).i -= (a).i; \
00124 }while(0)
00125
00126
00127 #ifdef FIXED_POINT
00128 # define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase))
00129 # define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase))
00130 # define HALF_OF(x) ((x)>>1)
00131 #elif defined(USE_SIMD)
00132 # define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
00133 # define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
00134 # define HALF_OF(x) ((x)*_mm_set1_ps(.5))
00135 #else
00136 # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
00137 # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
00138 # define HALF_OF(x) ((x)*.5)
00139 #endif
00140
00141 #define kf_cexp(x,phase) \
00142 do{ \
00143 (x)->r = KISS_FFT_COS(phase);\
00144 (x)->i = KISS_FFT_SIN(phase);\
00145 }while(0)
00146
00147
00148
00149 #define pcpx(c)\
00150 fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
00151
00152
00153 #ifdef KISS_FFT_USE_ALLOCA
00154
00155
00156
00157
00158 #include <alloca.h>
00159 #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
00160 #define KISS_FFT_TMP_FREE(ptr)
00161 #else
00162 #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
00163 #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
00164 #endif