1*3f1979aaSAndroid Build Coastguard Worker 2*3f1979aaSAndroid Build Coastguard Worker #include "pffft.h" 3*3f1979aaSAndroid Build Coastguard Worker 4*3f1979aaSAndroid Build Coastguard Worker #include <stdlib.h> 5*3f1979aaSAndroid Build Coastguard Worker 6*3f1979aaSAndroid Build Coastguard Worker /* SSE and co like 16-bytes aligned pointers 7*3f1979aaSAndroid Build Coastguard Worker * with a 64-byte alignment, we are even aligned on L2 cache lines... */ 8*3f1979aaSAndroid Build Coastguard Worker #define MALLOC_V4SF_ALIGNMENT 64 9*3f1979aaSAndroid Build Coastguard Worker Valigned_malloc(size_t nb_bytes)10*3f1979aaSAndroid Build Coastguard Workerstatic void * Valigned_malloc(size_t nb_bytes) { 11*3f1979aaSAndroid Build Coastguard Worker void *p, *p0 = malloc(nb_bytes + MALLOC_V4SF_ALIGNMENT); 12*3f1979aaSAndroid Build Coastguard Worker if (!p0) return (void *) 0; 13*3f1979aaSAndroid Build Coastguard Worker p = (void *) (((size_t) p0 + MALLOC_V4SF_ALIGNMENT) & (~((size_t) (MALLOC_V4SF_ALIGNMENT-1)))); 14*3f1979aaSAndroid Build Coastguard Worker *((void **) p - 1) = p0; 15*3f1979aaSAndroid Build Coastguard Worker return p; 16*3f1979aaSAndroid Build Coastguard Worker } 17*3f1979aaSAndroid Build Coastguard Worker Valigned_free(void * p)18*3f1979aaSAndroid Build Coastguard Workerstatic void Valigned_free(void *p) { 19*3f1979aaSAndroid Build Coastguard Worker if (p) free(*((void **) p - 1)); 20*3f1979aaSAndroid Build Coastguard Worker } 21*3f1979aaSAndroid Build Coastguard Worker 22*3f1979aaSAndroid Build Coastguard Worker next_power_of_two(int N)23*3f1979aaSAndroid Build Coastguard Workerstatic int next_power_of_two(int N) { 24*3f1979aaSAndroid Build Coastguard Worker /* https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */ 25*3f1979aaSAndroid Build Coastguard Worker /* compute the next highest power of 2 of 32-bit v */ 26*3f1979aaSAndroid Build Coastguard Worker unsigned v = N; 27*3f1979aaSAndroid Build Coastguard Worker v--; 28*3f1979aaSAndroid Build Coastguard Worker v |= v >> 1; 29*3f1979aaSAndroid Build Coastguard Worker v |= v >> 2; 30*3f1979aaSAndroid Build Coastguard Worker v |= v >> 4; 31*3f1979aaSAndroid Build Coastguard Worker v |= v >> 8; 32*3f1979aaSAndroid Build Coastguard Worker v |= v >> 16; 33*3f1979aaSAndroid Build Coastguard Worker v++; 34*3f1979aaSAndroid Build Coastguard Worker return v; 35*3f1979aaSAndroid Build Coastguard Worker } 36*3f1979aaSAndroid Build Coastguard Worker is_power_of_two(int N)37*3f1979aaSAndroid Build Coastguard Workerstatic int is_power_of_two(int N) { 38*3f1979aaSAndroid Build Coastguard Worker /* https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 */ 39*3f1979aaSAndroid Build Coastguard Worker int f = N && !(N & (N - 1)); 40*3f1979aaSAndroid Build Coastguard Worker return f; 41*3f1979aaSAndroid Build Coastguard Worker } 42*3f1979aaSAndroid Build Coastguard Worker min_fft_size(pffft_transform_t transform)43*3f1979aaSAndroid Build Coastguard Workerstatic int min_fft_size(pffft_transform_t transform) { 44*3f1979aaSAndroid Build Coastguard Worker /* unfortunately, the fft size must be a multiple of 16 for complex FFTs 45*3f1979aaSAndroid Build Coastguard Worker and 32 for real FFTs -- a lot of stuff would need to be rewritten to 46*3f1979aaSAndroid Build Coastguard Worker handle other cases (or maybe just switch to a scalar fft, I don't know..) */ 47*3f1979aaSAndroid Build Coastguard Worker int simdSz = pffft_simd_size(); 48*3f1979aaSAndroid Build Coastguard Worker if (transform == PFFFT_REAL) 49*3f1979aaSAndroid Build Coastguard Worker return ( 2 * simdSz * simdSz ); 50*3f1979aaSAndroid Build Coastguard Worker else if (transform == PFFFT_COMPLEX) 51*3f1979aaSAndroid Build Coastguard Worker return ( simdSz * simdSz ); 52*3f1979aaSAndroid Build Coastguard Worker else 53*3f1979aaSAndroid Build Coastguard Worker return 1; 54*3f1979aaSAndroid Build Coastguard Worker } 55*3f1979aaSAndroid Build Coastguard Worker 56*3f1979aaSAndroid Build Coastguard Worker pffft_aligned_malloc(size_t nb_bytes)57*3f1979aaSAndroid Build Coastguard Workervoid *pffft_aligned_malloc(size_t nb_bytes) { return Valigned_malloc(nb_bytes); } pffft_aligned_free(void * p)58*3f1979aaSAndroid Build Coastguard Workervoid pffft_aligned_free(void *p) { Valigned_free(p); } pffft_next_power_of_two(int N)59*3f1979aaSAndroid Build Coastguard Workerint pffft_next_power_of_two(int N) { return next_power_of_two(N); } pffft_is_power_of_two(int N)60*3f1979aaSAndroid Build Coastguard Workerint pffft_is_power_of_two(int N) { return is_power_of_two(N); } pffft_min_fft_size(pffft_transform_t transform)61*3f1979aaSAndroid Build Coastguard Workerint pffft_min_fft_size(pffft_transform_t transform) { return min_fft_size(transform); } 62*3f1979aaSAndroid Build Coastguard Worker pffftd_aligned_malloc(size_t nb_bytes)63*3f1979aaSAndroid Build Coastguard Workervoid *pffftd_aligned_malloc(size_t nb_bytes) { return Valigned_malloc(nb_bytes); } pffftd_aligned_free(void * p)64*3f1979aaSAndroid Build Coastguard Workervoid pffftd_aligned_free(void *p) { Valigned_free(p); } pffftd_next_power_of_two(int N)65*3f1979aaSAndroid Build Coastguard Workerint pffftd_next_power_of_two(int N) { return next_power_of_two(N); } pffftd_is_power_of_two(int N)66*3f1979aaSAndroid Build Coastguard Workerint pffftd_is_power_of_two(int N) { return is_power_of_two(N); } pffftd_min_fft_size(pffft_transform_t transform)67*3f1979aaSAndroid Build Coastguard Workerint pffftd_min_fft_size(pffft_transform_t transform) { return min_fft_size(transform); } 68*3f1979aaSAndroid Build Coastguard Worker 69