paulstretch_cpp

PaulStretch
Log | Files | Refs | LICENSE

_kiss_fft_guts.h (5260B)


      1 /*
      2 Copyright (c) 2003-2004, Mark Borgerding
      3 
      4 All rights reserved.
      5 
      6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
      7 
      8     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
     10     * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
     11 
     12 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     13 */
     14 
     15 /* kiss_fft.h
     16    defines kiss_fft_scalar as either short or a float type
     17    and defines
     18    typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
     19 #include "kiss_fft.h"
     20 #include <limits.h>
     21 
     22 #define MAXFACTORS 32
     23 /* e.g. an fft of length 128 has 4 factors 
     24  as far as kissfft is concerned
     25  4*4*4*2
     26  */
     27 
     28 struct kiss_fft_state{
     29     int nfft;
     30     int inverse;
     31     int factors[2*MAXFACTORS];
     32     kiss_fft_cpx twiddles[1];
     33 };
     34 
     35 /*
     36   Explanation of macros dealing with complex math:
     37 
     38    C_MUL(m,a,b)         : m = a*b
     39    C_FIXDIV( c , div )  : if a fixed point impl., c /= div. noop otherwise
     40    C_SUB( res, a,b)     : res = a - b
     41    C_SUBFROM( res , a)  : res -= a
     42    C_ADDTO( res , a)    : res += a
     43  * */
     44 #ifdef FIXED_POINT
     45 #if (FIXED_POINT==32)
     46 # define FRACBITS 31
     47 # define SAMPPROD int64_t
     48 #define SAMP_MAX 2147483647
     49 #else
     50 # define FRACBITS 15
     51 # define SAMPPROD int32_t 
     52 #define SAMP_MAX 32767
     53 #endif
     54 
     55 #define SAMP_MIN -SAMP_MAX
     56 
     57 #if defined(CHECK_OVERFLOW)
     58 #  define CHECK_OVERFLOW_OP(a,op,b)  \
     59 	if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
     60 		fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) );  }
     61 #endif
     62 
     63 
     64 #   define smul(a,b) ( (SAMPPROD)(a)*(b) )
     65 #   define sround( x )  (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
     66 
     67 #   define S_MUL(a,b) sround( smul(a,b) )
     68 
     69 #   define C_MUL(m,a,b) \
     70       do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
     71           (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
     72 
     73 #   define DIVSCALAR(x,k) \
     74 	(x) = sround( smul(  x, SAMP_MAX/k ) )
     75 
     76 #   define C_FIXDIV(c,div) \
     77 	do {    DIVSCALAR( (c).r , div);  \
     78 		DIVSCALAR( (c).i  , div); }while (0)
     79 
     80 #   define C_MULBYSCALAR( c, s ) \
     81     do{ (c).r =  sround( smul( (c).r , s ) ) ;\
     82         (c).i =  sround( smul( (c).i , s ) ) ; }while(0)
     83 
     84 #else  /* not FIXED_POINT*/
     85 
     86 #   define S_MUL(a,b) ( (a)*(b) )
     87 #define C_MUL(m,a,b) \
     88     do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
     89         (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
     90 #   define C_FIXDIV(c,div) /* NOOP */
     91 #   define C_MULBYSCALAR( c, s ) \
     92     do{ (c).r *= (s);\
     93         (c).i *= (s); }while(0)
     94 #endif
     95 
     96 #ifndef CHECK_OVERFLOW_OP
     97 #  define CHECK_OVERFLOW_OP(a,op,b) /* noop */
     98 #endif
     99 
    100 #define  C_ADD( res, a,b)\
    101     do { \
    102 	    CHECK_OVERFLOW_OP((a).r,+,(b).r)\
    103 	    CHECK_OVERFLOW_OP((a).i,+,(b).i)\
    104 	    (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i; \
    105     }while(0)
    106 #define  C_SUB( res, a,b)\
    107     do { \
    108 	    CHECK_OVERFLOW_OP((a).r,-,(b).r)\
    109 	    CHECK_OVERFLOW_OP((a).i,-,(b).i)\
    110 	    (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i; \
    111     }while(0)
    112 #define C_ADDTO( res , a)\
    113     do { \
    114 	    CHECK_OVERFLOW_OP((res).r,+,(a).r)\
    115 	    CHECK_OVERFLOW_OP((res).i,+,(a).i)\
    116 	    (res).r += (a).r;  (res).i += (a).i;\
    117     }while(0)
    118 
    119 #define C_SUBFROM( res , a)\
    120     do {\
    121 	    CHECK_OVERFLOW_OP((res).r,-,(a).r)\
    122 	    CHECK_OVERFLOW_OP((res).i,-,(a).i)\
    123 	    (res).r -= (a).r;  (res).i -= (a).i; \
    124     }while(0)
    125 
    126 
    127 #ifdef FIXED_POINT
    128 #  define KISS_FFT_COS(phase)  floor(.5+SAMP_MAX * cos (phase))
    129 #  define KISS_FFT_SIN(phase)  floor(.5+SAMP_MAX * sin (phase))
    130 #  define HALF_OF(x) ((x)>>1)
    131 #elif defined(USE_SIMD)
    132 #  define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
    133 #  define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
    134 #  define HALF_OF(x) ((x)*_mm_set1_ps(.5))
    135 #else
    136 #  define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
    137 #  define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
    138 #  define HALF_OF(x) ((x)*.5)
    139 #endif
    140 
    141 #define  kf_cexp(x,phase) \
    142 	do{ \
    143 		(x)->r = KISS_FFT_COS(phase);\
    144 		(x)->i = KISS_FFT_SIN(phase);\
    145 	}while(0)
    146 
    147 
    148 /* a debugging function */
    149 #define pcpx(c)\
    150     fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )