xref: /aosp_15_r20/external/rnnoise/src/kiss_fft.h (revision 1295d6828459cc82c3c29cc5d7d297215250a74b)
1*1295d682SXin Li /*Copyright (c) 2003-2004, Mark Borgerding
2*1295d682SXin Li   Lots of modifications by Jean-Marc Valin
3*1295d682SXin Li   Copyright (c) 2005-2007, Xiph.Org Foundation
4*1295d682SXin Li   Copyright (c) 2008,      Xiph.Org Foundation, CSIRO
5*1295d682SXin Li 
6*1295d682SXin Li   All rights reserved.
7*1295d682SXin Li 
8*1295d682SXin Li   Redistribution and use in source and binary forms, with or without
9*1295d682SXin Li    modification, are permitted provided that the following conditions are met:
10*1295d682SXin Li 
11*1295d682SXin Li     * Redistributions of source code must retain the above copyright notice,
12*1295d682SXin Li        this list of conditions and the following disclaimer.
13*1295d682SXin Li     * Redistributions in binary form must reproduce the above copyright notice,
14*1295d682SXin Li        this list of conditions and the following disclaimer in the
15*1295d682SXin Li        documentation and/or other materials provided with the distribution.
16*1295d682SXin Li 
17*1295d682SXin Li   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18*1295d682SXin Li   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*1295d682SXin Li   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*1295d682SXin Li   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21*1295d682SXin Li   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*1295d682SXin Li   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*1295d682SXin Li   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*1295d682SXin Li   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*1295d682SXin Li   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*1295d682SXin Li   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*1295d682SXin Li   POSSIBILITY OF SUCH DAMAGE.*/
28*1295d682SXin Li 
29*1295d682SXin Li #ifndef KISS_FFT_H
30*1295d682SXin Li #define KISS_FFT_H
31*1295d682SXin Li 
32*1295d682SXin Li #include <stdlib.h>
33*1295d682SXin Li #include <math.h>
34*1295d682SXin Li #include "arch.h"
35*1295d682SXin Li 
36*1295d682SXin Li #include <stdlib.h>
37*1295d682SXin Li #define opus_alloc(x) malloc(x)
38*1295d682SXin Li #define opus_free(x) free(x)
39*1295d682SXin Li 
40*1295d682SXin Li #ifdef __cplusplus
41*1295d682SXin Li extern "C" {
42*1295d682SXin Li #endif
43*1295d682SXin Li 
44*1295d682SXin Li #ifdef USE_SIMD
45*1295d682SXin Li # include <xmmintrin.h>
46*1295d682SXin Li # define kiss_fft_scalar __m128
47*1295d682SXin Li #define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
48*1295d682SXin Li #else
49*1295d682SXin Li #define KISS_FFT_MALLOC opus_alloc
50*1295d682SXin Li #endif
51*1295d682SXin Li 
52*1295d682SXin Li #ifdef FIXED_POINT
53*1295d682SXin Li #include "arch.h"
54*1295d682SXin Li 
55*1295d682SXin Li #  define kiss_fft_scalar opus_int32
56*1295d682SXin Li #  define kiss_twiddle_scalar opus_int16
57*1295d682SXin Li 
58*1295d682SXin Li 
59*1295d682SXin Li #else
60*1295d682SXin Li # ifndef kiss_fft_scalar
61*1295d682SXin Li /*  default is float */
62*1295d682SXin Li #   define kiss_fft_scalar float
63*1295d682SXin Li #   define kiss_twiddle_scalar float
64*1295d682SXin Li #   define KF_SUFFIX _celt_single
65*1295d682SXin Li # endif
66*1295d682SXin Li #endif
67*1295d682SXin Li 
68*1295d682SXin Li typedef struct {
69*1295d682SXin Li     kiss_fft_scalar r;
70*1295d682SXin Li     kiss_fft_scalar i;
71*1295d682SXin Li }kiss_fft_cpx;
72*1295d682SXin Li 
73*1295d682SXin Li typedef struct {
74*1295d682SXin Li    kiss_twiddle_scalar r;
75*1295d682SXin Li    kiss_twiddle_scalar i;
76*1295d682SXin Li }kiss_twiddle_cpx;
77*1295d682SXin Li 
78*1295d682SXin Li #define MAXFACTORS 8
79*1295d682SXin Li /* e.g. an fft of length 128 has 4 factors
80*1295d682SXin Li  as far as kissfft is concerned
81*1295d682SXin Li  4*4*4*2
82*1295d682SXin Li  */
83*1295d682SXin Li 
84*1295d682SXin Li typedef struct arch_fft_state{
85*1295d682SXin Li    int is_supported;
86*1295d682SXin Li    void *priv;
87*1295d682SXin Li } arch_fft_state;
88*1295d682SXin Li 
89*1295d682SXin Li typedef struct kiss_fft_state{
90*1295d682SXin Li     int nfft;
91*1295d682SXin Li     opus_val16 scale;
92*1295d682SXin Li #ifdef FIXED_POINT
93*1295d682SXin Li     int scale_shift;
94*1295d682SXin Li #endif
95*1295d682SXin Li     int shift;
96*1295d682SXin Li     opus_int16 factors[2*MAXFACTORS];
97*1295d682SXin Li     const opus_int16 *bitrev;
98*1295d682SXin Li     const kiss_twiddle_cpx *twiddles;
99*1295d682SXin Li     arch_fft_state *arch_fft;
100*1295d682SXin Li } kiss_fft_state;
101*1295d682SXin Li 
102*1295d682SXin Li #if defined(HAVE_ARM_NE10)
103*1295d682SXin Li #include "arm/fft_arm.h"
104*1295d682SXin Li #endif
105*1295d682SXin Li 
106*1295d682SXin Li /*typedef struct kiss_fft_state* kiss_fft_cfg;*/
107*1295d682SXin Li 
108*1295d682SXin Li /**
109*1295d682SXin Li  *  opus_fft_alloc
110*1295d682SXin Li  *
111*1295d682SXin Li  *  Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
112*1295d682SXin Li  *
113*1295d682SXin Li  *  typical usage:      kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL);
114*1295d682SXin Li  *
115*1295d682SXin Li  *  The return value from fft_alloc is a cfg buffer used internally
116*1295d682SXin Li  *  by the fft routine or NULL.
117*1295d682SXin Li  *
118*1295d682SXin Li  *  If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc.
119*1295d682SXin Li  *  The returned value should be free()d when done to avoid memory leaks.
120*1295d682SXin Li  *
121*1295d682SXin Li  *  The state can be placed in a user supplied buffer 'mem':
122*1295d682SXin Li  *  If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
123*1295d682SXin Li  *      then the function places the cfg in mem and the size used in *lenmem
124*1295d682SXin Li  *      and returns mem.
125*1295d682SXin Li  *
126*1295d682SXin Li  *  If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
127*1295d682SXin Li  *      then the function returns NULL and places the minimum cfg
128*1295d682SXin Li  *      buffer size in *lenmem.
129*1295d682SXin Li  * */
130*1295d682SXin Li 
131*1295d682SXin Li kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base, int arch);
132*1295d682SXin Li 
133*1295d682SXin Li kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch);
134*1295d682SXin Li 
135*1295d682SXin Li /**
136*1295d682SXin Li  * opus_fft(cfg,in_out_buf)
137*1295d682SXin Li  *
138*1295d682SXin Li  * Perform an FFT on a complex input buffer.
139*1295d682SXin Li  * for a forward FFT,
140*1295d682SXin Li  * fin should be  f[0] , f[1] , ... ,f[nfft-1]
141*1295d682SXin Li  * fout will be   F[0] , F[1] , ... ,F[nfft-1]
142*1295d682SXin Li  * Note that each element is complex and can be accessed like
143*1295d682SXin Li     f[k].r and f[k].i
144*1295d682SXin Li  * */
145*1295d682SXin Li void opus_fft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
146*1295d682SXin Li void opus_ifft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
147*1295d682SXin Li 
148*1295d682SXin Li void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);
149*1295d682SXin Li void opus_ifft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);
150*1295d682SXin Li 
151*1295d682SXin Li void opus_fft_free(const kiss_fft_state *cfg, int arch);
152*1295d682SXin Li 
153*1295d682SXin Li 
154*1295d682SXin Li void opus_fft_free_arch_c(kiss_fft_state *st);
155*1295d682SXin Li int opus_fft_alloc_arch_c(kiss_fft_state *st);
156*1295d682SXin Li 
157*1295d682SXin Li #if !defined(OVERRIDE_OPUS_FFT)
158*1295d682SXin Li /* Is run-time CPU detection enabled on this platform? */
159*1295d682SXin Li #if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10))
160*1295d682SXin Li 
161*1295d682SXin Li extern int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(
162*1295d682SXin Li  kiss_fft_state *st);
163*1295d682SXin Li 
164*1295d682SXin Li #define opus_fft_alloc_arch(_st, arch) \
165*1295d682SXin Li          ((*OPUS_FFT_ALLOC_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))
166*1295d682SXin Li 
167*1295d682SXin Li extern void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(
168*1295d682SXin Li  kiss_fft_state *st);
169*1295d682SXin Li #define opus_fft_free_arch(_st, arch) \
170*1295d682SXin Li          ((*OPUS_FFT_FREE_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))
171*1295d682SXin Li 
172*1295d682SXin Li extern void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
173*1295d682SXin Li  const kiss_fft_cpx *fin, kiss_fft_cpx *fout);
174*1295d682SXin Li #define opus_fft(_cfg, _fin, _fout, arch) \
175*1295d682SXin Li    ((*OPUS_FFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))
176*1295d682SXin Li 
177*1295d682SXin Li extern void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
178*1295d682SXin Li  const kiss_fft_cpx *fin, kiss_fft_cpx *fout);
179*1295d682SXin Li #define opus_ifft(_cfg, _fin, _fout, arch) \
180*1295d682SXin Li    ((*OPUS_IFFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))
181*1295d682SXin Li 
182*1295d682SXin Li #else /* else for if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */
183*1295d682SXin Li 
184*1295d682SXin Li #define opus_fft_alloc_arch(_st, arch) \
185*1295d682SXin Li          ((void)(arch), opus_fft_alloc_arch_c(_st))
186*1295d682SXin Li 
187*1295d682SXin Li #define opus_fft_free_arch(_st, arch) \
188*1295d682SXin Li          ((void)(arch), opus_fft_free_arch_c(_st))
189*1295d682SXin Li 
190*1295d682SXin Li #define opus_fft(_cfg, _fin, _fout, arch) \
191*1295d682SXin Li          ((void)(arch), opus_fft_c(_cfg, _fin, _fout))
192*1295d682SXin Li 
193*1295d682SXin Li #define opus_ifft(_cfg, _fin, _fout, arch) \
194*1295d682SXin Li          ((void)(arch), opus_ifft_c(_cfg, _fin, _fout))
195*1295d682SXin Li 
196*1295d682SXin Li #endif /* end if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */
197*1295d682SXin Li #endif /* end if !defined(OVERRIDE_OPUS_FFT) */
198*1295d682SXin Li 
199*1295d682SXin Li #ifdef __cplusplus
200*1295d682SXin Li }
201*1295d682SXin Li #endif
202*1295d682SXin Li 
203*1295d682SXin Li #endif
204