annotate src/vamp-sdk/ext/_kiss_fft_guts.h @ 434:e979a9c4ffb6 vampipe

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