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);