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