1
/* Copyright (C) 2005-2006 Jean-Marc Valin
4
Wrapper for various FFTs
6
Redistribution and use in source and binary forms, with or without
7
modification, are permitted provided that the following conditions
10
- Redistributions of source code must retain the above copyright
11
notice, this list of conditions and the following disclaimer.
13
- Redistributions in binary form must reproduce the above copyright
14
notice, this list of conditions and the following disclaimer in the
15
documentation and/or other materials provided with the distribution.
17
- Neither the name of the Xiph.org Foundation nor the names of its
18
contributors may be used to endorse or promote products derived from
19
this software without specific prior written permission.
21
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40
#include "os_support.h"
42
#define MAX_FFT_SIZE 2048
45
static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len)
48
spx_word16_t max_val = 0;
57
while (max_val <= (bound>>1) && max_val != 0)
64
out[i] = SHL16(in[i], shift);
69
static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len)
74
out[i] = PSHR16(in[i], shift);
84
void *spx_fft_init(int size)
86
struct drft_lookup *table;
87
table = speex_alloc(sizeof(struct drft_lookup));
88
spx_drft_init((struct drft_lookup *)table, size);
92
void spx_fft_destroy(void *table)
94
spx_drft_clear(table);
98
void spx_fft(void *table, float *in, float *out)
103
float scale = 1./((struct drft_lookup *)table)->n;
104
speex_warning("FFT should not be done in-place");
105
for (i=0;i<((struct drft_lookup *)table)->n;i++)
106
out[i] = scale*in[i];
109
float scale = 1./((struct drft_lookup *)table)->n;
110
for (i=0;i<((struct drft_lookup *)table)->n;i++)
111
out[i] = scale*in[i];
113
spx_drft_forward((struct drft_lookup *)table, out);
116
void spx_ifft(void *table, float *in, float *out)
120
speex_warning("FFT should not be done in-place");
123
for (i=0;i<((struct drft_lookup *)table)->n;i++)
126
spx_drft_backward((struct drft_lookup *)table, out);
129
#elif defined(USE_INTEL_MKL)
133
DFTI_DESCRIPTOR_HANDLE desc;
137
void *spx_fft_init(int size)
139
struct mkl_config *table = (struct mkl_config *) speex_alloc(sizeof(struct mkl_config));
141
DftiCreateDescriptor(&table->desc, DFTI_SINGLE, DFTI_REAL, 1, size);
142
DftiSetValue(table->desc, DFTI_PACKED_FORMAT, DFTI_PACK_FORMAT);
143
DftiSetValue(table->desc, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
144
DftiSetValue(table->desc, DFTI_FORWARD_SCALE, 1.0f / size);
145
DftiCommitDescriptor(table->desc);
149
void spx_fft_destroy(void *table)
151
struct mkl_config *t = (struct mkl_config *) table;
152
DftiFreeDescriptor(t->desc);
156
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
158
struct mkl_config *t = (struct mkl_config *) table;
159
DftiComputeForward(t->desc, in, out);
162
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
164
struct mkl_config *t = (struct mkl_config *) table;
165
DftiComputeBackward(t->desc, in, out);
168
#elif defined(USE_GPL_FFTW3)
180
void *spx_fft_init(int size)
182
struct fftw_config *table = (struct fftw_config *) speex_alloc(sizeof(struct fftw_config));
183
table->in = fftwf_malloc(sizeof(float) * (size+2));
184
table->out = fftwf_malloc(sizeof(float) * (size+2));
186
table->fft = fftwf_plan_dft_r2c_1d(size, table->in, (fftwf_complex *) table->out, FFTW_PATIENT);
187
table->ifft = fftwf_plan_dft_c2r_1d(size, (fftwf_complex *) table->in, table->out, FFTW_PATIENT);
193
void spx_fft_destroy(void *table)
195
struct fftw_config *t = (struct fftw_config *) table;
196
fftwf_destroy_plan(t->fft);
197
fftwf_destroy_plan(t->ifft);
204
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
207
struct fftw_config *t = (struct fftw_config *) table;
210
float *optr = t->out;
211
const float m = 1.0 / N;
215
fftwf_execute(t->fft);
222
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
225
struct fftw_config *t = (struct fftw_config *) table;
228
float *optr = t->out;
236
fftwf_execute(t->ifft);
242
#elif defined(USE_KISS_FFT)
244
#include "kiss_fftr.h"
245
#include "kiss_fft.h"
248
kiss_fftr_cfg forward;
249
kiss_fftr_cfg backward;
253
void *spx_fft_init(int size)
255
struct kiss_config *table;
256
table = (struct kiss_config*)speex_alloc(sizeof(struct kiss_config));
257
table->forward = kiss_fftr_alloc(size,0,NULL,NULL);
258
table->backward = kiss_fftr_alloc(size,1,NULL,NULL);
263
void spx_fft_destroy(void *table)
265
struct kiss_config *t = (struct kiss_config *)table;
266
kiss_fftr_free(t->forward);
267
kiss_fftr_free(t->backward);
273
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
276
struct kiss_config *t = (struct kiss_config *)table;
277
shift = maximize_range(in, in, 32000, t->N);
278
kiss_fftr2(t->forward, in, out);
279
renorm_range(in, in, shift, t->N);
280
renorm_range(out, out, shift, t->N);
285
void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
289
struct kiss_config *t = (struct kiss_config *)table;
291
kiss_fftr2(t->forward, in, out);
297
void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out)
299
struct kiss_config *t = (struct kiss_config *)table;
300
kiss_fftri2(t->backward, in, out);
306
#error No other FFT implemented
312
/*#include "smallft.h"*/
315
void spx_fft_float(void *table, float *in, float *out)
319
int N = ((struct drft_lookup *)table)->n;
320
#elif defined(USE_KISS_FFT)
321
int N = ((struct kiss_config *)table)->N;
326
spx_word16_t _out[N];
328
spx_word16_t _in[MAX_FFT_SIZE];
329
spx_word16_t _out[MAX_FFT_SIZE];
332
_in[i] = (int)floor(.5+in[i]);
333
spx_fft(table, _in, _out);
340
struct drft_lookup t;
341
spx_drft_init(&t, ((struct kiss_config *)table)->N);
342
scale = 1./((struct kiss_config *)table)->N;
343
for (i=0;i<((struct kiss_config *)table)->N;i++)
344
out[i] = scale*in[i];
345
spx_drft_forward(&t, out);
351
void spx_ifft_float(void *table, float *in, float *out)
355
int N = ((struct drft_lookup *)table)->n;
356
#elif defined(USE_KISS_FFT)
357
int N = ((struct kiss_config *)table)->N;
362
spx_word16_t _out[N];
364
spx_word16_t _in[MAX_FFT_SIZE];
365
spx_word16_t _out[MAX_FFT_SIZE];
368
_in[i] = (int)floor(.5+in[i]);
369
spx_ifft(table, _in, _out);
376
struct drft_lookup t;
377
spx_drft_init(&t, ((struct kiss_config *)table)->N);
378
for (i=0;i<((struct kiss_config *)table)->N;i++)
380
spx_drft_backward(&t, out);
388
void spx_fft_float(void *table, float *in, float *out)
390
spx_fft(table, in, out);
392
void spx_ifft_float(void *table, float *in, float *out)
394
spx_ifft(table, in, out);