annotate constant-q-cpp/src/ext/kissfft/_kiss_fft_guts.h @ 372:af71cbdab621 tip

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