Mercurial > hg > x
comparison fft.cpp @ 1:6422640a802f
first upload
author | Wen X <xue.wen@elec.qmul.ac.uk> |
---|---|
date | Tue, 05 Oct 2010 10:45:57 +0100 |
parents | |
children | fc19d45615d1 |
comparison
equal
deleted
inserted
replaced
0:9b9f21935f24 | 1:6422640a802f |
---|---|
1 //--------------------------------------------------------------------------- | |
2 | |
3 #include <mem.h> | |
4 #include <stdlib.h> | |
5 #include "fft.h" | |
6 | |
7 //--------------------------------------------------------------------------- | |
8 /* | |
9 function Atan2: (0, 0)-safe atan2 | |
10 | |
11 Returns 0 is x=y=0, atan2(x,y) otherwise. | |
12 */ | |
13 double Atan2(double y, double x) | |
14 { | |
15 if (x==0 && y==0) return 0; | |
16 else return atan2(y, x); | |
17 }//Atan2 | |
18 | |
19 /* | |
20 function BitInv: inverse bit order of Value within an $Order-bit expression. | |
21 | |
22 In: integer Value smaller than 2^Order | |
23 | |
24 Returns an integer whose lowest Order bits are the lowest Order bits of Value in reverse order. | |
25 */ | |
26 int BitInv(int Value, int Order) | |
27 { | |
28 int Result; | |
29 Result=0; | |
30 for (int i=0;i<Order;i++) | |
31 { | |
32 Result=(Result<<1)+(Value&0x00000001); | |
33 Value=Value>>1; | |
34 } | |
35 return Result; | |
36 }//BitInv | |
37 | |
38 /* | |
39 function SetTwiddleFactors: fill w[N/2] with twiddle factors used in N-point complex FFT. | |
40 | |
41 In: N | |
42 Out: array w[N/2] containing twiddle factors | |
43 | |
44 No return value. | |
45 */ | |
46 void SetTwiddleFactors(int N, cdouble* w) | |
47 { | |
48 double ep=-M_PI*2/N; | |
49 for (int i=0; i<N/2; i++) | |
50 { | |
51 double tmp=ep*i; | |
52 w[i].x=cos(tmp), w[i].y=sin(tmp); | |
53 } | |
54 }//SetTwiddleFactors | |
55 | |
56 //--------------------------------------------------------------------------- | |
57 /* | |
58 function CFFTCbii: basic complex DIF-FFT module, applied after bit-inversed ordering of inputs | |
59 | |
60 In: Order: integer, equals log2(Wid) | |
61 W[Wid/2]: twiddle factors | |
62 X[Wid]: complex waveform | |
63 Out: X[Wid]: complex spectrum | |
64 | |
65 No return value. | |
66 */ | |
67 void CFFTCbii(int Order, cdouble* W, cdouble* X) | |
68 { | |
69 int i, j, k, ElemsPerGroup, Groups, X0, X1, X2; | |
70 cdouble Temp; | |
71 for (i=0; i<Order; i++) | |
72 { | |
73 ElemsPerGroup=1<<i; | |
74 Groups=1<<(Order-i-1); | |
75 X0=0; | |
76 for (j=0; j<Groups; j++) | |
77 { | |
78 for (k=0; k<ElemsPerGroup; k++) | |
79 { | |
80 int kGroups=k*Groups; | |
81 X1=X0+k; | |
82 X2=X1+ElemsPerGroup; | |
83 //X(X2)<-X(X2)*W | |
84 Temp.x=X[X2].x*W[kGroups].x-X[X2].y*W[kGroups].y, | |
85 X[X2].y=X[X2].x*W[kGroups].y+X[X2].y*W[kGroups].x; | |
86 X[X2].x=Temp.x; | |
87 Temp.x=X[X1].x+X[X2].x, Temp.y=X[X1].y+X[X2].y; | |
88 X[X2].x=X[X1].x-X[X2].x, X[X2].y=X[X1].y-X[X2].y; | |
89 X[X1]=Temp; | |
90 } | |
91 X0+=ElemsPerGroup*2; | |
92 } | |
93 } | |
94 }//CFFTCbii | |
95 | |
96 /* | |
97 function CFFTC: in-place complex FFT | |
98 | |
99 In: Order: integer, equals log2(Wid) | |
100 W[Wid/2]: twiddle factors | |
101 X[Wid]: complex waveform | |
102 bitinv[Wid]: bit-inversion table | |
103 Out: X[Wid]: complex spectrum | |
104 | |
105 No return value. | |
106 */ | |
107 void CFFTC(int Order, cdouble* W, cdouble* X, int* bitinv) | |
108 { | |
109 int N=1<<Order, i, jj; | |
110 cdouble Temp; | |
111 int* bitinv1=bitinv; | |
112 if (!bitinv) bitinv=CreateBitInvTable(Order); | |
113 for (i=1; i<N-1; i++) | |
114 { | |
115 jj=bitinv[i]; | |
116 if (i<jj) | |
117 { | |
118 Temp=X[i]; | |
119 X[i]=X[jj]; | |
120 X[jj]=Temp; | |
121 } | |
122 } | |
123 if (!bitinv1) free(bitinv); | |
124 CFFTCbii(Order, W, X); | |
125 }//CFFTC | |
126 | |
127 /* | |
128 function CFFTC: complex FFT | |
129 | |
130 In: Input[Wid]: complex waveform | |
131 Order: integer, equals log2(Wid) | |
132 W[Wid/2]: twiddle factors | |
133 bitinv[Wid]: bit-inversion table | |
134 Out:X[Wid]: complex spectrum | |
135 Amp[Wid]: amplitude spectrum | |
136 Arg[Wid]: phase spectrum | |
137 | |
138 No return value. | |
139 */ | |
140 void CFFTC(cdouble* Input, double *Amp, double *Arg, int Order, cdouble* W, cdouble* X, int* bitinv) | |
141 { | |
142 int i, N=1<<Order; | |
143 | |
144 if (X!=Input) memcpy(X, Input, sizeof(cdouble)*N); | |
145 CFFTC(Order, W, X, bitinv); | |
146 | |
147 if (Amp) for (i=0; i<N; i++) Amp[i]=sqrt(X[i].x*X[i].x+X[i].y*X[i].y); | |
148 if (Arg) for (i=0; i<N; i++) Arg[i]=Atan2(X[i].y, X[i].x); | |
149 }//CFFTC | |
150 | |
151 //--------------------------------------------------------------------------- | |
152 /* | |
153 function CIFFTCbii: basic complex IFFT module, applied after bit-inversed ordering of inputs | |
154 | |
155 In: Order: integer, equals log2(Wid) | |
156 W[Wid/2]: twiddle factors | |
157 X[Wid]: complex spectrum | |
158 Out: X[Wid]: complex waveform | |
159 | |
160 No return value. | |
161 */ | |
162 void CIFFTCbii(int Order, cdouble* W, cdouble* X) | |
163 { | |
164 int N=1<<Order, i, j, k, Groups, ElemsPerGroup, X0, X1, X2; | |
165 cdouble Temp; | |
166 | |
167 for (i=0; i<Order; i++) | |
168 { | |
169 ElemsPerGroup=1<<i; | |
170 Groups=1<<(Order-i-1); | |
171 X0=0; | |
172 for (j=0; j<Groups; j++) | |
173 { | |
174 for (k=0; k<ElemsPerGroup; k++) | |
175 { | |
176 int kGroups=k*Groups; | |
177 X1=X0+k; | |
178 X2=X1+ElemsPerGroup; | |
179 Temp.x=X[X2].x*W[kGroups].x+X[X2].y*W[kGroups].y, | |
180 X[X2].y=-X[X2].x*W[kGroups].y+X[X2].y*W[kGroups].x; | |
181 X[X2].x=Temp.x; | |
182 Temp.x=X[X1].x+X[X2].x, Temp.y=X[X1].y+X[X2].y; | |
183 X[X2].x=X[X1].x-X[X2].x, X[X2].y=X[X1].y-X[X2].y; | |
184 X[X1]=Temp; | |
185 } | |
186 X0=X0+ElemsPerGroup*2; | |
187 } | |
188 } | |
189 for (i=0; i<N; i++) | |
190 { | |
191 X[i].x/=N; | |
192 X[i].y/=N; | |
193 } | |
194 }//CIFFTCbii | |
195 | |
196 /* | |
197 function CIFFTC: in-place complex IFFT | |
198 | |
199 In: Order: integer, equals log2(Wid) | |
200 W[Wid/2]: twiddle factors | |
201 X[Wid]: complex spectrum | |
202 bitinv[Wid]: bit-inversion table | |
203 Out: X[Wid]: complex waveform | |
204 | |
205 No return value. | |
206 */ | |
207 void CIFFTC(int Order, cdouble* W, cdouble* X, int* bitinv) | |
208 { | |
209 int N=1<<Order, i, jj, *bitinv1=bitinv; | |
210 cdouble Temp; | |
211 if (!bitinv) bitinv=CreateBitInvTable(Order); | |
212 for (i=1; i<N-1; i++) | |
213 { | |
214 jj=bitinv[i]; | |
215 if (i<jj) | |
216 { | |
217 Temp=X[i]; | |
218 X[i]=X[jj]; | |
219 X[jj]=Temp; | |
220 } | |
221 } | |
222 if (!bitinv1) free(bitinv); | |
223 CIFFTCbii(Order, W, X); | |
224 }//CIFFTC | |
225 | |
226 /* | |
227 function CIFFTC: complex IFFT | |
228 | |
229 In: Input[Wid]: complex spectrum | |
230 Order: integer, equals log2(Wid) | |
231 W[Wid/2]: twiddle factors | |
232 bitinv[Wid]: bit-inversion table | |
233 Out:X[Wid]: complex waveform | |
234 | |
235 No return value. | |
236 */ | |
237 void CIFFTC(cdouble* Input, int Order, cdouble* W, cdouble* X, int* bitinv) | |
238 { | |
239 int N=1<<Order; | |
240 if (X!=Input) memcpy(X, Input, sizeof(cdouble)*N); | |
241 if (bitinv) CIFFTC(Order, W, X, bitinv); | |
242 else CIFFTC(Order, W, X); | |
243 }//CIFFTC | |
244 | |
245 //--------------------------------------------------------------------------- | |
246 /* | |
247 function CIFFTR: complex-to-real IFFT | |
248 | |
249 In: Input[Wid/2+1]: complex spectrum, imaginary parts of Input[0] and Input[Wid/2] are ignored | |
250 Order: integer, equals log2(Wid) | |
251 W[Wid/2]: twiddle factors | |
252 hbitinv[Wid/2]: half bit-inversion table | |
253 Out:X[Wid]: real waveform | |
254 | |
255 No return value. | |
256 */ | |
257 void CIFFTR(cdouble* Input, int Order, cdouble* W, double* X, int* hbitinv) | |
258 { | |
259 int N=1<<Order, i, j, k, Groups, ElemsPerGroup, X0, X1, X2, *hbitinv1=hbitinv; | |
260 cdouble Temp; | |
261 | |
262 Order--; N/=2; | |
263 if (!hbitinv) hbitinv=CreateBitInvTable(Order); | |
264 | |
265 cdouble* Xc=(cdouble*)X; | |
266 | |
267 Xc[0].y=0.5*(Input[0].x-Input[N].x); | |
268 Xc[0].x=0.5*(Input[0].x+Input[N].x); | |
269 for (int i=1; i<N/2; i++) | |
270 { | |
271 double frp=Input[i].x+Input[N-i].x, frn=Input[i].x-Input[N-i].x, | |
272 fip=Input[i].y+Input[N-i].y, fin=Input[i].y-Input[N-i].y; | |
273 Xc[i].x=0.5*(frp+frn*W[i].y-fip*W[i].x); | |
274 Xc[i].y=0.5*(fin+frn*W[i].x+fip*W[i].y); | |
275 Xc[N-i].x=0.5*(frp-frn*W[i].y+fip*W[i].x); | |
276 Xc[N-i].y=0.5*(-fin+frn*W[i].x+fip*W[i].y); | |
277 } | |
278 Xc[N/2].x=Input[N/2].x; | |
279 Xc[N/2].y=-Input[N/2].y; | |
280 | |
281 ElemsPerGroup=1<<Order; | |
282 Groups=1; | |
283 | |
284 for (i=0; i<Order; i++) | |
285 { | |
286 ElemsPerGroup/=2; | |
287 X0=0; | |
288 for (j=0; j<Groups; j++) | |
289 { | |
290 int kGroups=hbitinv[j]; | |
291 for (k=0; k<ElemsPerGroup; k++) | |
292 { | |
293 X1=X0+k; | |
294 X2=X1+ElemsPerGroup; | |
295 Temp.x=Xc[X2].x*W[kGroups].x+Xc[X2].y*W[kGroups].y, | |
296 Xc[X2].y=-Xc[X2].x*W[kGroups].y+Xc[X2].y*W[kGroups].x; | |
297 Xc[X2].x=Temp.x; | |
298 Temp.x=Xc[X1].x+Xc[X2].x, Temp.y=Xc[X1].y+Xc[X2].y; | |
299 Xc[X2].x=Xc[X1].x-Xc[X2].x, Xc[X2].y=Xc[X1].y-Xc[X2].y; | |
300 Xc[X1].x=Temp.x, Xc[X1].y=Temp.y; | |
301 } | |
302 X0=X0+(ElemsPerGroup<<1); | |
303 } | |
304 Groups*=2; | |
305 } | |
306 | |
307 for (i=0; i<N; i++) | |
308 { | |
309 int jj=hbitinv[i]; | |
310 if (i<jj) | |
311 { | |
312 Temp=Xc[i]; | |
313 Xc[i]=Xc[jj]; | |
314 Xc[jj]=Temp; | |
315 } | |
316 } | |
317 double norm=1.0/N;; | |
318 N*=2; | |
319 for (int i=0; i<N; i++) X[i]*=norm; | |
320 if (!hbitinv1) free(hbitinv); | |
321 }//CIFFTR | |
322 | |
323 //--------------------------------------------------------------------------- | |
324 /* | |
325 function CreateBitInvTable: creates a table of bit-inversed integers | |
326 | |
327 In: Order: interger, equals log2(size of table) | |
328 | |
329 Returns a pointer to a newly allocated array containing the table. The returned pointer must be freed | |
330 using free(), NOT delete[]. | |
331 */ | |
332 int* CreateBitInvTable(int Order) | |
333 { | |
334 int N=1<<Order; | |
335 int* result=(int*)malloc(sizeof(int)*N); | |
336 for (int i=0; i<N; i++) result[i]=BitInv(i, Order); | |
337 return result; | |
338 }//CreateBitInvTable | |
339 | |
340 | |
341 //--------------------------------------------------------------------------- | |
342 /* | |
343 function RFFTC_ual: unaligned real-to-complex FFT | |
344 | |
345 In: Input[Wid]: real waveform | |
346 Order; integer, equals log2(Wid) | |
347 W[Wid/2]: twiddle factors | |
348 hbitinv[Wid/2]: half bit-inversion table | |
349 Out:X[Wid}: complex spectrum | |
350 Amp[Wid]: amplitude spectrum | |
351 Arg[Wid]: phase spetrum | |
352 | |
353 No return value. | |
354 */ | |
355 void RFFTC_ual(double* Input, double *Amp, double *Arg, int Order, cdouble* W, cdouble* X, int* hbitinv) | |
356 { | |
357 int N=1<<Order, i, j, k, *hbitinv1=hbitinv, Groups, ElemsPerGroup, X0, X1, X2; | |
358 cdouble Temp, zp, zn; | |
359 | |
360 N/=2; Order--; | |
361 | |
362 //Input being NULL implies external initialization of X. This is used by RFFTCW but is not | |
363 //recommended for external use. | |
364 if (Input) | |
365 { | |
366 if (!hbitinv) hbitinv=CreateBitInvTable(Order); | |
367 | |
368 if (Input==(double*)X) | |
369 { | |
370 //Input being identical to X is not recommended for external use. | |
371 for (int i=0; i<N; i++) | |
372 { | |
373 int bi=hbitinv[i]; | |
374 if (i<bi) {cdouble tmp=X[i]; X[i]=X[bi]; X[bi]=tmp;} | |
375 } | |
376 } | |
377 else | |
378 { | |
379 for (i=0; i<N; i++) X[i]=((cdouble*)Input)[hbitinv[i]]; | |
380 } | |
381 if (!hbitinv1) free(hbitinv); | |
382 } | |
383 | |
384 for (i=0; i<Order; i++) | |
385 { | |
386 ElemsPerGroup=1<<i; | |
387 Groups=1<<(Order-i-1); | |
388 X0=0; | |
389 for (j=0; j<Groups; j++) | |
390 { | |
391 for (k=0; k<ElemsPerGroup; k++) | |
392 { | |
393 X1=X0+k; | |
394 X2=X1+ElemsPerGroup; | |
395 int kGroups=k*2*Groups; | |
396 Temp.x=X[X2].x*W[kGroups].x-X[X2].y*W[kGroups].y, | |
397 X[X2].y=X[X2].x*W[kGroups].y+X[X2].y*W[kGroups].x; | |
398 X[X2].x=Temp.x; | |
399 Temp.x=X[X1].x+X[X2].x, Temp.y=X[X1].y+X[X2].y; | |
400 X[X2].x=X[X1].x-X[X2].x, X[X2].y=X[X1].y-X[X2].y; | |
401 X[X1]=Temp; | |
402 } | |
403 X0=X0+(ElemsPerGroup<<1); | |
404 } | |
405 } | |
406 zp.x=X[0].x+X[0].y, zn.x=X[0].x-X[0].y; | |
407 X[0].x=zp.x; | |
408 X[0].y=0; | |
409 X[N].x=zn.x; | |
410 X[N].y=0; | |
411 for (int k=1; k<N/2; k++) | |
412 { | |
413 zp.x=X[k].x+X[N-k].x, zn.x=X[k].x-X[N-k].x, | |
414 zp.y=X[k].y+X[N-k].y, zn.y=X[k].y-X[N-k].y; | |
415 X[k].x=0.5*(zp.x+W[k].y*zn.x+W[k].x*zp.y); | |
416 X[k].y=0.5*(zn.y-W[k].x*zn.x+W[k].y*zp.y); | |
417 X[N-k].x=0.5*(zp.x-W[k].y*zn.x-W[k].x*zp.y); | |
418 X[N-k].y=0.5*(-zn.y-W[k].x*zn.x+W[k].y*zp.y); | |
419 } | |
420 //X[N/2].x=X[N/2].x; | |
421 X[N/2].y=-X[N/2].y; | |
422 N*=2; | |
423 | |
424 for (int k=N/2+1; k<N; k++) X[k].x=X[N-k].x, X[k].y=-X[N-k].y; | |
425 if (Amp) for (i=0; i<N; i++) Amp[i]=sqrt(X[i].x*X[i].x+X[i].y*X[i].y); | |
426 if (Arg) for (i=0; i<N; i++) Arg[i]=Atan2(X[i].x, X[i].y); | |
427 }//RFFTC_ual | |
428 | |
429 //--------------------------------------------------------------------------- | |
430 /* | |
431 function RFFTCW: real-to-complex FFT with window | |
432 | |
433 In: Input[Wid]: real waveform | |
434 Window[Wid]: window function | |
435 Order; integer, equals log2(Wid) | |
436 W[Wid/2]: twiddle factors | |
437 hbitinv[Wid/2]: half bit-inversion table | |
438 Out:X[Wid}: complex spectrum | |
439 Amp[Wid]: amplitude spectrum | |
440 Arg[Wid]: phase spetrum | |
441 | |
442 No return value. | |
443 */ | |
444 void RFFTCW(double* Input, double* Window, double *Amp, double *Arg, int Order, cdouble* W, cdouble* X, int* hbitinv) | |
445 { | |
446 int N=1<<Order, *hbitinv1=hbitinv; | |
447 if (!hbitinv) hbitinv=CreateBitInvTable(Order-1); | |
448 N/=2; | |
449 | |
450 if (Input==(double*)X) | |
451 { //so that X[n].x IS Input[2n], X[n].y IS Input[2n+1] | |
452 for (int n=0; n<N; n++) | |
453 { | |
454 int bi=hbitinv[n], n2=n+n, bi2=bi+bi; | |
455 if (n<bi) | |
456 { | |
457 double tmp=X[n].x*Window[n2]; X[n].x=X[bi].x*Window[bi2]; X[bi].x=tmp; | |
458 tmp=X[n].y*Window[n2+1]; X[n].y=X[bi].y*Window[bi2+1]; X[bi].y=tmp; | |
459 } | |
460 else if (n==bi) | |
461 { //so that X[n].x IS Input[bi] | |
462 X[n].x*=Window[bi2], X[n].y*=Window[bi2+1]; | |
463 } | |
464 } | |
465 } | |
466 else | |
467 { | |
468 for (int n=0; n<N; n++) | |
469 { | |
470 int bi=hbitinv[n], bi2=bi+bi; X[n].x=Input[bi2]*Window[bi2], X[n].y=Input[bi2+1]*Window[bi2+1]; | |
471 } | |
472 } | |
473 | |
474 RFFTC_ual(0, Amp, Arg, Order, W, X, hbitinv); | |
475 if (!hbitinv1) free(hbitinv); | |
476 }//RFFTCW | |
477 | |
478 /* | |
479 function RFFTCW: real-to-complex FFT with window | |
480 | |
481 In: Input[Wid]: real waveform as _int16 array | |
482 Window[Wid]: window function | |
483 Order; integer, equals log2(Wid) | |
484 W[Wid/2]: twiddle factors | |
485 hbitinv[Wid/2]: half bit-inversion table | |
486 Out:X[Wid}: complex spectrum | |
487 Amp[Wid]: amplitude spectrum | |
488 Arg[Wid]: phase spetrum | |
489 | |
490 No return value. | |
491 */ | |
492 void RFFTCW(__int16* Input, double* Window, double *Amp, double *Arg, int Order, cdouble* W, cdouble* X, int* hbitinv) | |
493 { | |
494 int N=1<<Order, *hbitinv1=hbitinv; | |
495 | |
496 N/=2; | |
497 if (!hbitinv) hbitinv=CreateBitInvTable(Order-1); | |
498 for (int n=0; n<N; n++) | |
499 { | |
500 int bi=hbitinv[n], bi2=bi+bi; X[n].x=Input[bi2]*Window[bi2], X[n].y=Input[bi2+1]*Window[bi2+1]; | |
501 } | |
502 | |
503 RFFTC_ual(0, Amp, Arg, Order, W, X, hbitinv); | |
504 if (!hbitinv1) free(hbitinv); | |
505 }//RFFTCW | |
506 | |
507 //--------------------------------------------------------------------------- | |
508 /* | |
509 function CFFTCW: complex FFT with window | |
510 | |
511 In: Window[Wid]: window function | |
512 Order: integer, equals log2(Wid) | |
513 W[Wid/2]: twiddle factors | |
514 X[Wid]: complex waveform | |
515 bitinv[Wid]: bit-inversion table | |
516 Out:X[Wid], complex spectrum | |
517 | |
518 No return value. | |
519 */ | |
520 void CFFTCW(double* Window, int Order, cdouble* W, cdouble* X, int* bitinv) | |
521 { | |
522 int N=1<<Order; | |
523 for (int i=0; i<N; i++) X[i].x*=Window[i], X[i].y*=Window[i]; | |
524 CFFTC(Order, W, X, bitinv); | |
525 }//CFFTCW | |
526 | |
527 /* | |
528 function CFFTCW: complex FFT with window | |
529 | |
530 In: Input[Wid]: complex waveform | |
531 Window[Wid]: window function | |
532 Order: integer, equals log2(Wid) | |
533 W[Wid/2]: twiddle factors | |
534 X[Wid]: complex waveform | |
535 bitinv[Wid]: bit-inversion table | |
536 Out:X[Wid], complex spectrum | |
537 Amp[Wid], amplitude spectrum | |
538 Arg[Wid], phase spectrum | |
539 | |
540 No return value. | |
541 */ | |
542 void CFFTCW(cdouble* Input, double* Window, double *Amp, double *Arg, int Order, cdouble* W, cdouble* X, int* bitinv) | |
543 { | |
544 int N=1<<Order; | |
545 for (int i=0; i<N; i++) X[i].x=Input[i].x*Window[i], X[i].y=Input[i].y*Window[i]; | |
546 CFFTC(X, Amp, Arg, Order, W, X, bitinv); | |
547 }//CFFTCW | |
548 | |
549 //--------------------------------------------------------------------------- | |
550 /* | |
551 function RDCT1: fast DCT1 implemented using FFT. DCT-I has the time scale 0.5-sample shifted from the DFT. | |
552 | |
553 In: Input[Wid]: real waveform | |
554 Order: integer, equals log2(Wid) | |
555 qW[Wid/8]: quarter table of twiddle factors | |
556 qX[Wid/4]: quarter FFT data buffer | |
557 qbitinv[Wid/4]: quarter bit-inversion table | |
558 Out:Output[Wid]: DCT-I of Input. | |
559 | |
560 No return value. Content of qW is destroyed on return. On calling the fft buffers should be allocated | |
561 to size 0.25*Wid. | |
562 */ | |
563 void RDCT1(double* Input, double* Output, int Order, cdouble* qW, cdouble* qX, int* qbitinv) | |
564 { | |
565 const double lmd0=sqrt(0.5); | |
566 if (Order==0) | |
567 { | |
568 Output[0]=Input[0]*lmd0; | |
569 return; | |
570 } | |
571 if (Order==1) | |
572 { | |
573 double tmp1=(Input[0]+Input[1])*lmd0; | |
574 Output[1]=(Input[0]-Input[1])*lmd0; | |
575 Output[0]=tmp1; | |
576 return; | |
577 } | |
578 int order=Order-1, N=1<<(Order-1), C=1; | |
579 bool createbitinv=!qbitinv; | |
580 if (createbitinv) qbitinv=CreateBitInvTable(Order-2); | |
581 double *even=(double*)malloc8(sizeof(double)*N*2); | |
582 double *odd=&even[N]; | |
583 //data pass from Input to Output, combined with the first sequence split | |
584 for (int i=0, N2=N*2; i<N; i++) | |
585 { | |
586 even[i]=Input[i]+Input[N2-1-i]; | |
587 odd[i]=Input[i]-Input[N2-1-i]; | |
588 } | |
589 for (int i=0; i<N; i++) Output[i*2]=even[i], Output[i*2+1]=odd[i]; | |
590 while (order>1) | |
591 { | |
592 //N=2^order, 4|N, 2|hN | |
593 //keep subsequence 0, 2C, 4C, ... 2(N-1)C | |
594 //process sequence C, 3C, ..., (2N-1)C only | |
595 //RDCT4 routine | |
596 int hN=N/2, N2=N*2; | |
597 for (int i=0; i<hN; i++) | |
598 { | |
599 double b=Output[(2*(2*i)+1)*C], c=Output[(2*(N-1-2*i)+1)*C], theta=-(i+0.25)*M_PI/N; | |
600 double co=cos(theta), si=sin(theta); | |
601 qX[i].x=b*co-c*si, qX[i].y=c*co+b*si; | |
602 } | |
603 CFFTC(order-1, qW, qX, qbitinv); | |
604 for (int i=0; i<hN; i++) | |
605 { | |
606 double gr=qX[i].x, gi=qX[i].y, theta=-i*M_PI/N; | |
607 double co=cos(theta), si=sin(theta); | |
608 Output[(4*i+1)*C]=gr*co-gi*si; | |
609 Output[(N2-4*i-1)*C]=-gr*si-gi*co; | |
610 } | |
611 N=(N>>1); | |
612 C=(C<<1); | |
613 for (int i=1; i<N/4; i++) | |
614 qW[i]=qW[i*2]; | |
615 for (int i=1; i<N/2; i++) | |
616 qbitinv[i]=qbitinv[i*2]; | |
617 | |
618 //splitting subsequence 0, 2C, 4C, ..., 2(N-1)C | |
619 for (int i=0, N2=N*2; i<N; i++) | |
620 { | |
621 even[i]=Output[i*C]+Output[(N2-1-i)*C]; | |
622 odd[i]=Output[i*C]-Output[(N2-1-i)*C]; | |
623 } | |
624 for (int i=0; i<N; i++) | |
625 { | |
626 Output[2*i*C]=even[i]; | |
627 Output[(2*i+1)*C]=odd[i]; | |
628 } | |
629 order--; | |
630 } | |
631 //order==1 | |
632 //use C and 3C in DCT4 | |
633 //use 0 and 2C in DCT1 | |
634 double c1=cos(M_PI/8), c2=cos(3*M_PI/8); | |
635 double tmp1=c1*Output[C]+c2*Output[3*C]; | |
636 Output[3*C]=c2*Output[C]-c1*Output[3*C]; | |
637 Output[C]=tmp1; | |
638 tmp1=Output[0]+Output[2*C]; | |
639 Output[2*C]=(Output[0]-Output[2*C])*lmd0; | |
640 Output[0]=tmp1*lmd0; | |
641 | |
642 if (createbitinv) free(qbitinv); | |
643 free8(even); | |
644 }//RDCT1 | |
645 | |
646 //--------------------------------------------------------------------------- | |
647 /* | |
648 function RDCT4: fast DCT4 implemented using FFT. DCT-IV has both the time and frequency scales | |
649 0.5-sample or 0.5-bin shifted from DFT. | |
650 | |
651 In: Input[Wid]: real waveform | |
652 Order: integer, equals log2(Wid) | |
653 hW[Wid/4]: half table of twiddle factors | |
654 hX[Wid/2]: hal FFT data buffer | |
655 hbitinv[Wid/2]: half bit-inversion table | |
656 Out:Output[Wid]: DCT-IV of Input. | |
657 | |
658 No return value. Content of hW not affected. On calling the fft buffers should be allocated to size | |
659 0.5*Wid. | |
660 */ | |
661 void RDCT4(double* Input, double* Output, int Order, cdouble* hW, cdouble* hX, int* hbitinv) | |
662 { | |
663 if (Order==0) | |
664 { | |
665 Output[0]=Input[0]/sqrt(2); | |
666 return; | |
667 } | |
668 if (Order==1) | |
669 { | |
670 double c1=cos(M_PI/8), c2=cos(3*M_PI/8); | |
671 double tmp1=c1*Input[0]+c2*Input[1]; | |
672 Output[1]=c2*Input[0]-c1*Input[1]; | |
673 Output[0]=tmp1; | |
674 return; | |
675 } | |
676 int N=1<<Order, hN=N/2; | |
677 for (int i=0; i<hN; i++) | |
678 { | |
679 double b=Input[2*i], c=Input[N-1-i*2], theta=-(i+0.25)*M_PI/N; | |
680 double co=cos(theta), si=sin(theta); | |
681 hX[i].x=b*co-c*si, hX[i].y=c*co+b*si; | |
682 } | |
683 CFFTC(Order-1, hW, hX, hbitinv); | |
684 for (int i=0; i<hN; i++) | |
685 { | |
686 double gr=hX[i].x, gi=hX[i].y, theta=-i*M_PI/N; | |
687 double co=cos(theta), si=sin(theta); | |
688 Output[2*i]=gr*co-gi*si; | |
689 Output[N-1-2*i]=-gr*si-gi*co; | |
690 } | |
691 }//RDCT4 | |
692 | |
693 //--------------------------------------------------------------------------- | |
694 /* | |
695 function RIDCT1: fast IDCT1 implemented using FFT. | |
696 | |
697 In: Input[Wid]: DCT-I of some real waveform. | |
698 Order: integer, equals log2(Wid) | |
699 qW[Wid/8]: quarter table of twiddle factors | |
700 qX[Wid/4]: quarter FFT data buffer | |
701 qbitinv[Wid/4]: quarter bit-inversion table | |
702 Out:Output[Wid]: IDCT-I of Input. | |
703 | |
704 No return value. Content of qW is destroyed on return. On calling the fft buffers should be allocated | |
705 to size 0.25*Wid. | |
706 */ | |
707 void RIDCT1(double* Input, double* Output, int Order, cdouble* qW, cdouble* qX, int* qbitinv) | |
708 { | |
709 const double lmd0=sqrt(0.5); | |
710 if (Order==0) | |
711 { | |
712 Output[0]=Input[0]/lmd0; | |
713 return; | |
714 } | |
715 if (Order==1) | |
716 { | |
717 double tmp1=(Input[0]+Input[1])*lmd0; | |
718 Output[1]=(Input[0]-Input[1])*lmd0; | |
719 Output[0]=tmp1; | |
720 return; | |
721 } | |
722 int order=Order-1, N=1<<(Order-1), C=1; | |
723 bool createbitinv=!qbitinv; | |
724 if (createbitinv) qbitinv=CreateBitInvTable(Order-2); | |
725 double *even=(double*)malloc8(sizeof(double)*N*2); | |
726 double *odd=&even[N]; | |
727 | |
728 while (order>0) | |
729 { | |
730 //N=2^order, 4|N, 2|hN | |
731 //keep subsequence 0, 2C, 4C, ... 2(N-1)C | |
732 //process sequence C, 3C, ..., (2N-1)C only | |
733 //data pass from Input | |
734 for (int i=0; i<N; i++) | |
735 { | |
736 odd[i]=Input[(i*2+1)*C]; | |
737 } | |
738 | |
739 //IDCT4 routine | |
740 //RIDCT4(odd, odd, order, qW, qX, qbitinv); | |
741 | |
742 if (order==1) | |
743 { | |
744 double c1=cos(M_PI/8), c2=cos(3*M_PI/8); | |
745 double tmp1=c1*odd[0]+c2*odd[1]; | |
746 odd[1]=c2*odd[0]-c1*odd[1]; | |
747 odd[0]=tmp1; | |
748 } | |
749 else | |
750 { | |
751 int hN=N/2; | |
752 for (int i=0; i<hN; i++) | |
753 { | |
754 double b=odd[2*i], c=odd[N-1-i*2], theta=-(i+0.25)*M_PI/N; | |
755 double co=cos(theta), si=sin(theta); | |
756 qX[i].x=b*co-c*si, qX[i].y=c*co+b*si; | |
757 } | |
758 CFFTC(order-1, qW, qX, qbitinv); | |
759 double i2N=2.0/N; | |
760 for (int i=0; i<hN; i++) | |
761 { | |
762 double gr=qX[i].x, gi=qX[i].y, theta=-i*M_PI/N; | |
763 double co=cos(theta), si=sin(theta); | |
764 odd[2*i]=(gr*co-gi*si)*i2N; | |
765 odd[N-1-2*i]=(-gr*si-gi*co)*i2N; | |
766 } | |
767 } | |
768 | |
769 order--; | |
770 N=(N>>1); | |
771 C=(C<<1); | |
772 for (int i=1; i<N/4; i++) | |
773 qW[i]=qW[i*2]; | |
774 for (int i=1; i<N/2; i++) | |
775 qbitinv[i]=qbitinv[i*2]; | |
776 | |
777 odd=&even[N]; | |
778 } | |
779 //order==0 | |
780 even[0]=Input[0]; | |
781 even[1]=Input[C]; | |
782 double tmp1=(even[0]+even[1])*lmd0; | |
783 Output[1]=(even[0]-even[1])*lmd0; | |
784 Output[0]=tmp1; | |
785 order++; | |
786 | |
787 while (order<Order) | |
788 { | |
789 N=(N<<1); | |
790 odd=&even[N]; | |
791 for (int i=0; i<N; i++) | |
792 { | |
793 Output[N*2-1-i]=(Output[i]-odd[i])/2; | |
794 Output[i]=(Output[i]+odd[i])/2; | |
795 } | |
796 order++; | |
797 } | |
798 | |
799 if (createbitinv) free(qbitinv); | |
800 free8(even); | |
801 }//RIDCT1 | |
802 | |
803 //--------------------------------------------------------------------------- | |
804 /* | |
805 function RIDCT4: fast IDCT4 implemented using FFT. | |
806 | |
807 In: Input[Wid]: DCT-IV of some real waveform | |
808 Order: integer, equals log2(Wid) | |
809 hW[Wid/4]: half table of twiddle factors | |
810 hX[Wid/2]: hal FFT data buffer | |
811 hbitinv[Wid/2]: half bit-inversion table | |
812 Out:Output[Wid]: IDCT-IV of Input. | |
813 | |
814 No return value. Content of hW not affected. On calling the fft buffers should be allocated to size | |
815 0.5*Wid. | |
816 */ | |
817 void RIDCT4(double* Input, double* Output, int Order, cdouble* hW, cdouble* hX, int* hbitinv) | |
818 { | |
819 if (Order==0) | |
820 { | |
821 Output[0]=Input[0]*sqrt(2); | |
822 return; | |
823 } | |
824 if (Order==1) | |
825 { | |
826 double c1=cos(M_PI/8), c2=cos(3*M_PI/8); | |
827 double tmp1=c1*Input[0]+c2*Input[1]; | |
828 Output[1]=c2*Input[0]-c1*Input[1]; | |
829 Output[0]=tmp1; | |
830 return; | |
831 } | |
832 int N=1<<Order, hN=N/2; | |
833 for (int i=0; i<hN; i++) | |
834 { | |
835 double b=Input[2*i], c=Input[N-1-i*2], theta=-(i+0.25)*M_PI/N; | |
836 double co=cos(theta), si=sin(theta); | |
837 hX[i].x=b*co-c*si, hX[i].y=c*co+b*si; | |
838 } | |
839 CFFTC(Order-1, hW, hX, hbitinv); | |
840 double i2N=2.0/N; | |
841 for (int i=0; i<hN; i++) | |
842 { | |
843 double gr=hX[i].x, gi=hX[i].y, theta=-i*M_PI/N; | |
844 double co=cos(theta), si=sin(theta); | |
845 Output[2*i]=(gr*co-gi*si)*i2N; | |
846 Output[N-1-2*i]=(-gr*si-gi*co)*i2N; | |
847 } | |
848 }//RIDCT4 | |
849 | |
850 //--------------------------------------------------------------------------- | |
851 /* | |
852 function RLCT: real local cosine transform of equal frame widths Wid=2^Order | |
853 | |
854 In: data[Count]: real waveform | |
855 Order: integer, equals log2(Wid), Wid being the cosine atom size | |
856 g[wid]: lap window, designed so that g[k] increases from 0 to 1 and g[k]^2+g[wid-1-k]^2=1 | |
857 example: wid=4, g[k]=sin(pi*(k+0.5)/8). | |
858 Out:spec[Fr][Wid]: the local cosine transform | |
859 | |
860 No return value. | |
861 */ | |
862 void RLCT(double** spec, double* data, int Count, int Order, int wid, double* g) | |
863 { | |
864 int Wid=1<<Order, Fr=Count/Wid, hwid=wid/2; | |
865 int* hbitinv=CreateBitInvTable(Order-1); | |
866 cdouble *hx=(cdouble*)malloc8(sizeof(cdouble)*Wid*3/4), *hw=(cdouble*)&hx[Wid/2]; | |
867 double norm=sqrt(2.0/Wid); | |
868 SetTwiddleFactors(Wid/2, hw); | |
869 | |
870 for (int fr=0; fr<Fr; fr++) | |
871 { | |
872 if (fr==0) | |
873 { | |
874 memcpy(spec[fr], data, sizeof(double)*(Wid-hwid)); | |
875 for (int i=0, k=Wid+hwid-1, l=Wid-hwid; i<hwid; i++, k--, l++) | |
876 spec[fr][l]=data[l]*g[wid-1-i]-data[k]*g[i]; | |
877 } | |
878 else if (fr==Fr-1) | |
879 { | |
880 for (int i=hwid, j=fr*Wid, k=fr*Wid-1, l=0; i<wid; i++, j++, k--, l++) | |
881 spec[fr][l]=data[k]*g[wid-1-i]+data[j]*g[i]; | |
882 memcpy(&spec[fr][hwid], &data[fr*Wid+hwid], sizeof(double)*(Wid-hwid)); | |
883 } | |
884 else | |
885 { | |
886 for (int i=hwid, j=fr*Wid, k=fr*Wid-1, l=0; i<wid; i++, j++, k--, l++) | |
887 spec[fr][l]=data[k]*g[wid-1-i]+data[j]*g[i]; | |
888 if (Wid>wid) memcpy(&spec[fr][hwid], &data[fr*Wid+hwid], sizeof(double)*(Wid-wid)); | |
889 for (int i=0, j=(fr+1)*Wid-hwid, k=(fr+1)*Wid+hwid-1, l=Wid-hwid; i<hwid; i++, j++, k--, l++) | |
890 spec[fr][l]=data[j]*g[wid-1-i]-data[k]*g[i]; | |
891 } | |
892 } | |
893 for (int fr=0; fr<Fr; fr++) | |
894 { | |
895 if (fr==Fr-1) | |
896 { | |
897 for (int i=1; i<Wid/4; i++) hw[i]=hw[2*i], hbitinv[i]=hbitinv[2*i]; | |
898 RDCT1(spec[fr], spec[fr], Order, hw, hx, hbitinv); | |
899 } | |
900 else | |
901 RDCT4(spec[fr], spec[fr], Order, hw, hx, hbitinv); | |
902 | |
903 ////The following line can be removed if the corresponding line in RILCT(...) is removed | |
904 for (int i=0; i<Wid; i++) spec[fr][i]*=norm; | |
905 } | |
906 free(hbitinv); | |
907 free8(hx); | |
908 }//RLCT | |
909 | |
910 //--------------------------------------------------------------------------- | |
911 /* | |
912 function RILCT: inverse local cosine transform of equal frame widths Wid=2^Order | |
913 | |
914 In: spec[Fr][Wid]: the local cosine transform | |
915 Order: integer, equals log2(Wid), Wid being the cosine atom size | |
916 g[wid]: lap window, designed so that g[k] increases from 0 to 1 and g[k]^2+g[wid-1-k]^2=1. | |
917 example: wid=4, g[k]=sin(pi*(k+0.5)/8). | |
918 Out:data[Count]: real waveform | |
919 | |
920 No return value. | |
921 */ | |
922 void RILCT(double* data, double** spec, int Fr, int Order, int wid, double* g) | |
923 { | |
924 int Wid=1<<Order, Count=Fr*Wid, hwid=wid/2, *hbitinv=CreateBitInvTable(Order-1); | |
925 cdouble *hx=(cdouble*)malloc8(sizeof(cdouble)*Wid*3/4), *hw=&hx[Wid/2]; | |
926 double norm=sqrt(Wid/2.0); | |
927 SetTwiddleFactors(Wid/2, hw); | |
928 | |
929 for (int fr=0; fr<Fr; fr++) | |
930 { | |
931 if (fr==Fr-1) | |
932 { | |
933 for (int i=1; i<Wid/4; i++) hw[i]=hw[2*i], hbitinv[i]=hbitinv[i*2]; | |
934 RIDCT1(spec[fr], &data[fr*Wid], Order, hw, hx, hbitinv); | |
935 } | |
936 else | |
937 RIDCT4(spec[fr], &data[fr*Wid], Order, hw, hx, hbitinv); | |
938 } | |
939 //unfolding | |
940 for (int fr=1; fr<Fr; fr++) | |
941 { | |
942 double* h=&data[fr*Wid]; | |
943 for (int i=0; i<hwid; i++) | |
944 { | |
945 double a=h[i], b=h[-1-i], c=g[i+hwid], d=g[hwid-1-i]; | |
946 h[i]=a*c-b*d, h[-i-1]=b*c+a*d; | |
947 } | |
948 } | |
949 | |
950 free8(hx); | |
951 ////The following line can be removed if the corresponding line in RLCT(...) is removed | |
952 for (int i=0; i<Count; i++) data[i]*=norm; | |
953 }//RILCT | |
954 | |
955 //--------------------------------------------------------------------------- | |
956 /* | |
957 function CMFTC: radix-2 complex multiresolution Fourier transform | |
958 | |
959 In: x[Wid]: complex waveform | |
960 Order: integer, equals log2(Wid) | |
961 W[Wid/2]: twiddle factors | |
962 Out:X[Order+1][Wid]: multiresolution FT of x. X[0] is the same as x itself. | |
963 | |
964 No return value. | |
965 | |
966 Further reading: Wen X. and M. Sandler, "Calculation of radix-2 discrete multiresolution Fourier | |
967 transform," Signal Processing, vol.87 no.10, 2007, pp.2455-2460. | |
968 */ | |
969 void CMFTC(cdouble* x, int Order, cdouble** X, cdouble* W) | |
970 { | |
971 X[0]=x; | |
972 for (int n=1, L=1<<(Order-1), M=2; n<=Order; n++, L>>=1, M<<=1) | |
973 { | |
974 cdouble *Xn=X[n], *Xp=X[n-1]; | |
975 for (int l=0; l<L; l++) | |
976 { | |
977 cdouble* lX=&Xn[l*M]; | |
978 for (int m=0; m<M/2; m++) | |
979 { | |
980 lX[m].x=Xp[l*M+m].x+Xp[l*M+M/2+m].x; | |
981 lX[m].y=Xp[l*M+m].y+Xp[l*M+M/2+m].y; | |
982 double tmpr=x[l*M+m].x-x[l*M+M/2+m].x, tmpi=x[l*M+m].y-x[l*M+M/2+m].y; | |
983 int iw=m*L; | |
984 double wr=W[iw].x, wi=W[iw].y; | |
985 lX[M/2+m].x=tmpr*wr-tmpi*wi; | |
986 lX[M/2+m].y=tmpr*wi+tmpi*wr; | |
987 } | |
988 if (n==1) {} | |
989 else if (n==2) //two-point DFT | |
990 { | |
991 cdouble *aX=&X[n][l*M+M/2]; | |
992 double tmp; | |
993 tmp=aX[0].x+aX[1].x; aX[1].x=aX[0].x-aX[1].x; aX[0].x=tmp; | |
994 tmp=aX[0].y+aX[1].y; aX[1].y=aX[0].y-aX[1].y; aX[0].y=tmp; | |
995 } | |
996 else if (n==3) //4-point DFT | |
997 { | |
998 cdouble *aX=&X[n][l*M+M/2]; | |
999 double tmp, tmp2; | |
1000 tmp=aX[0].x+aX[2].x; aX[2].x=aX[0].x-aX[2].x; aX[0].x=tmp; | |
1001 tmp=aX[0].y+aX[2].y; aX[2].y=aX[0].y-aX[2].y; aX[0].y=tmp; | |
1002 tmp=aX[1].y+aX[3].y; tmp2=aX[1].y-aX[3].y; aX[1].y=tmp; | |
1003 tmp=aX[3].x-aX[1].x; aX[1].x+=aX[3].x; aX[3].x=tmp2; aX[3].y=tmp; | |
1004 tmp=aX[0].x+aX[1].x; aX[1].x=aX[0].x-aX[1].x; aX[0].x=tmp; | |
1005 tmp=aX[0].y+aX[1].y; aX[1].y=aX[0].y-aX[1].y; aX[0].y=tmp; | |
1006 tmp=aX[2].x+aX[3].x; aX[3].x=aX[2].x-aX[3].x; aX[2].x=tmp; | |
1007 tmp=aX[2].y+aX[3].y; aX[3].y=aX[2].y-aX[3].y; aX[2].y=tmp; | |
1008 } | |
1009 else //n>3 | |
1010 { | |
1011 cdouble *aX=&X[n][l*M+M/2]; | |
1012 for (int an=1, aL=1, aM=M/2; an<n; aL*=2, aM/=2, an++) | |
1013 { | |
1014 for (int al=0; al<aL; al++) | |
1015 for (int am=0; am<aM/2; am++) | |
1016 { | |
1017 int iw=am*2*aL*L; | |
1018 cdouble *lX=&aX[al*aM]; | |
1019 double x1r=lX[am].x, x1i=lX[am].y, | |
1020 x2r=lX[aM/2+am].x, x2i=lX[aM/2+am].y; | |
1021 lX[am].x=x1r+x2r, lX[am].y=x1i+x2i; | |
1022 x1r=x1r-x2r, x1i=x1i-x2i; | |
1023 lX[aM/2+am].x=x1r*W[iw].x-x1i*W[iw].y, | |
1024 lX[aM/2+am].y=x1r*W[iw].y+x1i*W[iw].x; | |
1025 } | |
1026 } | |
1027 } | |
1028 } | |
1029 } | |
1030 }//CMFTC | |
1031 | |
1032 | |
1033 //--------------------------------------------------------------------------- | |
1034 /* | |
1035 Old versions no longer in use. For reference only. | |
1036 */ | |
1037 void RFFTC_ual_old(double* Input, double *Amp, double *Arg, int Order, cdouble* W, double* XR, double* XI, int* bitinv) | |
1038 { | |
1039 int N=1<<Order, i, j, jj, k, *bitinv1=bitinv, Groups, ElemsPerGroup, X0, X1, X2; | |
1040 cdouble Temp, zp, zn; | |
1041 | |
1042 if (!bitinv) bitinv=CreateBitInvTable(Order); | |
1043 if (XR!=Input) for (i=0; i<N; i++) XR[i]=Input[bitinv[i]]; | |
1044 else for (i=0; i<N; i++) {jj=bitinv[i]; if (i<jj) {Temp.x=XR[i]; XR[i]=XR[jj]; XR[jj]=Temp.x;}} | |
1045 N/=2; | |
1046 double* XII=&XR[N]; | |
1047 Order--; | |
1048 if (!bitinv1) free(bitinv); | |
1049 for (i=0; i<Order; i++) | |
1050 { | |
1051 ElemsPerGroup=1<<i; | |
1052 Groups=1<<(Order-i-1); | |
1053 X0=0; | |
1054 for (j=0; j<Groups; j++) | |
1055 { | |
1056 for (k=0; k<ElemsPerGroup; k++) | |
1057 { | |
1058 X1=X0+k; | |
1059 X2=X1+ElemsPerGroup; | |
1060 int kGroups=k*2*Groups; | |
1061 Temp.x=XR[X2]*W[kGroups].x-XII[X2]*W[kGroups].y, | |
1062 XII[X2]=XR[X2]*W[kGroups].y+XII[X2]*W[kGroups].x; | |
1063 XR[X2]=Temp.x; | |
1064 Temp.x=XR[X1]+XR[X2], Temp.y=XII[X1]+XII[X2]; | |
1065 XR[X2]=XR[X1]-XR[X2], XII[X2]=XII[X1]-XII[X2]; | |
1066 XR[X1]=Temp.x, XII[X1]=Temp.y; | |
1067 } | |
1068 X0=X0+(ElemsPerGroup<<1); | |
1069 } | |
1070 } | |
1071 zp.x=XR[0]+XII[0], zn.x=XR[0]-XII[0]; | |
1072 XR[0]=zp.x; | |
1073 XI[0]=0; | |
1074 XR[N]=zn.x; | |
1075 XI[N]=0; | |
1076 for (int k=1; k<N/2; k++) | |
1077 { | |
1078 zp.x=XR[k]+XR[N-k], zn.x=XR[k]-XR[N-k], | |
1079 zp.y=XII[k]+XII[N-k], zn.y=XII[k]-XII[N-k]; | |
1080 XR[k]=0.5*(zp.x+W[k].y*zn.x+W[k].x*zp.y); | |
1081 XI[k]=0.5*(zn.y-W[k].x*zn.x+W[k].y*zp.y); | |
1082 XR[N-k]=0.5*(zp.x-W[k].y*zn.x-W[k].x*zp.y); | |
1083 XI[N-k]=0.5*(-zn.y-W[k].x*zn.x+W[k].y*zp.y); | |
1084 } | |
1085 XR[N/2]=XR[N/2]; | |
1086 XI[N/2]=-XII[N/2]; | |
1087 N*=2; | |
1088 | |
1089 for (int k=N/2+1; k<N; k++) XR[k]=XR[N-k], XI[k]=-XI[N-k]; | |
1090 if (Amp) for (i=0; i<N; i++) Amp[i]=sqrt(XR[i]*XR[i]+XI[i]*XI[i]); | |
1091 if (Arg) for (i=0; i<N; i++) Arg[i]=Atan2(XI[i], XR[i]); | |
1092 }//RFFTC_ual_old | |
1093 | |
1094 void CIFFTR_old(cdouble* Input, int Order, cdouble* W, double* X, int* bitinv) | |
1095 { | |
1096 int N=1<<Order, i, j, k, Groups, ElemsPerGroup, X0, X1, X2, *bitinv1=bitinv; | |
1097 cdouble Temp; | |
1098 if (!bitinv) bitinv=CreateBitInvTable(Order); | |
1099 | |
1100 Order--; | |
1101 N/=2; | |
1102 double* XII=&X[N]; | |
1103 | |
1104 X[0]=0.5*(Input[0].x+Input[N].x); | |
1105 XII[0]=0.5*(Input[0].x-Input[N].x); | |
1106 for (int i=1; i<N/2; i++) | |
1107 { | |
1108 double frp=Input[i].x+Input[N-i].x, frn=Input[i].x-Input[N-i].x, | |
1109 fip=Input[i].y+Input[N-i].y, fin=Input[i].y-Input[N-i].y; | |
1110 X[i]=0.5*(frp+frn*W[i].y-fip*W[i].x); | |
1111 XII[i]=0.5*(fin+frn*W[i].x+fip*W[i].y); | |
1112 X[N-i]=0.5*(frp-frn*W[i].y+fip*W[i].x); | |
1113 XII[N-i]=0.5*(-fin+frn*W[i].x+fip*W[i].y); | |
1114 } | |
1115 X[N/2]=Input[N/2].x; | |
1116 XII[N/2]=-Input[N/2].y; | |
1117 | |
1118 ElemsPerGroup=1<<Order; | |
1119 Groups=1; | |
1120 | |
1121 for (i=0; i<Order; i++) | |
1122 { | |
1123 ElemsPerGroup/=2; | |
1124 X0=0; | |
1125 for (j=0; j<Groups; j++) | |
1126 { | |
1127 int kGroups=bitinv[j]/2; | |
1128 for (k=0; k<ElemsPerGroup; k++) | |
1129 { | |
1130 X1=X0+k; | |
1131 X2=X1+ElemsPerGroup; | |
1132 Temp.x=X[X2]*W[kGroups].x+XII[X2]*W[kGroups].y, | |
1133 XII[X2]=-X[X2]*W[kGroups].y+XII[X2]*W[kGroups].x; | |
1134 X[X2]=Temp.x; | |
1135 Temp.x=X[X1]+X[X2], Temp.y=XII[X1]+XII[X2]; | |
1136 X[X2]=X[X1]-X[X2], XII[X2]=XII[X1]-XII[X2]; | |
1137 X[X1]=Temp.x, XII[X1]=Temp.y; | |
1138 } | |
1139 X0=X0+(ElemsPerGroup<<1); | |
1140 } | |
1141 Groups*=2; | |
1142 } | |
1143 | |
1144 N*=2; | |
1145 Order++; | |
1146 for (i=0; i<N; i++) | |
1147 { | |
1148 int jj=bitinv[i]; | |
1149 if (i<jj) | |
1150 { | |
1151 Temp.x=X[i]; | |
1152 X[i]=X[jj]; | |
1153 X[jj]=Temp.x; | |
1154 } | |
1155 } | |
1156 for (int i=0; i<N; i++) X[i]/=(N/2); | |
1157 if (!bitinv1) free(bitinv); | |
1158 }//RFFTC_ual_old | |
1159 |