2 ZynAddSubFX - a software synthesizer
4 FFTwrapper.c - A wrapper for Fast Fourier Transforms
5 Copyright (C) 2002-2005 Nasca Octavian Paul
6 Author: Nasca Octavian Paul
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of version 2 of the GNU General Public License
10 as published by the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License (version 2) for more details.
17 You should have received a copy of the GNU General Public License (version 2)
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 /* If you got error messages about rfftw.h, replace the next include line with "#include <srfftw.h>"
29 or with "#include <drfftw.h> (if one doesn't work try the other). It may be necessary to replace
30 the <fftw.h> with <dfftw.h> or <sfftw.h>. If the neither one doesn't work,
31 please install latest version of fftw(recomanded from the sources) from www.fftw.org.
32 If you'll install fftw3 you need to change the Makefile.inc
33 Hope all goes right." */
37 # define fftw_real double
38 # define rfftw_plan fftw_plan
46 fftw_real
* tmp_data1
;
47 fftw_real
* tmp_data2
;
56 struct zyn_fft
* fft_ptr
;
58 fft_ptr
= malloc(sizeof(struct zyn_fft
));
60 fft_ptr
->size
= fftsize
;
62 fft_ptr
->tmp_data1
= malloc(sizeof(fftw_real
) * fftsize
);
63 fft_ptr
->tmp_data2
= malloc(sizeof(fftw_real
) * fftsize
);
66 fft_ptr
->plan
= rfftw_create_plan(fftsize
, FFTW_REAL_TO_COMPLEX
, FFTW_ESTIMATE
| FFTW_IN_PLACE
);
67 fft_ptr
->plan_inv
= rfftw_create_plan(fftsize
, FFTW_COMPLEX_TO_REAL
, FFTW_ESTIMATE
| FFTW_IN_PLACE
);
69 fft_ptr
->plan
= fftw_plan_r2r_1d(fftsize
, fft_ptr
->tmp_data1
, fft_ptr
->tmp_data1
, FFTW_R2HC
, FFTW_ESTIMATE
);
70 fft_ptr
->plan_inv
= fftw_plan_r2r_1d(fftsize
, fft_ptr
->tmp_data2
, fft_ptr
->tmp_data2
, FFTW_HC2R
, FFTW_ESTIMATE
);
73 return (zyn_fft_handle
)fft_ptr
;
76 #define fft_ptr ((struct zyn_fft *)handle)
80 zyn_fft_handle handle
)
83 rfftw_destroy_plan(fft_ptr
->plan
);
84 rfftw_destroy_plan(fft_ptr
->plan_inv
);
86 fftw_destroy_plan(fft_ptr
->plan
);
87 fftw_destroy_plan(fft_ptr
->plan_inv
);
90 free(fft_ptr
->tmp_data1
);
91 free(fft_ptr
->tmp_data2
);
95 * do the Fast Fourier Transform
99 zyn_fft_handle handle
,
101 struct zyn_fft_freqs
* freqs_ptr
)
104 fftw_real
* tmp_data_ptr
;
106 for (i
= 0 ; i
< fft_ptr
->size
; i
++)
108 fft_ptr
->tmp_data1
[i
] = smps
[i
];
111 #ifdef FFTW_VERSION_2
112 rfftw_one(fft_ptr
->plan
, fft_ptr
->tmp_data1
, fft_ptr
->tmp_data2
);
113 tmp_data_ptr
= fft_ptr
->tmp_data2
;
115 fftw_execute(fft_ptr
->plan
);
116 tmp_data_ptr
= fft_ptr
->tmp_data1
;
119 for (i
= 0 ; i
< fft_ptr
->size
/ 2 ; i
++)
121 freqs_ptr
->c
[i
] = tmp_data_ptr
[i
];
124 freqs_ptr
->s
[i
] = tmp_data_ptr
[fft_ptr
->size
- i
];
128 fft_ptr
->tmp_data2
[fft_ptr
->size
/ 2] = 0.0;
132 * do the Inverse Fast Fourier Transform
136 zyn_fft_handle handle
,
137 struct zyn_fft_freqs
* freqs_ptr
,
141 fftw_real
* tmp_data_ptr
;
143 fft_ptr
->tmp_data2
[fft_ptr
->size
/ 2] = 0.0;
145 #ifdef FFTW_VERSION_2
146 tmp_data_ptr
= fft_ptr
->tmp_data1
;
148 tmp_data_ptr
= fft_ptr
->tmp_data2
;
151 for (i
= 0 ; i
< fft_ptr
->size
/ 2 ; i
++)
153 tmp_data_ptr
[i
] = freqs_ptr
->c
[i
];
156 tmp_data_ptr
[fft_ptr
->size
- i
] = freqs_ptr
->s
[i
];
160 #ifdef FFTW_VERSION_2
161 rfftw_one(fft_ptr
->plan_inv
, fft_ptr
->tmp_data1
, fft_ptr
->tmp_data2
);
163 fftw_execute(fft_ptr
->plan_inv
);
166 for (i
= 0 ; i
< fft_ptr
->size
; i
++)
168 smps
[i
] = fft_ptr
->tmp_data2
[i
];
174 struct zyn_fft_freqs
* f
,
177 f
->c
= malloc(size
* sizeof(zyn_sample_type
));
178 f
->s
= malloc(size
* sizeof(zyn_sample_type
));
180 silence_two_buffers(f
->c
, f
->s
, size
);
184 zyn_fft_freqs_uninit(
185 struct zyn_fft_freqs
* f
)