annotate ext/kissfft/_kiss_fft_guts.h @ 510:2adcd94c2079

Update test
author Chris Cannam <cannam@all-day-breakfast.com>
date Thu, 06 Jun 2019 14:26:46 +0100
parents 1f1999b0f577
children
rev   line source
c@409 1 /*
c@409 2 Copyright (c) 2003-2010, Mark Borgerding
c@409 3
c@409 4 All rights reserved.
c@409 5
c@409 6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
c@409 7
c@409 8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
c@409 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.
c@409 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.
c@409 11
c@409 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.
c@409 13 */
c@409 14
c@409 15 /* kiss_fft.h
c@409 16 defines kiss_fft_scalar as either short or a float type
c@409 17 and defines
c@409 18 typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
c@409 19 #include "kiss_fft.h"
c@409 20 #include <limits.h>
c@409 21
c@409 22 #define MAXFACTORS 32
c@409 23 /* e.g. an fft of length 128 has 4 factors
c@409 24 as far as kissfft is concerned
c@409 25 4*4*4*2
c@409 26 */
c@409 27
c@409 28 struct kiss_fft_state{
c@409 29 int nfft;
c@409 30 int inverse;
c@409 31 int factors[2*MAXFACTORS];
c@409 32 kiss_fft_cpx twiddles[1];
c@409 33 };
c@409 34
c@409 35 /*
c@409 36 Explanation of macros dealing with complex math:
c@409 37
c@409 38 C_MUL(m,a,b) : m = a*b
c@409 39 C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
c@409 40 C_SUB( res, a,b) : res = a - b
c@409 41 C_SUBFROM( res , a) : res -= a
c@409 42 C_ADDTO( res , a) : res += a
c@409 43 * */
c@409 44 #ifdef FIXED_POINT
c@409 45 #if (FIXED_POINT==32)
c@409 46 # define FRACBITS 31
c@409 47 # define SAMPPROD int64_t
c@409 48 #define SAMP_MAX 2147483647
c@409 49 #else
c@409 50 # define FRACBITS 15
c@409 51 # define SAMPPROD int32_t
c@409 52 #define SAMP_MAX 32767
c@409 53 #endif
c@409 54
c@409 55 #define SAMP_MIN -SAMP_MAX
c@409 56
c@409 57 #if defined(CHECK_OVERFLOW)
c@409 58 # define CHECK_OVERFLOW_OP(a,op,b) \
c@409 59 if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
c@409 60 fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); }
c@409 61 #endif
c@409 62
c@409 63
c@409 64 # define smul(a,b) ( (SAMPPROD)(a)*(b) )
c@409 65 # define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
c@409 66
c@409 67 # define S_MUL(a,b) sround( smul(a,b) )
c@409 68
c@409 69 # define C_MUL(m,a,b) \
c@409 70 do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
c@409 71 (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
c@409 72
c@409 73 # define DIVSCALAR(x,k) \
c@409 74 (x) = sround( smul( x, SAMP_MAX/k ) )
c@409 75
c@409 76 # define C_FIXDIV(c,div) \
c@409 77 do { DIVSCALAR( (c).r , div); \
c@409 78 DIVSCALAR( (c).i , div); }while (0)
c@409 79
c@409 80 # define C_MULBYSCALAR( c, s ) \
c@409 81 do{ (c).r = sround( smul( (c).r , s ) ) ;\
c@409 82 (c).i = sround( smul( (c).i , s ) ) ; }while(0)
c@409 83
c@409 84 #else /* not FIXED_POINT*/
c@409 85
c@409 86 # define S_MUL(a,b) ( (a)*(b) )
c@409 87 #define C_MUL(m,a,b) \
c@409 88 do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
c@409 89 (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
c@409 90 # define C_FIXDIV(c,div) /* NOOP */
c@409 91 # define C_MULBYSCALAR( c, s ) \
c@409 92 do{ (c).r *= (s);\
c@409 93 (c).i *= (s); }while(0)
c@409 94 #endif
c@409 95
c@409 96 #ifndef CHECK_OVERFLOW_OP
c@409 97 # define CHECK_OVERFLOW_OP(a,op,b) /* noop */
c@409 98 #endif
c@409 99
c@409 100 #define C_ADD( res, a,b)\
c@409 101 do { \
c@409 102 CHECK_OVERFLOW_OP((a).r,+,(b).r)\
c@409 103 CHECK_OVERFLOW_OP((a).i,+,(b).i)\
c@409 104 (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
c@409 105 }while(0)
c@409 106 #define C_SUB( res, a,b)\
c@409 107 do { \
c@409 108 CHECK_OVERFLOW_OP((a).r,-,(b).r)\
c@409 109 CHECK_OVERFLOW_OP((a).i,-,(b).i)\
c@409 110 (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
c@409 111 }while(0)
c@409 112 #define C_ADDTO( res , a)\
c@409 113 do { \
c@409 114 CHECK_OVERFLOW_OP((res).r,+,(a).r)\
c@409 115 CHECK_OVERFLOW_OP((res).i,+,(a).i)\
c@409 116 (res).r += (a).r; (res).i += (a).i;\
c@409 117 }while(0)
c@409 118
c@409 119 #define C_SUBFROM( res , a)\
c@409 120 do {\
c@409 121 CHECK_OVERFLOW_OP((res).r,-,(a).r)\
c@409 122 CHECK_OVERFLOW_OP((res).i,-,(a).i)\
c@409 123 (res).r -= (a).r; (res).i -= (a).i; \
c@409 124 }while(0)
c@409 125
c@409 126
c@409 127 #ifdef FIXED_POINT
c@409 128 # define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase))
c@409 129 # define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase))
c@409 130 # define HALF_OF(x) ((x)>>1)
c@409 131 #elif defined(USE_SIMD)
c@409 132 # define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
c@409 133 # define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
c@409 134 # define HALF_OF(x) ((x)*_mm_set1_ps(.5))
c@409 135 #else
c@409 136 # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
c@409 137 # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
c@409 138 # define HALF_OF(x) ((x)*.5)
c@409 139 #endif
c@409 140
c@409 141 #define kf_cexp(x,phase) \
c@409 142 do{ \
c@409 143 (x)->r = KISS_FFT_COS(phase);\
c@409 144 (x)->i = KISS_FFT_SIN(phase);\
c@409 145 }while(0)
c@409 146
c@409 147
c@409 148 /* a debugging function */
c@409 149 #define pcpx(c)\
c@409 150 fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
c@409 151
c@409 152
c@409 153 #ifdef KISS_FFT_USE_ALLOCA
c@409 154 // define this to allow use of alloca instead of malloc for temporary buffers
c@409 155 // Temporary buffers are used in two case:
c@409 156 // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
c@409 157 // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
c@409 158 #include <alloca.h>
c@409 159 #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
c@409 160 #define KISS_FFT_TMP_FREE(ptr)
c@409 161 #else
c@409 162 #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
c@409 163 #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
c@409 164 #endif