* Onda VX747: add browse screen, pitchscreen, context menu, quickscreen, rewind...
[kugel-rb.git] / apps / codecs / libspeex / fftwrap.c
blob2312f755d64081d20e0045c81c2189823eaab189
1 /* Copyright (C) 2005-2006 Jean-Marc Valin
2 File: fftwrap.c
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
8 are met:
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.
35 #ifdef HAVE_CONFIG_H
36 #include "config-speex.h"
37 #endif
39 /*#define USE_SMALLFT*/
40 #define USE_KISS_FFT
43 #include "arch.h"
44 #include "os_support.h"
46 #define MAX_FFT_SIZE 2048
48 #ifdef FIXED_POINT
49 static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len)
51 int i, shift;
52 spx_word16_t max_val = 0;
53 for (i=0;i<len;i++)
55 if (in[i]>max_val)
56 max_val = in[i];
57 if (-in[i]>max_val)
58 max_val = -in[i];
60 shift=0;
61 while (max_val <= (bound>>1) && max_val != 0)
63 max_val <<= 1;
64 shift++;
66 for (i=0;i<len;i++)
68 out[i] = SHL16(in[i], shift);
70 return shift;
73 static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len)
75 int i;
76 for (i=0;i<len;i++)
78 out[i] = PSHR16(in[i], shift);
81 #endif
83 #ifdef USE_SMALLFT
85 #include "smallft.h"
86 #include <math.h>
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);
93 return (void*)table;
96 void spx_fft_destroy(void *table)
98 spx_drft_clear(table);
99 speex_free(table);
102 void spx_fft(void *table, float *in, float *out)
104 if (in==out)
106 int i;
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];
111 } else {
112 int 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)
122 if (in==out)
124 speex_warning("FFT should not be done in-place");
125 } else {
126 int i;
127 for (i=0;i<((struct drft_lookup *)table)->n;i++)
128 out[i] = in[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"
138 struct kiss_config {
139 kiss_fftr_cfg forward;
140 kiss_fftr_cfg backward;
141 int N;
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);
150 table->N = size;
151 return table;
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);
159 speex_free(table);
162 #ifdef FIXED_POINT
164 void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
166 int shift;
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);
174 #else
176 void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out)
178 int i;
179 float scale;
180 struct kiss_config *t = (struct kiss_config *)table;
181 scale = 1./t->N;
182 kiss_fftr2(t->forward, in, out);
183 for (i=0;i<t->N;i++)
184 out[i] *= scale;
186 #endif
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);
195 #else
197 #error No other FFT implemented
199 #endif
202 #ifdef FIXED_POINT
203 /*#include "smallft.h"*/
206 void spx_fft_float(void *table, float *in, float *out)
208 int i;
209 #ifdef USE_SMALLFT
210 int N = ((struct drft_lookup *)table)->n;
211 #elif defined(USE_KISS_FFT)
212 int N = ((struct kiss_config *)table)->N;
213 #else
214 #endif
215 #ifdef VAR_ARRAYS
216 spx_word16_t _in[N];
217 spx_word16_t _out[N];
218 #else
219 spx_word16_t _in[MAX_FFT_SIZE];
220 spx_word16_t _out[MAX_FFT_SIZE];
221 #endif
222 for (i=0;i<N;i++)
223 _in[i] = (int)floor(.5+in[i]);
224 spx_fft(table, _in, _out);
225 for (i=0;i<N;i++)
226 out[i] = _out[i];
227 #if 0
228 if (!fixed_point)
230 float scale;
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);
237 spx_drft_clear(&t);
239 #endif
242 void spx_ifft_float(void *table, float *in, float *out)
244 int i;
245 #ifdef USE_SMALLFT
246 int N = ((struct drft_lookup *)table)->n;
247 #elif defined(USE_KISS_FFT)
248 int N = ((struct kiss_config *)table)->N;
249 #else
250 #endif
251 #ifdef VAR_ARRAYS
252 spx_word16_t _in[N];
253 spx_word16_t _out[N];
254 #else
255 spx_word16_t _in[MAX_FFT_SIZE];
256 spx_word16_t _out[MAX_FFT_SIZE];
257 #endif
258 for (i=0;i<N;i++)
259 _in[i] = (int)floor(.5+in[i]);
260 spx_ifft(table, _in, _out);
261 for (i=0;i<N;i++)
262 out[i] = _out[i];
263 #if 0
264 if (!fixed_point)
266 int i;
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++)
270 out[i] = in[i];
271 spx_drft_backward(&t, out);
272 spx_drft_clear(&t);
274 #endif
277 #else
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);
288 #endif