1 // Copyright Jernej Krempuš 2012 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 /** 7 Functions in this module can be used from both C and D. To use them from C, 8 include pfft.h. Only the functions that operate on floats are listed here. To 9 calculate fft of doubles or reals (long doubles in C), just replace the "_f" 10 suffix on functions and "F" on types with "_d" or "_l" on functions and "D" or 11 "L" on types. 12 13 Example of using this module from C: 14 --- 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <pfft.h> 18 19 int main(int argc, char **argv) 20 { 21 int n = atoi(argv[1]); 22 PfftTableF tab = pfft_table_f(n, 0); 23 float *re = pfft_allocate_f(n); 24 float *im = pfft_allocate_f(n); 25 26 int i; 27 for(i = 0; i < n; i++) 28 scanf("%f %f", re + i, im + i); 29 30 pfft_fft_f(re, im, tab); 31 32 for(i = 0; i < n; i++) 33 printf("%f %f\n", re[i], im[i]); 34 35 pfft_free_f(re); 36 pfft_free_f(im); 37 pfft_table_free_f(tab); 38 } 39 --- 40 */ 41 module pfft.clib; 42 43 /** 44 A struct that contains precomputed tables used in $(D pfft_fft_f) and $(D pfft_ifft_f). 45 */ 46 struct PfftTableF{} 47 48 /** 49 Returns an instance $(D PfftTableF) suitable for computing discrete fourier 50 transforms on input sequences of length n (I will also use the name n 51 to refer to the length of the input sequence in the function descriptions below). 52 If null is passed as mem, the function will 53 alocate the needed memory. In this case you should call $(D pfft_table_free_f) on 54 the returned instance of $(D PfftTableF) when you are done with it. If a value 55 different from null is passed as mem, the function does not allocate and 56 uses memory at mem instead. In this case there should be at least 57 $(D pfft_table_size_bytes_f) bytes of memory available at mem and it should be 58 properly aligned. To find out what the proper alignment is, use $(D pfft_alignment_f). 59 */ 60 extern(C) PfftTableF pfft_table_f(size_t n, void* mem); 61 62 /** 63 This function returns the size of a memory block needed by $(D pfft_table_f). See 64 the description of $(D pfft_table_f) above. 65 */ 66 extern(C) size_t pfft_table_size_bytes_f(size_t n); 67 68 /** 69 Frees the memory used by a $(D PfftTableF) instance. If you passed a pointer 70 different from null as a second parameter to $(D pfft_table_f) when creating 71 the instance of $(D PfftTableF,) you should not call this function on it - 72 you should take care of dealocating memory you used yoursef instead. 73 */ 74 extern(C) void pfft_table_free_f(PfftTableF table); 75 76 /** 77 Computes discrete fourier transform. re should contain the real 78 part of the input sequence and im the imaginary part of the sequence. The 79 length of the input sequence should be equal to the number that was passed 80 to $(D pfft_table_f) when creating table. The method operates in place - the 81 result is saved back to $(D_PARAM re) and $(D_PARAM im). Both arrays must 82 be properly aligned. An easy way to obtain a properly aligned block of memory 83 is to use $(D pfft_allocate_f). If you want to take care of memory allocation in 84 some other way, you should make sure that the addresses re and im are multiples 85 of the number returned by $(D pfft_alignment_f). 86 */ 87 extern(C) void pfft_fft_f(float* re, float* im, PfftTableF table); 88 89 /** 90 This function is an inverse of $(D pfft_fft_f,) scaled by n. See the 91 description of $(D pfft_fft_f). 92 */ 93 extern(C) void pfft_ifft_f(float* re, float* im, PfftTableF table); 94 95 /** 96 A struct that contains precomputed tables used in $(D pfft_rfft_f) and $(D pfft_irfft_f). 97 */ 98 struct PfftRTableF{} 99 100 /** 101 This function is used in the same way as $(D pfft_table_f,) the only difference is 102 that it returns an instance of struct $(D PfftRTableF). 103 */ 104 extern(C) PfftRTableF pfft_rtable_f(size_t n, void* mem); 105 106 /** 107 This function returns the size of a memory block needed by $(D pfft_rtable_f). 108 See the descriptions of $(D pfft_rtable_f) and $(D pfft_table_f). 109 */ 110 extern(C) size_t pfft_rtable_size_bytes_f(size_t n); 111 112 /** 113 This function is used in the same was as $(D pfft_table_free_f,) the only difference 114 is that it takes an instance of struct $(D PfftRTableF) as a parameter. 115 */ 116 extern(C) void pfft_rtable_free_f(PfftRTableF table); 117 118 119 /** 120 Calculates discrete fourier transform of the real valued sequence in data. 121 The method operates in place. When the method completes, data contains the 122 result. First $(I n / 2 + 1) elements contain the real part of the result and 123 the rest contains the imaginary part. Imaginary parts at position 0 and 124 $(I n / 2) are known to be equal to 0 and are not stored, so the content of 125 data looks like this: 126 127 $(D r(0), r(1), ... r(n / 2), i(1), i(2), ... i(n / 2 - 1)) 128 129 130 The elements of the result at position greater than $(I n / 2) can be trivially 131 calculated from the relation $(I DFT(f)[i] = DFT(f)[n - i]*) that holds 132 because the input sequence is real. 133 134 135 The length of the array must be equal to n and the array must be properly 136 aligned. To obtain a properly aligned array you can use $(D pfft_allocate_f). 137 If you want to take care of memory allocation in some other way, you should 138 make sure that the address data is a multiple of the number returned by 139 $(D pfft_alignment_f). 140 */ 141 extern(C) void pfft_rfft_f(float* data, PfftRTableF table); 142 143 /** 144 Calculates the inverse of $(D pfft_rfft_f), scaled by n. Before the method 145 is called, data should contain a complex sequence in the same format as the 146 result of $(D pfft_rfft_f). It is assumed that the input sequence is a discrete 147 fourier transform of a real valued sequence, so the elements of the input 148 sequence not stored in data can be calculated from 149 $(I DFT(f)[i] = DFT(f)[n - i]*). When the method completes, the array 150 contains the real part of the inverse discrete fourier transform of the 151 input sequence, scaled by n. The imaginary part is known to be equal to zero. 152 153 The length of the array must be equal to n and the array must be properly 154 aligned. To obtain a properly aligned array you can use $(D pfft_allocate_f). 155 If you want to take care of memory allocation in some other way, you should 156 make sure that the address data is a multiple of the number returned by 157 $(D pfft_alignment_f). 158 */ 159 extern(C) void pfft_irfft_f(float* data, PfftRTableF table); 160 161 /** 162 Returns appropriate alignment for use with functions in this module for a 163 memory block of size nbytes. 164 */ 165 extern(C) size_t pfft_alignment_f(size_t nbytes); 166 167 /** 168 Returns a pointer to an array of size nelements, aligned apropriately for 169 use with functions in this module. 170 */ 171 extern(C) float* pfft_allocate_f(size_t nelements); 172 173 /** 174 Frees memory allocated with $(D pfft_allocate_f). 175 */ 176 extern(C) void pfft_free_f(float* p);