1*3f1979aaSAndroid Build Coastguard Worker /* Copyright (c) 2013 Julien Pommier ( [email protected] ) 2*3f1979aaSAndroid Build Coastguard Worker 3*3f1979aaSAndroid Build Coastguard Worker Based on original fortran 77 code from FFTPACKv4 from NETLIB, 4*3f1979aaSAndroid Build Coastguard Worker authored by Dr Paul Swarztrauber of NCAR, in 1985. 5*3f1979aaSAndroid Build Coastguard Worker 6*3f1979aaSAndroid Build Coastguard Worker As confirmed by the NCAR fftpack software curators, the following 7*3f1979aaSAndroid Build Coastguard Worker FFTPACKv5 license applies to FFTPACKv4 sources. My changes are 8*3f1979aaSAndroid Build Coastguard Worker released under the same terms. 9*3f1979aaSAndroid Build Coastguard Worker 10*3f1979aaSAndroid Build Coastguard Worker FFTPACK license: 11*3f1979aaSAndroid Build Coastguard Worker 12*3f1979aaSAndroid Build Coastguard Worker http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html 13*3f1979aaSAndroid Build Coastguard Worker 14*3f1979aaSAndroid Build Coastguard Worker Copyright (c) 2004 the University Corporation for Atmospheric 15*3f1979aaSAndroid Build Coastguard Worker Research ("UCAR"). All rights reserved. Developed by NCAR's 16*3f1979aaSAndroid Build Coastguard Worker Computational and Information Systems Laboratory, UCAR, 17*3f1979aaSAndroid Build Coastguard Worker www.cisl.ucar.edu. 18*3f1979aaSAndroid Build Coastguard Worker 19*3f1979aaSAndroid Build Coastguard Worker Redistribution and use of the Software in source and binary forms, 20*3f1979aaSAndroid Build Coastguard Worker with or without modification, is permitted provided that the 21*3f1979aaSAndroid Build Coastguard Worker following conditions are met: 22*3f1979aaSAndroid Build Coastguard Worker 23*3f1979aaSAndroid Build Coastguard Worker - Neither the names of NCAR's Computational and Information Systems 24*3f1979aaSAndroid Build Coastguard Worker Laboratory, the University Corporation for Atmospheric Research, 25*3f1979aaSAndroid Build Coastguard Worker nor the names of its sponsors or contributors may be used to 26*3f1979aaSAndroid Build Coastguard Worker endorse or promote products derived from this Software without 27*3f1979aaSAndroid Build Coastguard Worker specific prior written permission. 28*3f1979aaSAndroid Build Coastguard Worker 29*3f1979aaSAndroid Build Coastguard Worker - Redistributions of source code must retain the above copyright 30*3f1979aaSAndroid Build Coastguard Worker notices, this list of conditions, and the disclaimer below. 31*3f1979aaSAndroid Build Coastguard Worker 32*3f1979aaSAndroid Build Coastguard Worker - Redistributions in binary form must reproduce the above copyright 33*3f1979aaSAndroid Build Coastguard Worker notice, this list of conditions, and the disclaimer below in the 34*3f1979aaSAndroid Build Coastguard Worker documentation and/or other materials provided with the 35*3f1979aaSAndroid Build Coastguard Worker distribution. 36*3f1979aaSAndroid Build Coastguard Worker 37*3f1979aaSAndroid Build Coastguard Worker THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 38*3f1979aaSAndroid Build Coastguard Worker EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF 39*3f1979aaSAndroid Build Coastguard Worker MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 40*3f1979aaSAndroid Build Coastguard Worker NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT 41*3f1979aaSAndroid Build Coastguard Worker HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL, 42*3f1979aaSAndroid Build Coastguard Worker EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN 43*3f1979aaSAndroid Build Coastguard Worker ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 44*3f1979aaSAndroid Build Coastguard Worker CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 45*3f1979aaSAndroid Build Coastguard Worker SOFTWARE. 46*3f1979aaSAndroid Build Coastguard Worker */ 47*3f1979aaSAndroid Build Coastguard Worker 48*3f1979aaSAndroid Build Coastguard Worker /* 49*3f1979aaSAndroid Build Coastguard Worker PFFFT : a Pretty Fast FFT. 50*3f1979aaSAndroid Build Coastguard Worker 51*3f1979aaSAndroid Build Coastguard Worker This is basically an adaptation of the single precision fftpack 52*3f1979aaSAndroid Build Coastguard Worker (v4) as found on netlib taking advantage of SIMD instruction found 53*3f1979aaSAndroid Build Coastguard Worker on cpus such as intel x86 (SSE1), powerpc (Altivec), and arm (NEON). 54*3f1979aaSAndroid Build Coastguard Worker 55*3f1979aaSAndroid Build Coastguard Worker For architectures where no SIMD instruction is available, the code 56*3f1979aaSAndroid Build Coastguard Worker falls back to a scalar version. 57*3f1979aaSAndroid Build Coastguard Worker 58*3f1979aaSAndroid Build Coastguard Worker Restrictions: 59*3f1979aaSAndroid Build Coastguard Worker 60*3f1979aaSAndroid Build Coastguard Worker - 1D transforms only, with 32-bit single precision. 61*3f1979aaSAndroid Build Coastguard Worker 62*3f1979aaSAndroid Build Coastguard Worker - supports only transforms for inputs of length N of the form 63*3f1979aaSAndroid Build Coastguard Worker N=(2^a)*(3^b)*(5^c), a >= 5, b >=0, c >= 0 (32, 48, 64, 96, 128, 64*3f1979aaSAndroid Build Coastguard Worker 144, 160, etc are all acceptable lengths). Performance is best for 65*3f1979aaSAndroid Build Coastguard Worker 128<=N<=8192. 66*3f1979aaSAndroid Build Coastguard Worker 67*3f1979aaSAndroid Build Coastguard Worker - all (float*) pointers in the functions below are expected to 68*3f1979aaSAndroid Build Coastguard Worker have an "simd-compatible" alignment, that is 16 bytes on x86 and 69*3f1979aaSAndroid Build Coastguard Worker powerpc CPUs. 70*3f1979aaSAndroid Build Coastguard Worker 71*3f1979aaSAndroid Build Coastguard Worker You can allocate such buffers with the functions 72*3f1979aaSAndroid Build Coastguard Worker pffft_aligned_malloc / pffft_aligned_free (or with stuff like 73*3f1979aaSAndroid Build Coastguard Worker posix_memalign..) 74*3f1979aaSAndroid Build Coastguard Worker 75*3f1979aaSAndroid Build Coastguard Worker */ 76*3f1979aaSAndroid Build Coastguard Worker 77*3f1979aaSAndroid Build Coastguard Worker #ifndef PFFFT_H 78*3f1979aaSAndroid Build Coastguard Worker #define PFFFT_H 79*3f1979aaSAndroid Build Coastguard Worker 80*3f1979aaSAndroid Build Coastguard Worker #include <stddef.h> /* for size_t */ 81*3f1979aaSAndroid Build Coastguard Worker 82*3f1979aaSAndroid Build Coastguard Worker #ifdef __cplusplus 83*3f1979aaSAndroid Build Coastguard Worker extern "C" { 84*3f1979aaSAndroid Build Coastguard Worker #endif 85*3f1979aaSAndroid Build Coastguard Worker 86*3f1979aaSAndroid Build Coastguard Worker /* opaque struct holding internal stuff (precomputed twiddle factors) 87*3f1979aaSAndroid Build Coastguard Worker this struct can be shared by many threads as it contains only 88*3f1979aaSAndroid Build Coastguard Worker read-only data. 89*3f1979aaSAndroid Build Coastguard Worker */ 90*3f1979aaSAndroid Build Coastguard Worker typedef struct PFFFT_Setup PFFFT_Setup; 91*3f1979aaSAndroid Build Coastguard Worker 92*3f1979aaSAndroid Build Coastguard Worker #ifndef PFFFT_COMMON_ENUMS 93*3f1979aaSAndroid Build Coastguard Worker #define PFFFT_COMMON_ENUMS 94*3f1979aaSAndroid Build Coastguard Worker 95*3f1979aaSAndroid Build Coastguard Worker /* direction of the transform */ 96*3f1979aaSAndroid Build Coastguard Worker typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t; 97*3f1979aaSAndroid Build Coastguard Worker 98*3f1979aaSAndroid Build Coastguard Worker /* type of transform */ 99*3f1979aaSAndroid Build Coastguard Worker typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t; 100*3f1979aaSAndroid Build Coastguard Worker 101*3f1979aaSAndroid Build Coastguard Worker #endif 102*3f1979aaSAndroid Build Coastguard Worker 103*3f1979aaSAndroid Build Coastguard Worker /* 104*3f1979aaSAndroid Build Coastguard Worker prepare for performing transforms of size N -- the returned 105*3f1979aaSAndroid Build Coastguard Worker PFFFT_Setup structure is read-only so it can safely be shared by 106*3f1979aaSAndroid Build Coastguard Worker multiple concurrent threads. 107*3f1979aaSAndroid Build Coastguard Worker */ 108*3f1979aaSAndroid Build Coastguard Worker PFFFT_Setup *pffft_new_setup(int N, pffft_transform_t transform); 109*3f1979aaSAndroid Build Coastguard Worker void pffft_destroy_setup(PFFFT_Setup *); 110*3f1979aaSAndroid Build Coastguard Worker /* 111*3f1979aaSAndroid Build Coastguard Worker Perform a Fourier transform , The z-domain data is stored in the 112*3f1979aaSAndroid Build Coastguard Worker most efficient order for transforming it back, or using it for 113*3f1979aaSAndroid Build Coastguard Worker convolution. If you need to have its content sorted in the 114*3f1979aaSAndroid Build Coastguard Worker "usual" way, that is as an array of interleaved complex numbers, 115*3f1979aaSAndroid Build Coastguard Worker either use pffft_transform_ordered , or call pffft_zreorder after 116*3f1979aaSAndroid Build Coastguard Worker the forward fft, and before the backward fft. 117*3f1979aaSAndroid Build Coastguard Worker 118*3f1979aaSAndroid Build Coastguard Worker Transforms are not scaled: PFFFT_BACKWARD(PFFFT_FORWARD(x)) = N*x. 119*3f1979aaSAndroid Build Coastguard Worker Typically you will want to scale the backward transform by 1/N. 120*3f1979aaSAndroid Build Coastguard Worker 121*3f1979aaSAndroid Build Coastguard Worker The 'work' pointer should point to an area of N (2*N for complex 122*3f1979aaSAndroid Build Coastguard Worker fft) floats, properly aligned. If 'work' is NULL, then stack will 123*3f1979aaSAndroid Build Coastguard Worker be used instead (this is probably the best strategy for small 124*3f1979aaSAndroid Build Coastguard Worker FFTs, say for N < 16384). Threads usually have a small stack, that 125*3f1979aaSAndroid Build Coastguard Worker there's no sufficient amount of memory, usually leading to a crash! 126*3f1979aaSAndroid Build Coastguard Worker Use the heap with pffft_aligned_malloc() in this case. 127*3f1979aaSAndroid Build Coastguard Worker 128*3f1979aaSAndroid Build Coastguard Worker input and output may alias. 129*3f1979aaSAndroid Build Coastguard Worker */ 130*3f1979aaSAndroid Build Coastguard Worker void pffft_transform(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction); 131*3f1979aaSAndroid Build Coastguard Worker 132*3f1979aaSAndroid Build Coastguard Worker /* 133*3f1979aaSAndroid Build Coastguard Worker Similar to pffft_transform, but makes sure that the output is 134*3f1979aaSAndroid Build Coastguard Worker ordered as expected (interleaved complex numbers). This is 135*3f1979aaSAndroid Build Coastguard Worker similar to calling pffft_transform and then pffft_zreorder. 136*3f1979aaSAndroid Build Coastguard Worker 137*3f1979aaSAndroid Build Coastguard Worker input and output may alias. 138*3f1979aaSAndroid Build Coastguard Worker */ 139*3f1979aaSAndroid Build Coastguard Worker void pffft_transform_ordered(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction); 140*3f1979aaSAndroid Build Coastguard Worker 141*3f1979aaSAndroid Build Coastguard Worker /* 142*3f1979aaSAndroid Build Coastguard Worker call pffft_zreorder(.., PFFFT_FORWARD) after pffft_transform(..., 143*3f1979aaSAndroid Build Coastguard Worker PFFFT_FORWARD) if you want to have the frequency components in 144*3f1979aaSAndroid Build Coastguard Worker the correct "canonical" order, as interleaved complex numbers. 145*3f1979aaSAndroid Build Coastguard Worker 146*3f1979aaSAndroid Build Coastguard Worker (for real transforms, both 0-frequency and half frequency 147*3f1979aaSAndroid Build Coastguard Worker components, which are real, are assembled in the first entry as 148*3f1979aaSAndroid Build Coastguard Worker F(0)+i*F(n/2+1). Note that the original fftpack did place 149*3f1979aaSAndroid Build Coastguard Worker F(n/2+1) at the end of the arrays). 150*3f1979aaSAndroid Build Coastguard Worker 151*3f1979aaSAndroid Build Coastguard Worker input and output should not alias. 152*3f1979aaSAndroid Build Coastguard Worker */ 153*3f1979aaSAndroid Build Coastguard Worker void pffft_zreorder(PFFFT_Setup *setup, const float *input, float *output, pffft_direction_t direction); 154*3f1979aaSAndroid Build Coastguard Worker 155*3f1979aaSAndroid Build Coastguard Worker /* 156*3f1979aaSAndroid Build Coastguard Worker Perform a multiplication of the frequency components of dft_a and 157*3f1979aaSAndroid Build Coastguard Worker dft_b and accumulate them into dft_ab. The arrays should have 158*3f1979aaSAndroid Build Coastguard Worker been obtained with pffft_transform(.., PFFFT_FORWARD) and should 159*3f1979aaSAndroid Build Coastguard Worker *not* have been reordered with pffft_zreorder (otherwise just 160*3f1979aaSAndroid Build Coastguard Worker perform the operation yourself as the dft coefs are stored as 161*3f1979aaSAndroid Build Coastguard Worker interleaved complex numbers). 162*3f1979aaSAndroid Build Coastguard Worker 163*3f1979aaSAndroid Build Coastguard Worker the operation performed is: dft_ab += (dft_a * fdt_b)*scaling 164*3f1979aaSAndroid Build Coastguard Worker 165*3f1979aaSAndroid Build Coastguard Worker The dft_a, dft_b and dft_ab pointers may alias. 166*3f1979aaSAndroid Build Coastguard Worker */ 167*3f1979aaSAndroid Build Coastguard Worker void pffft_zconvolve_accumulate(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling); 168*3f1979aaSAndroid Build Coastguard Worker 169*3f1979aaSAndroid Build Coastguard Worker /* 170*3f1979aaSAndroid Build Coastguard Worker Perform a multiplication of the frequency components of dft_a and 171*3f1979aaSAndroid Build Coastguard Worker dft_b and put result in dft_ab. The arrays should have 172*3f1979aaSAndroid Build Coastguard Worker been obtained with pffft_transform(.., PFFFT_FORWARD) and should 173*3f1979aaSAndroid Build Coastguard Worker *not* have been reordered with pffft_zreorder (otherwise just 174*3f1979aaSAndroid Build Coastguard Worker perform the operation yourself as the dft coefs are stored as 175*3f1979aaSAndroid Build Coastguard Worker interleaved complex numbers). 176*3f1979aaSAndroid Build Coastguard Worker 177*3f1979aaSAndroid Build Coastguard Worker the operation performed is: dft_ab = (dft_a * fdt_b)*scaling 178*3f1979aaSAndroid Build Coastguard Worker 179*3f1979aaSAndroid Build Coastguard Worker The dft_a, dft_b and dft_ab pointers may alias. 180*3f1979aaSAndroid Build Coastguard Worker */ 181*3f1979aaSAndroid Build Coastguard Worker void pffft_zconvolve_no_accu(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling); 182*3f1979aaSAndroid Build Coastguard Worker 183*3f1979aaSAndroid Build Coastguard Worker /* return 4 or 1 wether support SSE/NEON/Altivec instructions was enabled when building pffft.c */ 184*3f1979aaSAndroid Build Coastguard Worker int pffft_simd_size(); 185*3f1979aaSAndroid Build Coastguard Worker 186*3f1979aaSAndroid Build Coastguard Worker /* return string identifier of used architecture (SSE/NEON/Altivec/..) */ 187*3f1979aaSAndroid Build Coastguard Worker const char * pffft_simd_arch(); 188*3f1979aaSAndroid Build Coastguard Worker 189*3f1979aaSAndroid Build Coastguard Worker 190*3f1979aaSAndroid Build Coastguard Worker /* following functions are identical to the pffftd_ functions */ 191*3f1979aaSAndroid Build Coastguard Worker 192*3f1979aaSAndroid Build Coastguard Worker /* simple helper to get minimum possible fft size */ 193*3f1979aaSAndroid Build Coastguard Worker int pffft_min_fft_size(pffft_transform_t transform); 194*3f1979aaSAndroid Build Coastguard Worker 195*3f1979aaSAndroid Build Coastguard Worker /* simple helper to determine next power of 2 196*3f1979aaSAndroid Build Coastguard Worker - without inexact/rounding floating point operations 197*3f1979aaSAndroid Build Coastguard Worker */ 198*3f1979aaSAndroid Build Coastguard Worker int pffft_next_power_of_two(int N); 199*3f1979aaSAndroid Build Coastguard Worker 200*3f1979aaSAndroid Build Coastguard Worker /* simple helper to determine if power of 2 - returns bool */ 201*3f1979aaSAndroid Build Coastguard Worker int pffft_is_power_of_two(int N); 202*3f1979aaSAndroid Build Coastguard Worker 203*3f1979aaSAndroid Build Coastguard Worker /* 204*3f1979aaSAndroid Build Coastguard Worker the float buffers must have the correct alignment (16-byte boundary 205*3f1979aaSAndroid Build Coastguard Worker on intel and powerpc). This function may be used to obtain such 206*3f1979aaSAndroid Build Coastguard Worker correctly aligned buffers. 207*3f1979aaSAndroid Build Coastguard Worker */ 208*3f1979aaSAndroid Build Coastguard Worker void *pffft_aligned_malloc(size_t nb_bytes); 209*3f1979aaSAndroid Build Coastguard Worker void pffft_aligned_free(void *); 210*3f1979aaSAndroid Build Coastguard Worker 211*3f1979aaSAndroid Build Coastguard Worker #ifdef __cplusplus 212*3f1979aaSAndroid Build Coastguard Worker } 213*3f1979aaSAndroid Build Coastguard Worker #endif 214*3f1979aaSAndroid Build Coastguard Worker 215*3f1979aaSAndroid Build Coastguard Worker #endif /* PFFFT_H */ 216*3f1979aaSAndroid Build Coastguard Worker 217