annotate fft.cpp @ 2:fc19d45615d1

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