xref: /aosp_15_r20/external/rnnoise/src/_kiss_fft_guts.h (revision 1295d6828459cc82c3c29cc5d7d297215250a74b)
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