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