1*1295d682SXin Li /*Copyright (c) 2003-2004, Mark Borgerding 2*1295d682SXin Li 3*1295d682SXin Li All rights reserved. 4*1295d682SXin Li 5*1295d682SXin Li Redistribution and use in source and binary forms, with or without 6*1295d682SXin Li modification, are permitted provided that the following conditions are met: 7*1295d682SXin Li 8*1295d682SXin Li * Redistributions of source code must retain the above copyright notice, 9*1295d682SXin Li this list of conditions and the following disclaimer. 10*1295d682SXin Li * Redistributions in binary form must reproduce the above copyright notice, 11*1295d682SXin Li this list of conditions and the following disclaimer in the 12*1295d682SXin Li documentation and/or other materials provided with the distribution. 13*1295d682SXin Li 14*1295d682SXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15*1295d682SXin Li AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*1295d682SXin Li IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*1295d682SXin Li ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18*1295d682SXin Li LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19*1295d682SXin Li CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20*1295d682SXin Li SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21*1295d682SXin Li INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22*1295d682SXin Li CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23*1295d682SXin Li ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24*1295d682SXin Li POSSIBILITY OF SUCH DAMAGE.*/ 25*1295d682SXin Li 26*1295d682SXin Li #ifndef KISS_FFT_GUTS_H 27*1295d682SXin Li #define KISS_FFT_GUTS_H 28*1295d682SXin Li 29*1295d682SXin Li #define MIN(a,b) ((a)<(b) ? (a):(b)) 30*1295d682SXin Li #define MAX(a,b) ((a)>(b) ? (a):(b)) 31*1295d682SXin Li 32*1295d682SXin Li /* kiss_fft.h 33*1295d682SXin Li defines kiss_fft_scalar as either short or a float type 34*1295d682SXin Li and defines 35*1295d682SXin Li typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ 36*1295d682SXin Li #include "kiss_fft.h" 37*1295d682SXin Li 38*1295d682SXin Li /* 39*1295d682SXin Li Explanation of macros dealing with complex math: 40*1295d682SXin Li 41*1295d682SXin Li C_MUL(m,a,b) : m = a*b 42*1295d682SXin Li C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise 43*1295d682SXin Li C_SUB( res, a,b) : res = a - b 44*1295d682SXin Li C_SUBFROM( res , a) : res -= a 45*1295d682SXin Li C_ADDTO( res , a) : res += a 46*1295d682SXin Li * */ 47*1295d682SXin Li #ifdef FIXED_POINT 48*1295d682SXin Li #include "arch.h" 49*1295d682SXin Li 50*1295d682SXin Li 51*1295d682SXin Li #define SAMP_MAX 2147483647 52*1295d682SXin Li #define TWID_MAX 32767 53*1295d682SXin Li #define TRIG_UPSCALE 1 54*1295d682SXin Li 55*1295d682SXin Li #define SAMP_MIN -SAMP_MAX 56*1295d682SXin Li 57*1295d682SXin Li 58*1295d682SXin Li # define S_MUL(a,b) MULT16_32_Q15(b, a) 59*1295d682SXin Li 60*1295d682SXin Li # define C_MUL(m,a,b) \ 61*1295d682SXin Li do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ 62*1295d682SXin Li (m).i = ADD32_ovflw(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0) 63*1295d682SXin Li 64*1295d682SXin Li # define C_MULC(m,a,b) \ 65*1295d682SXin Li do{ (m).r = ADD32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ 66*1295d682SXin Li (m).i = SUB32_ovflw(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0) 67*1295d682SXin Li 68*1295d682SXin Li # define C_MULBYSCALAR( c, s ) \ 69*1295d682SXin Li do{ (c).r = S_MUL( (c).r , s ) ;\ 70*1295d682SXin Li (c).i = S_MUL( (c).i , s ) ; }while(0) 71*1295d682SXin Li 72*1295d682SXin Li # define DIVSCALAR(x,k) \ 73*1295d682SXin Li (x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 ) 74*1295d682SXin Li 75*1295d682SXin Li # define C_FIXDIV(c,div) \ 76*1295d682SXin Li do { DIVSCALAR( (c).r , div); \ 77*1295d682SXin Li DIVSCALAR( (c).i , div); }while (0) 78*1295d682SXin Li 79*1295d682SXin Li #define C_ADD( res, a,b)\ 80*1295d682SXin Li do {(res).r=ADD32_ovflw((a).r,(b).r); (res).i=ADD32_ovflw((a).i,(b).i); \ 81*1295d682SXin Li }while(0) 82*1295d682SXin Li #define C_SUB( res, a,b)\ 83*1295d682SXin Li do {(res).r=SUB32_ovflw((a).r,(b).r); (res).i=SUB32_ovflw((a).i,(b).i); \ 84*1295d682SXin Li }while(0) 85*1295d682SXin Li #define C_ADDTO( res , a)\ 86*1295d682SXin Li do {(res).r = ADD32_ovflw((res).r, (a).r); (res).i = ADD32_ovflw((res).i,(a).i);\ 87*1295d682SXin Li }while(0) 88*1295d682SXin Li 89*1295d682SXin Li #define C_SUBFROM( res , a)\ 90*1295d682SXin Li do {(res).r = ADD32_ovflw((res).r,(a).r); (res).i = SUB32_ovflw((res).i,(a).i); \ 91*1295d682SXin Li }while(0) 92*1295d682SXin Li 93*1295d682SXin Li #if defined(OPUS_ARM_INLINE_ASM) 94*1295d682SXin Li #include "arm/kiss_fft_armv4.h" 95*1295d682SXin Li #endif 96*1295d682SXin Li 97*1295d682SXin Li #if defined(OPUS_ARM_INLINE_EDSP) 98*1295d682SXin Li #include "arm/kiss_fft_armv5e.h" 99*1295d682SXin Li #endif 100*1295d682SXin Li #if defined(MIPSr1_ASM) 101*1295d682SXin Li #include "mips/kiss_fft_mipsr1.h" 102*1295d682SXin Li #endif 103*1295d682SXin Li 104*1295d682SXin Li #else /* not FIXED_POINT*/ 105*1295d682SXin Li 106*1295d682SXin Li # define S_MUL(a,b) ( (a)*(b) ) 107*1295d682SXin Li #define C_MUL(m,a,b) \ 108*1295d682SXin Li do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ 109*1295d682SXin Li (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) 110*1295d682SXin Li #define C_MULC(m,a,b) \ 111*1295d682SXin Li do{ (m).r = (a).r*(b).r + (a).i*(b).i;\ 112*1295d682SXin Li (m).i = (a).i*(b).r - (a).r*(b).i; }while(0) 113*1295d682SXin Li 114*1295d682SXin Li #define C_MUL4(m,a,b) C_MUL(m,a,b) 115*1295d682SXin Li 116*1295d682SXin Li # define C_FIXDIV(c,div) /* NOOP */ 117*1295d682SXin Li # define C_MULBYSCALAR( c, s ) \ 118*1295d682SXin Li do{ (c).r *= (s);\ 119*1295d682SXin Li (c).i *= (s); }while(0) 120*1295d682SXin Li #endif 121*1295d682SXin Li 122*1295d682SXin Li #ifndef CHECK_OVERFLOW_OP 123*1295d682SXin Li # define CHECK_OVERFLOW_OP(a,op,b) /* noop */ 124*1295d682SXin Li #endif 125*1295d682SXin Li 126*1295d682SXin Li #ifndef C_ADD 127*1295d682SXin Li #define C_ADD( res, a,b)\ 128*1295d682SXin Li do { \ 129*1295d682SXin Li CHECK_OVERFLOW_OP((a).r,+,(b).r)\ 130*1295d682SXin Li CHECK_OVERFLOW_OP((a).i,+,(b).i)\ 131*1295d682SXin Li (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ 132*1295d682SXin Li }while(0) 133*1295d682SXin Li #define C_SUB( res, a,b)\ 134*1295d682SXin Li do { \ 135*1295d682SXin Li CHECK_OVERFLOW_OP((a).r,-,(b).r)\ 136*1295d682SXin Li CHECK_OVERFLOW_OP((a).i,-,(b).i)\ 137*1295d682SXin Li (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ 138*1295d682SXin Li }while(0) 139*1295d682SXin Li #define C_ADDTO( res , a)\ 140*1295d682SXin Li do { \ 141*1295d682SXin Li CHECK_OVERFLOW_OP((res).r,+,(a).r)\ 142*1295d682SXin Li CHECK_OVERFLOW_OP((res).i,+,(a).i)\ 143*1295d682SXin Li (res).r += (a).r; (res).i += (a).i;\ 144*1295d682SXin Li }while(0) 145*1295d682SXin Li 146*1295d682SXin Li #define C_SUBFROM( res , a)\ 147*1295d682SXin Li do {\ 148*1295d682SXin Li CHECK_OVERFLOW_OP((res).r,-,(a).r)\ 149*1295d682SXin Li CHECK_OVERFLOW_OP((res).i,-,(a).i)\ 150*1295d682SXin Li (res).r -= (a).r; (res).i -= (a).i; \ 151*1295d682SXin Li }while(0) 152*1295d682SXin Li #endif /* C_ADD defined */ 153*1295d682SXin Li 154*1295d682SXin Li #ifdef FIXED_POINT 155*1295d682SXin Li /*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase)))) 156*1295d682SXin Li # define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/ 157*1295d682SXin Li # define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase)) 158*1295d682SXin Li # define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase)) 159*1295d682SXin Li # define HALF_OF(x) ((x)>>1) 160*1295d682SXin Li #elif defined(USE_SIMD) 161*1295d682SXin Li # define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) 162*1295d682SXin Li # define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) 163*1295d682SXin Li # define HALF_OF(x) ((x)*_mm_set1_ps(.5f)) 164*1295d682SXin Li #else 165*1295d682SXin Li # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) 166*1295d682SXin Li # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) 167*1295d682SXin Li # define HALF_OF(x) ((x)*.5f) 168*1295d682SXin Li #endif 169*1295d682SXin Li 170*1295d682SXin Li #define kf_cexp(x,phase) \ 171*1295d682SXin Li do{ \ 172*1295d682SXin Li (x)->r = KISS_FFT_COS(phase);\ 173*1295d682SXin Li (x)->i = KISS_FFT_SIN(phase);\ 174*1295d682SXin Li }while(0) 175*1295d682SXin Li 176*1295d682SXin Li #define kf_cexp2(x,phase) \ 177*1295d682SXin Li do{ \ 178*1295d682SXin Li (x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\ 179*1295d682SXin Li (x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\ 180*1295d682SXin Li }while(0) 181*1295d682SXin Li 182*1295d682SXin Li #endif /* KISS_FFT_GUTS_H */ 183