Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 415 lines (359 sloc) 14.099 kb
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
1 /*
2 SC_fftlib.cpp
3 An interface to abstract over different FFT libraries, for SuperCollider 3.
4 (c) 2007-2008 Dan Stowell, incorporating code from
5 SuperCollider 3 Copyright (c) 2002 James McCartney.
6 All rights reserved.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
b7013ee @danstowell Update address of Free Software Foundation (debian source-checking tools...
danstowell authored
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
21
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
22 NOTE:
23 vDSP uses a "SplitBuf" as an intermediate representation of the data.
24 For speed we keep this global, although this makes the code non-thread-safe.
25 (This is not new to this refactoring. Just worth noting.)
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
26 */
27
28 #include "clz.h"
29 #include <stdlib.h>
30 #include <cmath>
31 #include <stdio.h>
32 #include <cstring>
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
33 #include <cassert>
34
35 #include "SC_fftlib.h"
702d1c3 @timblechmann common: fftlib - ensure buffer alignment
timblechmann authored
36 #include "../server/supernova/utilities/malloc_aligned.hpp"
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
37
a162233 @timblechmann fftlib: make use of nova.simd
timblechmann authored
38 #ifdef NOVA_SIMD
39 #include "simd_binary_arithmetic.hpp"
40 #endif
41
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
42
43 // We include vDSP even if not using for FFT, since we want to use some vectorised add/mul tricks
30f2ecf Fixed iOS XCode project compilation
Axel Balley authored
44 #if defined(__APPLE__) && !defined(SC_IPHONE)
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
45 #include "vecLib/vDSP.h"
e3e4a44 Fixed iOS projects, now using Accelerate framework for FFT
Axel Balley authored
46 #elif defined(SC_IPHONE)
47 #include <Accelerate/Accelerate.h>
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
48 #endif
49
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
50 ////////////////////////////////////////////////////////////////////////////////////////////////////
51 // Constants and structs
52
53 // Decisions here about which FFT library to use - vDSP only exists on Mac BTW.
54 // We include the relevant libs but also ensure that one, and only one, of them is active...
55 #if SC_FFT_NONE
56 // "SC_FFT_NONE" allows compilation without FFT support; only expected to be used on very limited platforms
57 #define SC_FFT_FFTW 0
58 #define SC_FFT_VDSP 0
59 #define SC_FFT_GREEN 0
60 #elif SC_FFT_GREEN
61 #define SC_FFT_FFTW 0
62 #define SC_FFT_VDSP 0
63 #define SC_FFT_GREEN 1
c37cc19 @timblechmann fftlib: supernova does not require fftw
timblechmann authored
64 #elif !SC_FFT_FFTW && defined(__APPLE__)
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
65 #define SC_FFT_FFTW 0
66 #define SC_FFT_VDSP 1
67 #define SC_FFT_GREEN 0
68 #else
69 //#elif SC_FFT_FFTW
70 #define SC_FFT_FFTW 1
71 #define SC_FFT_VDSP 0
72 #define SC_FFT_GREEN 0
73 #include <fftw3.h>
74 #endif
75
76 // Note that things like *fftWindow actually allow for other sizes, to be created on user request.
77 #define SC_FFT_ABSOLUTE_MAXSIZE 2147483648
78 #define SC_FFT_LOG2_ABSOLUTE_MAXSIZE 31
79 #define SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1 32
80
81 // This struct is a bit like FFTW's idea of a "plan": it represents an FFT operation that may be applied once or repeatedly.
82 // It should be possible for indata and outdata to be the same, for quasi-in-place operation.
83 typedef struct scfft {
84 unsigned int nfull, nwin, log2nfull, log2nwin; // Lengths of full FFT frame, and the (possibly shorter) windowed data frame
85 short wintype;
86 float *indata, *outdata, *trbuf;
87 float scalefac; // Used to rescale the data to unity gain
88 } scfft;
89
90
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
91 static float *fftWindow[2][SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1];
92
93 #if SC_FFT_VDSP
94 static FFTSetup fftSetup[SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1]; // vDSP setups, one per FFT size
95 static COMPLEX_SPLIT splitBuf; // Temp buf for holding rearranged data
96 #endif
97
b1ebb5e @danstowell un-deprecate scsynth ability to use internal Green FFT lib
danstowell authored
98 #if SC_FFT_GREEN
99 extern "C" {
100 #include "fftlib.h"
101 static float *cosTable[SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1];
102 }
103 #endif
104
4d1d1e6 @timblechmann fft lib: adapt fftw code to make use of the new-array API of 3.3
timblechmann authored
105 #if SC_FFT_FFTW
106 static fftwf_plan precompiledForwardPlans[SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1];
107 static fftwf_plan precompiledBackwardPlans[SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1];
108 static fftwf_plan precompiledForwardPlansInPlace[SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1];
109 static fftwf_plan precompiledBackwardPlansInPlace[SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1];
110 #endif
111
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
112 #define pi 3.1415926535898f
d769495 remove trailing whitespaces
Tim Blechmann authored
113 #define twopi 6.28318530717952646f
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
114
115 ////////////////////////////////////////////////////////////////////////////////////////////////////
116 // Functions
117
b1ebb5e @danstowell un-deprecate scsynth ability to use internal Green FFT lib
danstowell authored
118 #if SC_FFT_GREEN
119 static float* create_cosTable(int log2n);
120 static float* create_cosTable(int log2n)
121 {
122 int size = 1 << log2n;
123 int size2 = size / 4 + 1;
702d1c3 @timblechmann common: fftlib - ensure buffer alignment
timblechmann authored
124 float *win = (float*)malloc_aligned(size2 * sizeof(float));
125 if (win == NULL)
126 return NULL;
127
b1ebb5e @danstowell un-deprecate scsynth ability to use internal Green FFT lib
danstowell authored
128 double winc = twopi / size;
129 for (int i=0; i<size2; ++i) {
130 double w = i * winc;
131 win[i] = cos(w);
132 }
133 return win;
134 }
135 #endif
136
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
137 static float* scfft_create_fftwindow(int wintype, int log2n)
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
138 {
139 int size = 1 << log2n;
140 unsigned short i;
702d1c3 @timblechmann common: fftlib - ensure buffer alignment
timblechmann authored
141
142 float * win = (float*)nova::malloc_aligned(size * sizeof(float));
143
144 if (!win) return NULL;
145
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
146 double winc;
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
147 switch(wintype) {
148 case kSineWindow:
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
149 winc = pi / size;
150 for (i=0; i<size; ++i) {
151 double w = i * winc;
152 win[i] = sin(w);
153 }
154 break;
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
155 case kHannWindow:
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
156 winc = twopi / size;
157 for (i=0; i<size; ++i) {
158 double w = i * winc;
159 win[i] = 0.5 - 0.5 * cos(w);
160 }
161 break;
162 }
d769495 remove trailing whitespaces
Tim Blechmann authored
163
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
164 return win;
165 }
166
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
167 static void scfft_ensurewindow(unsigned short log2_fullsize, unsigned short log2_winsize, short wintype);
168
169 static bool scfft_global_initialization (void)
170 {
171 for (int wintype=0; wintype<2; ++wintype) {
172 for (int i=0; i< SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1; ++i) {
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
173 fftWindow[wintype][i] = 0;
174 }
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
175 for (int i= SC_FFT_LOG2_MINSIZE; i < SC_FFT_LOG2_MAXSIZE+1; ++i) {
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
176 fftWindow[wintype][i] = scfft_create_fftwindow(wintype, i);
177 }
178 }
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
179 #if SC_FFT_GREEN
180 for (int i=0; i< SC_FFT_LOG2_ABSOLUTE_MAXSIZE_PLUS1; ++i) {
181 cosTable[i] = 0;
182 }
183 for (int i= SC_FFT_LOG2_MINSIZE; i < SC_FFT_LOG2_MAXSIZE+1; ++i) {
184 cosTable[i] = create_cosTable(i);
185 }
186 printf("SC FFT global init: cosTable initialised.\n");
187 #elif SC_FFT_VDSP
188 // vDSP inits its twiddle factors
189 for (int i= SC_FFT_LOG2_MINSIZE; i < SC_FFT_LOG2_MAXSIZE+1; ++i) {
190 fftSetup[i] = vDSP_create_fftsetup (i, FFT_RADIX2);
191 if(fftSetup[i] == NULL){
192 printf("FFT ERROR: Mac vDSP library could not allocate FFT setup for size %i\n", 1<<i);
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
193 }
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
194 }
195 // vDSP prepares its memory-aligned buffer for rearranging input data.
196 // Note max size here - meaning max input buffer size is these two sizes added together.
197 // vec_malloc used in API docs, but apparently that's deprecated and malloc is sufficient for aligned memory on OSX.
198 splitBuf.realp = (float*) malloc ( SC_FFT_MAXSIZE * sizeof(float) / 2);
199 splitBuf.imagp = (float*) malloc ( SC_FFT_MAXSIZE * sizeof(float) / 2);
200 //printf("SC FFT global init: vDSP initialised.\n");
201 #elif SC_FFT_FFTW
4d1d1e6 @timblechmann fft lib: adapt fftw code to make use of the new-array API of 3.3
timblechmann authored
202 size_t maxSize = 1<<SC_FFT_LOG2_MAXSIZE;
203 float * buffer1 = (float*)fftwf_malloc((maxSize + 1) * sizeof(float));
204 float * buffer2 = (float*)fftwf_malloc((maxSize + 1) * sizeof(float));
205 for (int i= SC_FFT_LOG2_MINSIZE; i < SC_FFT_LOG2_MAXSIZE+1; ++i) {
206 size_t currentSize = 1<<i;
207
208 precompiledForwardPlans[i] = fftwf_plan_dft_r2c_1d(currentSize, buffer1, (fftwf_complex*) buffer2, FFTW_ESTIMATE);
209 precompiledBackwardPlans[i] = fftwf_plan_dft_c2r_1d(currentSize, (fftwf_complex*) buffer2, buffer1, FFTW_ESTIMATE);
210
211 precompiledForwardPlansInPlace[i] = fftwf_plan_dft_r2c_1d(currentSize, buffer1, (fftwf_complex*) buffer1, FFTW_ESTIMATE);
212 precompiledBackwardPlansInPlace[i] = fftwf_plan_dft_c2r_1d(currentSize, (fftwf_complex*) buffer1, buffer1, FFTW_ESTIMATE);
213 }
214 fftwf_free(buffer1);
215 fftwf_free(buffer2);
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
216 #endif
217 return false;
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
218 }
219
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
220 static bool dummy = scfft_global_initialization();
221
222 // You need to provide an intermediate "transform buffer". Size will depend on which underlying lib is being used.
223 // "fullsize" is the number of samples in the input buffer (inc any padding), aka the number of "points" in the FFT.
224 // Often in an SC plugin you can get this number from buf->samples if you're grabbing an external buffer.
225 // The input value is given in samples.
226 // The return value is given in bytes.
227 static size_t scfft_trbufsize(unsigned int fullsize)
228 {
229 #if SC_FFT_FFTW
230 // Transform buf is two floats "too big" because of FFTWF's output ordering
231 return (fullsize+2) * sizeof(float);
232 #else
233 // vDSP packs the nyquist in with the DC, so size is same as input buffer (plus zeropadding)
234 // Green does this too
235 return (fullsize ) * sizeof(float);
236 #endif
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
237 }
238
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
239
240 scfft * scfft_create(size_t fullsize, size_t winsize, SCFFT_WindowFunction wintype,
241 float *indata, float *outdata, SCFFT_Direction forward, SCFFT_Allocator & alloc)
242 {
702d1c3 @timblechmann common: fftlib - ensure buffer alignment
timblechmann authored
243 const int alignment = 128; // in bytes
244 char * chunk = (char*) alloc.alloc(sizeof(scfft) + scfft_trbufsize(fullsize) + alignment);
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
245 if (!chunk)
246 return NULL;
247
248 scfft * f = (scfft*)chunk;
249 float *trbuf = (float*)(chunk + sizeof(scfft));
702d1c3 @timblechmann common: fftlib - ensure buffer alignment
timblechmann authored
250 trbuf = (float*) ((intptr_t)((char*)trbuf + (alignment - 1)) & -alignment);
251
252 assert(nova::vec<float>::is_aligned(trbuf));
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
253
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
254 f->nfull = fullsize;
255 f->nwin = winsize;
256 f->log2nfull = LOG2CEIL(fullsize);
257 f->log2nwin = LOG2CEIL( winsize);
258 f->wintype = wintype;
259 f->indata = indata;
260 f->outdata = outdata;
261 f->trbuf = trbuf;
d769495 remove trailing whitespaces
Tim Blechmann authored
262
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
263 // Buffer is larger than the range of sizes we provide for at startup; we can get ready just-in-time though
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
264 if (fullsize > SC_FFT_MAXSIZE)
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
265 scfft_ensurewindow(f->log2nfull, f->log2nwin, wintype);
d769495 remove trailing whitespaces
Tim Blechmann authored
266
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
267 // The scale factors rescale the data to unity gain. The old Green lib did this itself, meaning scalefacs would here be 1...
702d1c3 @timblechmann common: fftlib - ensure buffer alignment
timblechmann authored
268 if (forward) {
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
269 #if SC_FFT_VDSP
270 f->scalefac = 0.5f;
271 #else // forward FFTW and Green factor
272 f->scalefac = 1.f;
273 #endif
274 } else { // backward FFTW and VDSP factor
275 #if SC_FFT_GREEN
276 f->scalefac = 1.f;
277 #else // fftw, vdsp
278 f->scalefac = 1.f / fullsize;
279 #endif
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
280 }
d769495 remove trailing whitespaces
Tim Blechmann authored
281
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
282 memset(trbuf, 0, scfft_trbufsize(fullsize));
d769495 remove trailing whitespaces
Tim Blechmann authored
283
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
284 return f;
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
285 }
286
287 static int largest_log2n = SC_FFT_LOG2_MAXSIZE;
d769495 remove trailing whitespaces
Tim Blechmann authored
288
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
289 // check the global list of windows incs ours; create if not.
290 // Note that expanding the table, if triggered, will cause a CPU hit as things are malloc'ed, realloc'ed, etc.
291 void scfft_ensurewindow(unsigned short log2_fullsize, unsigned short log2_winsize, short wintype)
292 {
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
293 // Ensure we have enough space to do our calcs
294 if(log2_fullsize > largest_log2n){
295 largest_log2n = log2_fullsize;
702d1c3 @timblechmann common: fftlib - ensure buffer alignment
timblechmann authored
296 #if SC_FFT_VDSP
297 size_t newsize = (1 << largest_log2n) * sizeof(float) / 2;
298 splitBuf.realp = (float*) realloc (splitBuf.realp, newsize);
299 splitBuf.imagp = (float*) realloc (splitBuf.imagp, newsize);
300 #endif
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
301 }
d769495 remove trailing whitespaces
Tim Blechmann authored
302
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
303 // Ensure our window has been created
304 if((wintype != -1) && (fftWindow[wintype][log2_winsize] == 0)){
305 fftWindow[wintype][log2_winsize] = scfft_create_fftwindow(wintype, log2_winsize);
306 }
d769495 remove trailing whitespaces
Tim Blechmann authored
307
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
308 // Ensure our FFT twiddle factors (or whatever) have been created
4d1d1e6 @timblechmann fft lib: adapt fftw code to make use of the new-array API of 3.3
timblechmann authored
309 #if SC_FFT_VDSP
310 if(fftSetup[log2_fullsize] == 0)
311 fftSetup[log2_fullsize] = vDSP_create_fftsetup (log2_fullsize, FFT_RADIX2);
312 #elif SC_FFT_GREEN
313 if(cosTable[log2_fullsize] == 0)
314 cosTable[log2_fullsize] = create_cosTable(log2_fullsize);
315 #endif
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
316 }
317
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
318 // these do the main jobs.
319 // Note: you DON"T need to call the windowing function yourself, it'll be applied by the _dofft and _doifft funcs.
320 static void scfft_dowindowing(float *data, unsigned int winsize, unsigned int fullsize, unsigned short log2_winsize,
321 short wintype, float scalefac)
322 {
323 if (wintype != kRectWindow) {
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
324 float *win = fftWindow[wintype][log2_winsize];
325 if (!win) return;
a162233 @timblechmann fftlib: make use of nova.simd
timblechmann authored
326 #if SC_FFT_VDSP
327 vDSP_vmul(data, 1, win, 1, data, 1, winsize);
328 #elif defined (NOVA_SIMD)
329 using namespace nova;
8664d1d @timblechmann common: fix nova-simd code selection in fftlib
timblechmann authored
330 if (((vec<float>::objects_per_cacheline & winsize) == 0) && vec<float>::is_aligned(data))
a162233 @timblechmann fftlib: make use of nova.simd
timblechmann authored
331 times_vec_simd(data, data, win, winsize);
332 else
333 times_vec(data, data, win, winsize);
334 #else
335 --win;
336 float *in = data - 1;
337 for (int i=0; i< winsize ; ++i) {
338 *++in *= *++win;
339 }
340 #endif
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
341 }
d77ba22 fixed scale factor for rectnagular window in SC_fftlib and Convolution
Nick Collins authored
342
4d1d1e6 @timblechmann fft lib: adapt fftw code to make use of the new-array API of 3.3
timblechmann authored
343 // scale factor is different for different libs. But the compiler switch here is about using vDSP's fast multiplication method.
344 #if SC_FFT_VDSP
345 vDSP_vsmul(data, 1, &scalefac, data, 1, winsize);
346 #else
347 for(int i=0; i<winsize; ++i){
348 data[i] *= scalefac;
349 }
350 #endif
d77ba22 fixed scale factor for rectnagular window in SC_fftlib and Convolution
Nick Collins authored
351
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
352 // Zero-padding:
353 memset(data + winsize, 0, (fullsize - winsize) * sizeof(float));
354 }
355
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
356 void scfft_dofft(scfft * f)
357 {
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
358 // Data goes to transform buf
359 memcpy(f->trbuf, f->indata, f->nwin * sizeof(float));
f53708a @danstowell Fix bug in FFT library if winsize != audiosize
danstowell authored
360 scfft_dowindowing(f->trbuf, f->nwin, f->nfull, f->log2nwin, f->wintype, f->scalefac);
4d1d1e6 @timblechmann fft lib: adapt fftw code to make use of the new-array API of 3.3
timblechmann authored
361 #if SC_FFT_FFTW
362 // forward transformation is in-place
363 fftwf_execute_dft_r2c(precompiledForwardPlansInPlace[f->log2nfull], f->trbuf, (fftwf_complex*)f->trbuf);
364
365 // Rearrange output data onto public buffer
366 memcpy(f->outdata, f->trbuf, f->nfull * sizeof(float));
367 f->outdata[1] = f->trbuf[f->nfull]; // Pack nyquist val in
368 #elif SC_FFT_VDSP
369 // Perform even-odd split
370 vDSP_ctoz((COMPLEX*) f->trbuf, 2, &splitBuf, 1, f->nfull >> 1);
371 // Now the actual FFT
372 vDSP_fft_zrip(fftSetup[f->log2nfull], &splitBuf, 1, f->log2nfull, FFT_FORWARD);
373 // Copy the data to the public output buf, transforming it back out of "split" representation
374 vDSP_ztoc(&splitBuf, 1, (DSPComplex*) f->outdata, 2, f->nfull >> 1);
375 #elif SC_FFT_GREEN
376 // Green FFT is in-place
377 rffts(f->trbuf, f->log2nfull, 1, cosTable[f->log2nfull]);
378 // Copy to public buffer
379 memcpy(f->outdata, f->trbuf, f->nfull * sizeof(float));
380 #endif
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
381 }
382
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
383 void scfft_doifft(scfft * f)
384 {
4d1d1e6 @timblechmann fft lib: adapt fftw code to make use of the new-array API of 3.3
timblechmann authored
385 #if SC_FFT_FFTW
386 float *trbuf = f->trbuf;
387 size_t bytesize = f->nfull * sizeof(float);
388 memcpy(trbuf, f->indata, bytesize);
389 trbuf[1] = 0.f;
390 trbuf[f->nfull] = f->indata[1]; // Nyquist goes all the way down to the end of the line...
391 trbuf[f->nfull+1] = 0.f;
392
393 fftwf_execute_dft_c2r(precompiledBackwardPlans[f->log2nfull], (fftwf_complex*)trbuf, f->outdata);
394
395 #elif SC_FFT_VDSP
396 vDSP_ctoz((COMPLEX*) f->indata, 2, &splitBuf, 1, f->nfull >> 1);
397 vDSP_fft_zrip(fftSetup[f->log2nfull], &splitBuf, 1, f->log2nfull, FFT_INVERSE);
398 vDSP_ztoc(&splitBuf, 1, (DSPComplex*) f->outdata, 2, f->nfull >> 1);
399 #elif SC_FFT_GREEN
400 float *trbuf = f->trbuf;
401 size_t bytesize = f->nfull * sizeof(float);
402 memcpy(trbuf, f->indata, bytesize);
403 // Green FFT is in-place
404 riffts(trbuf, f->log2nfull, 1, cosTable[f->log2nfull]);
405 // Copy to public buffer
406 memcpy(f->outdata, trbuf, f->nwin * sizeof(float));
407 #endif
f53708a @danstowell Fix bug in FFT library if winsize != audiosize
danstowell authored
408 scfft_dowindowing(f->outdata, f->nwin, f->nfull, f->log2nwin, f->wintype, f->scalefac);
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
409 }
410
7ee9cd8 @timblechmann fftlib: expose fft functionality through the interface table
timblechmann authored
411 void scfft_destroy(scfft *f, SCFFT_Allocator & alloc)
412 {
413 alloc.free(f);
a995e79 @danstowell FFT and IFFT refactoring into separate lib "SC_fftlib". (I haven't yet u...
danstowell authored
414 }
Something went wrong with that request. Please try again.