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.
36 #include "config-speex.h"
39 /*#define USE_SMALLFT*/
44 #include "os_support.h"
46 #define MAX_FFT_SIZE 2048
49 static int maximize_range(spx_word16_t
*in
, spx_word16_t
*out
, spx_word16_t bound
, int len
)
52 spx_word16_t max_val
= 0;
61 while (max_val
<= (bound
>>1) && max_val
!= 0)
68 out
[i
] = SHL16(in
[i
], shift
);
73 static void renorm_range(spx_word16_t
*in
, spx_word16_t
*out
, int shift
, int len
)
78 out
[i
] = PSHR16(in
[i
], shift
);
88 void *spx_fft_init(int size
)
90 struct drft_lookup
*table
;
91 table
= speex_alloc(sizeof(struct drft_lookup
));
92 spx_drft_init((struct drft_lookup
*)table
, size
);
96 void spx_fft_destroy(void *table
)
98 spx_drft_clear(table
);
102 void spx_fft(void *table
, float *in
, float *out
)
107 float scale
= 1./((struct drft_lookup
*)table
)->n
;
108 speex_warning("FFT should not be done in-place");
109 for (i
=0;i
<((struct drft_lookup
*)table
)->n
;i
++)
110 out
[i
] = scale
*in
[i
];
113 float scale
= 1./((struct drft_lookup
*)table
)->n
;
114 for (i
=0;i
<((struct drft_lookup
*)table
)->n
;i
++)
115 out
[i
] = scale
*in
[i
];
117 spx_drft_forward((struct drft_lookup
*)table
, out
);
120 void spx_ifft(void *table
, float *in
, float *out
)
124 speex_warning("FFT should not be done in-place");
127 for (i
=0;i
<((struct drft_lookup
*)table
)->n
;i
++)
130 spx_drft_backward((struct drft_lookup
*)table
, out
);
133 #elif defined(USE_KISS_FFT)
135 #include "kiss_fftr.h"
136 #include "kiss_fft.h"
139 kiss_fftr_cfg forward
;
140 kiss_fftr_cfg backward
;
144 void *spx_fft_init(int size
)
146 struct kiss_config
*table
;
147 table
= (struct kiss_config
*)speex_alloc(sizeof(struct kiss_config
));
148 table
->forward
= kiss_fftr_alloc(size
,0,NULL
,NULL
);
149 table
->backward
= kiss_fftr_alloc(size
,1,NULL
,NULL
);
154 void spx_fft_destroy(void *table
)
156 struct kiss_config
*t
= (struct kiss_config
*)table
;
157 kiss_fftr_free(t
->forward
);
158 kiss_fftr_free(t
->backward
);
164 void spx_fft(void *table
, spx_word16_t
*in
, spx_word16_t
*out
)
167 struct kiss_config
*t
= (struct kiss_config
*)table
;
168 shift
= maximize_range(in
, in
, 32000, t
->N
);
169 kiss_fftr2(t
->forward
, in
, out
);
170 renorm_range(in
, in
, shift
, t
->N
);
171 renorm_range(out
, out
, shift
, t
->N
);
176 void spx_fft(void *table
, spx_word16_t
*in
, spx_word16_t
*out
)
180 struct kiss_config
*t
= (struct kiss_config
*)table
;
182 kiss_fftr2(t
->forward
, in
, out
);
188 void spx_ifft(void *table
, spx_word16_t
*in
, spx_word16_t
*out
)
190 struct kiss_config
*t
= (struct kiss_config
*)table
;
191 kiss_fftri2(t
->backward
, in
, out
);
197 #error No other FFT implemented
203 /*#include "smallft.h"*/
206 void spx_fft_float(void *table
, float *in
, float *out
)
210 int N
= ((struct drft_lookup
*)table
)->n
;
211 #elif defined(USE_KISS_FFT)
212 int N
= ((struct kiss_config
*)table
)->N
;
217 spx_word16_t _out
[N
];
219 spx_word16_t _in
[MAX_FFT_SIZE
];
220 spx_word16_t _out
[MAX_FFT_SIZE
];
223 _in
[i
] = (int)floor(.5+in
[i
]);
224 spx_fft(table
, _in
, _out
);
231 struct drft_lookup t
;
232 spx_drft_init(&t
, ((struct kiss_config
*)table
)->N
);
233 scale
= 1./((struct kiss_config
*)table
)->N
;
234 for (i
=0;i
<((struct kiss_config
*)table
)->N
;i
++)
235 out
[i
] = scale
*in
[i
];
236 spx_drft_forward(&t
, out
);
242 void spx_ifft_float(void *table
, float *in
, float *out
)
246 int N
= ((struct drft_lookup
*)table
)->n
;
247 #elif defined(USE_KISS_FFT)
248 int N
= ((struct kiss_config
*)table
)->N
;
253 spx_word16_t _out
[N
];
255 spx_word16_t _in
[MAX_FFT_SIZE
];
256 spx_word16_t _out
[MAX_FFT_SIZE
];
259 _in
[i
] = (int)floor(.5+in
[i
]);
260 spx_ifft(table
, _in
, _out
);
267 struct drft_lookup t
;
268 spx_drft_init(&t
, ((struct kiss_config
*)table
)->N
);
269 for (i
=0;i
<((struct kiss_config
*)table
)->N
;i
++)
271 spx_drft_backward(&t
, out
);
279 void spx_fft_float(void *table
, float *in
, float *out
)
281 spx_fft(table
, in
, out
);
283 void spx_ifft_float(void *table
, float *in
, float *out
)
285 spx_ifft(table
, in
, out
);