annotate fft.cpp @ 5:5f3c32dc6e17

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