00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "FFT_ooura.hxx"
00024
00025 #include "Assert.hxx"
00026 #include "Audio.hxx"
00027 #include "Spectrum.hxx"
00028 #include "SpectrumConfig.hxx"
00029 #include "CLAM_Math.hxx"
00030 #include "ProcessingFactory.hxx"
00031
00032 namespace CLAM
00033 {
00034
00035 namespace Hidden
00036 {
00037 static const char * metadata[] = {
00038 "key", "FFT_ooura",
00039 "category", "Analysis",
00040 "description", "FFT_ooura",
00041 0
00042 };
00043 static FactoryRegistrator<ProcessingFactory, FFT_ooura> reg = metadata;
00044 }
00045
00046 bool FFT_ooura::ConcreteConfigure(const ProcessingConfig& c) {
00047 int oldSize=mSize;
00048 FFT_base::ConcreteConfigure(c);
00049 if ( !isPowerOfTwo( mSize ) )
00050 {
00051 AddConfigErrorMessage("Configure failed: FFT Ooura algorithm only works for input buffers that are a power of two!");
00052 return false;
00053 }
00054 if (mSize>0) {
00055 if (mSize != oldSize) {
00056 ReleaseMemory();
00057 SetupMemory();
00058 }
00059 return true;
00060 }
00061 ReleaseMemory();
00062 return false;
00063 }
00064
00065 void FFT_ooura::ReleaseMemory() {
00066 if (ip) { delete[] ip; ip = 0; }
00067 if (w) { delete[] w; w = 0; }
00068 }
00069
00070 void FFT_ooura::SetupMemory() {
00071 int ipSize = (int)(2+(1<<(int)(log(mSize/2+0.5)/log(2.0))/2));
00072 ip = new int[ipSize];
00073 for (int i=0; i<ipSize; i++) ip[i] = 0;
00074
00075 int wSize = (int)(mSize*5/8-1);
00076 w = new TData[wSize];
00077 for (int i=0; i<wSize; i++) w[i] = 0;
00078 }
00079
00080 FFT_ooura::FFT_ooura()
00081 : ip(0), w(0)
00082 {
00083 Configure(FFTConfig());
00084 }
00085
00086 FFT_ooura::FFT_ooura(const FFTConfig &c) throw(ErrDynamicType)
00087 : ip(0), w(0)
00088 {
00089 Configure(c);
00090 };
00091
00092 FFT_ooura::~FFT_ooura()
00093 {
00094 ReleaseMemory();
00095 }
00096
00097 bool FFT_ooura::Do()
00098 {
00099 mOutput.GetData().SetSize( mInput.GetSize()/2+1);
00100 bool toReturn = Do(mInput.GetAudio(), mOutput.GetData());
00101 mInput.Consume();
00102 mOutput.Produce();
00103 return toReturn;
00104 }
00105
00106 bool FFT_ooura::Do(const Audio& in, Spectrum &out){
00107 TData *inbuffer;
00108
00109 CLAM_DEBUG_ASSERT(IsRunning(),
00110 "FFT_ooura: Do(): Not in execution mode");
00111 CLAM_DEBUG_ASSERT(isPowerOfTwo(mSize),
00112 "FFT_ooura: Do(): Not a power of two");
00113
00114 out.SetSpectralRange(in.GetSampleRate()/2);
00115
00116 switch(mState) {
00117 case sComplex:
00118 inbuffer = in.GetBuffer().GetPtr();
00119
00120
00121
00122 for (int i=0; i<mSize; i++)
00123 fftbuffer[i] = inbuffer[i];
00124 rdft(mSize, 1, fftbuffer, ip, w);
00125 ToComplex(out);
00126 break;
00127 case sComplexSync:
00128 inbuffer = in.GetBuffer().GetPtr();
00129
00130
00131
00132 for (int i=0; i<mSize; i++)
00133 fftbuffer[i]=inbuffer[i];
00134 rdft(mSize, 1, fftbuffer, ip, w);
00135 ToComplex(out);
00136 out.SynchronizeTo(mComplexflags);
00137 break;
00138 case sOther:
00139 CheckTypes(in,out);
00140 inbuffer = in.GetBuffer().GetPtr();
00141
00142
00143
00144 for (int i=0; i<mSize; i++)
00145 fftbuffer[i]=inbuffer[i];
00146 rdft(mSize, 1, fftbuffer, ip, w);
00147
00148 ToOther(out);
00149 break;
00150 default:
00151 CLAM_ASSERT(false, "FFT_ooura: Do(): Inconsistent state");
00152 }
00153
00154 return true;
00155 }
00156
00157
00158 void FFT_ooura::ToComplex(Spectrum &out) {
00159 Array<Complex>& outbuffer = out.GetComplexArray();
00160
00161 outbuffer[0].SetReal(fftbuffer[0]);
00162 outbuffer[0].SetImag(0);
00163 outbuffer[mSize/2].SetReal(fftbuffer[1]);
00164 outbuffer[mSize/2].SetImag(0);
00165
00166 for (int i=1; i<mSize/2; i++) {
00167 outbuffer[i].SetReal(fftbuffer[2*i]);
00168 outbuffer[i].SetImag(-fftbuffer[2*i+1]);
00169 }
00170
00171 outbuffer.SetSize(mSize/2+1);
00172 }
00173
00174 void FFT_ooura::ToOther(Spectrum &out)
00175 {
00176 if(out.HasComplexArray()) {
00177 ToComplex(out);
00178 out.SynchronizeTo(mComplexflags);
00179 }
00180 else {
00181 SpecTypeFlags flags;
00182 out.GetType(flags);
00183
00184
00185 ToComplex(mComplexSpectrum);
00186 out.SynchronizeTo(mComplexSpectrum);
00187 }
00188 }
00189
00190
00192
00193
00194 void FFT_ooura::rdft(int n, int isgn, TData *a, int *ip, TData *w)
00195 {
00196 int nw, nc;
00197 TData xi;
00198
00199 nw = ip[0];
00200 if (n > (nw << 2)) {
00201 nw = n >> 2;
00202 makewt(nw, ip, w);
00203 }
00204 nc = ip[1];
00205 if (n > (nc << 2)) {
00206 nc = n >> 2;
00207 makect(nc, ip, w + nw);
00208 }
00209 if (isgn >= 0) {
00210 if (n > 4) {
00211 bitrv2(n, ip + 2, a);
00212 cftfsub(n, a, w);
00213 rftfsub(n, a, nc, w + nw);
00214 } else if (n == 4) {
00215 cftfsub(n, a, w);
00216 }
00217 xi = a[0] - a[1];
00218 a[0] += a[1];
00219 a[1] = xi;
00220 } else {
00221 a[1] = 0.5 * (a[0] - a[1]);
00222 a[0] -= a[1];
00223 if (n > 4) {
00224 rftbsub(n, a, nc, w + nw);
00225 bitrv2(n, ip + 2, a);
00226 cftbsub(n, a, w);
00227 } else if (n == 4) {
00228 cftfsub(n, a, w);
00229 }
00230 }
00231 }
00232
00233
00234
00235 void FFT_ooura::makewt(int nw, int *ip, TData *w)
00236 {
00237 int j, nwh;
00238 TData delta, x, y;
00239
00240 ip[0] = nw;
00241 ip[1] = 1;
00242 if (nw > 2) {
00243 nwh = nw >> 1;
00244 delta = CLAM_atan(1.0) / nwh;
00245 w[0] = 1;
00246 w[1] = 0;
00247 w[nwh] = CLAM_cos(delta * nwh);
00248 w[nwh + 1] = w[nwh];
00249 if (nwh > 2) {
00250 for (j = 2; j < nwh; j += 2) {
00251 x = CLAM_cos(delta * j);
00252 y = CLAM_sin(delta * j);
00253 w[j] = x;
00254 w[j + 1] = y;
00255 w[nw - j] = y;
00256 w[nw - j + 1] = x;
00257 }
00258 bitrv2(nw, ip + 2, w);
00259 }
00260 }
00261 }
00262
00263
00264 void FFT_ooura::makect(int nc, int *ip, TData *c)
00265 {
00266 int j, nch;
00267 TData delta;
00268
00269 ip[1] = nc;
00270 if (nc > 1) {
00271 nch = nc >> 1;
00272 delta = CLAM_atan(1.0) / nch;
00273 c[0] = CLAM_cos(delta * nch);
00274 c[nch] = 0.5 * c[0];
00275 for (j = 1; j < nch; j++) {
00276 c[j] = 0.5 * CLAM_cos(delta * j);
00277 c[nc - j] = 0.5 * CLAM_sin(delta * j);
00278 }
00279 }
00280 }
00281
00282 void FFT_ooura::bitrv2(int n, int *ip, TData *a)
00283 {
00284 int j, j1, k, k1, l, m, m2;
00285 TData xr, xi, yr, yi;
00286
00287 ip[0] = 0;
00288 l = n;
00289 m = 1;
00290 while ((m << 3) < l) {
00291 l >>= 1;
00292 for (j = 0; j < m; j++) {
00293 ip[m + j] = ip[j] + l;
00294 }
00295 m <<= 1;
00296 }
00297 m2 = 2 * m;
00298 if ((m << 3) == l) {
00299 for (k = 0; k < m; k++) {
00300 for (j = 0; j < k; j++) {
00301 j1 = 2 * j + ip[k];
00302 k1 = 2 * k + ip[j];
00303 xr = a[j1];
00304 xi = a[j1 + 1];
00305 yr = a[k1];
00306 yi = a[k1 + 1];
00307 a[j1] = yr;
00308 a[j1 + 1] = yi;
00309 a[k1] = xr;
00310 a[k1 + 1] = xi;
00311 j1 += m2;
00312 k1 += 2 * m2;
00313 xr = a[j1];
00314 xi = a[j1 + 1];
00315 yr = a[k1];
00316 yi = a[k1 + 1];
00317 a[j1] = yr;
00318 a[j1 + 1] = yi;
00319 a[k1] = xr;
00320 a[k1 + 1] = xi;
00321 j1 += m2;
00322 k1 -= m2;
00323 xr = a[j1];
00324 xi = a[j1 + 1];
00325 yr = a[k1];
00326 yi = a[k1 + 1];
00327 a[j1] = yr;
00328 a[j1 + 1] = yi;
00329 a[k1] = xr;
00330 a[k1 + 1] = xi;
00331 j1 += m2;
00332 k1 += 2 * m2;
00333 xr = a[j1];
00334 xi = a[j1 + 1];
00335 yr = a[k1];
00336 yi = a[k1 + 1];
00337 a[j1] = yr;
00338 a[j1 + 1] = yi;
00339 a[k1] = xr;
00340 a[k1 + 1] = xi;
00341 }
00342 j1 = 2 * k + m2 + ip[k];
00343 k1 = j1 + m2;
00344 xr = a[j1];
00345 xi = a[j1 + 1];
00346 yr = a[k1];
00347 yi = a[k1 + 1];
00348 a[j1] = yr;
00349 a[j1 + 1] = yi;
00350 a[k1] = xr;
00351 a[k1 + 1] = xi;
00352 }
00353 } else {
00354 for (k = 1; k < m; k++) {
00355 for (j = 0; j < k; j++) {
00356 j1 = 2 * j + ip[k];
00357 k1 = 2 * k + ip[j];
00358 xr = a[j1];
00359 xi = a[j1 + 1];
00360 yr = a[k1];
00361 yi = a[k1 + 1];
00362 a[j1] = yr;
00363 a[j1 + 1] = yi;
00364 a[k1] = xr;
00365 a[k1 + 1] = xi;
00366 j1 += m2;
00367 k1 += m2;
00368 xr = a[j1];
00369 xi = a[j1 + 1];
00370 yr = a[k1];
00371 yi = a[k1 + 1];
00372 a[j1] = yr;
00373 a[j1 + 1] = yi;
00374 a[k1] = xr;
00375 a[k1 + 1] = xi;
00376 }
00377 }
00378 }
00379 }
00380
00381 void FFT_ooura::cftfsub(int n, TData *a, TData *w)
00382 {
00383 int j, j1, j2, j3, l;
00384 TData x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
00385
00386 l = 2;
00387 if (n > 8) {
00388 cft1st(n, a, w);
00389 l = 8;
00390 while ((l << 2) < n) {
00391 cftmdl(n, l, a, w);
00392 l <<= 2;
00393 }
00394 }
00395 if ((l << 2) == n) {
00396 for (j = 0; j < l; j += 2) {
00397 j1 = j + l;
00398 j2 = j1 + l;
00399 j3 = j2 + l;
00400 x0r = a[j] + a[j1];
00401 x0i = a[j + 1] + a[j1 + 1];
00402 x1r = a[j] - a[j1];
00403 x1i = a[j + 1] - a[j1 + 1];
00404 x2r = a[j2] + a[j3];
00405 x2i = a[j2 + 1] + a[j3 + 1];
00406 x3r = a[j2] - a[j3];
00407 x3i = a[j2 + 1] - a[j3 + 1];
00408 a[j] = x0r + x2r;
00409 a[j + 1] = x0i + x2i;
00410 a[j2] = x0r - x2r;
00411 a[j2 + 1] = x0i - x2i;
00412 a[j1] = x1r - x3i;
00413 a[j1 + 1] = x1i + x3r;
00414 a[j3] = x1r + x3i;
00415 a[j3 + 1] = x1i - x3r;
00416 }
00417 } else {
00418 for (j = 0; j < l; j += 2) {
00419 j1 = j + l;
00420 x0r = a[j] - a[j1];
00421 x0i = a[j + 1] - a[j1 + 1];
00422 a[j] += a[j1];
00423 a[j + 1] += a[j1 + 1];
00424 a[j1] = x0r;
00425 a[j1 + 1] = x0i;
00426 }
00427 }
00428 }
00429
00430 void FFT_ooura::cftbsub(int n, TData *a, TData *w)
00431 {
00432 int j, j1, j2, j3, l;
00433 TData x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
00434
00435 l = 2;
00436 if (n > 8) {
00437 cft1st(n, a, w);
00438 l = 8;
00439 while ((l << 2) < n) {
00440 cftmdl(n, l, a, w);
00441 l <<= 2;
00442 }
00443 }
00444 if ((l << 2) == n) {
00445 for (j = 0; j < l; j += 2) {
00446 j1 = j + l;
00447 j2 = j1 + l;
00448 j3 = j2 + l;
00449 x0r = a[j] + a[j1];
00450 x0i = -a[j + 1] - a[j1 + 1];
00451 x1r = a[j] - a[j1];
00452 x1i = -a[j + 1] + a[j1 + 1];
00453 x2r = a[j2] + a[j3];
00454 x2i = a[j2 + 1] + a[j3 + 1];
00455 x3r = a[j2] - a[j3];
00456 x3i = a[j2 + 1] - a[j3 + 1];
00457 a[j] = x0r + x2r;
00458 a[j + 1] = x0i - x2i;
00459 a[j2] = x0r - x2r;
00460 a[j2 + 1] = x0i + x2i;
00461 a[j1] = x1r - x3i;
00462 a[j1 + 1] = x1i - x3r;
00463 a[j3] = x1r + x3i;
00464 a[j3 + 1] = x1i + x3r;
00465 }
00466 } else {
00467 for (j = 0; j < l; j += 2) {
00468 j1 = j + l;
00469 x0r = a[j] - a[j1];
00470 x0i = -a[j + 1] + a[j1 + 1];
00471 a[j] += a[j1];
00472 a[j + 1] = -a[j + 1] - a[j1 + 1];
00473 a[j1] = x0r;
00474 a[j1 + 1] = x0i;
00475 }
00476 }
00477 }
00478
00479 void FFT_ooura::cft1st(int n, TData *a, TData *w)
00480 {
00481 int j, k1, k2;
00482 TData wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
00483 TData x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
00484
00485 x0r = a[0] + a[2];
00486 x0i = a[1] + a[3];
00487 x1r = a[0] - a[2];
00488 x1i = a[1] - a[3];
00489 x2r = a[4] + a[6];
00490 x2i = a[5] + a[7];
00491 x3r = a[4] - a[6];
00492 x3i = a[5] - a[7];
00493 a[0] = x0r + x2r;
00494 a[1] = x0i + x2i;
00495 a[4] = x0r - x2r;
00496 a[5] = x0i - x2i;
00497 a[2] = x1r - x3i;
00498 a[3] = x1i + x3r;
00499 a[6] = x1r + x3i;
00500 a[7] = x1i - x3r;
00501 wk1r = w[2];
00502 x0r = a[8] + a[10];
00503 x0i = a[9] + a[11];
00504 x1r = a[8] - a[10];
00505 x1i = a[9] - a[11];
00506 x2r = a[12] + a[14];
00507 x2i = a[13] + a[15];
00508 x3r = a[12] - a[14];
00509 x3i = a[13] - a[15];
00510 a[8] = x0r + x2r;
00511 a[9] = x0i + x2i;
00512 a[12] = x2i - x0i;
00513 a[13] = x0r - x2r;
00514 x0r = x1r - x3i;
00515 x0i = x1i + x3r;
00516 a[10] = wk1r * (x0r - x0i);
00517 a[11] = wk1r * (x0r + x0i);
00518 x0r = x3i + x1r;
00519 x0i = x3r - x1i;
00520 a[14] = wk1r * (x0i - x0r);
00521 a[15] = wk1r * (x0i + x0r);
00522 k1 = 0;
00523 for (j = 16; j < n; j += 16) {
00524 k1 += 2;
00525 k2 = 2 * k1;
00526 wk2r = w[k1];
00527 wk2i = w[k1 + 1];
00528 wk1r = w[k2];
00529 wk1i = w[k2 + 1];
00530 wk3r = wk1r - 2 * wk2i * wk1i;
00531 wk3i = 2 * wk2i * wk1r - wk1i;
00532 x0r = a[j] + a[j + 2];
00533 x0i = a[j + 1] + a[j + 3];
00534 x1r = a[j] - a[j + 2];
00535 x1i = a[j + 1] - a[j + 3];
00536 x2r = a[j + 4] + a[j + 6];
00537 x2i = a[j + 5] + a[j + 7];
00538 x3r = a[j + 4] - a[j + 6];
00539 x3i = a[j + 5] - a[j + 7];
00540 a[j] = x0r + x2r;
00541 a[j + 1] = x0i + x2i;
00542 x0r -= x2r;
00543 x0i -= x2i;
00544 a[j + 4] = wk2r * x0r - wk2i * x0i;
00545 a[j + 5] = wk2r * x0i + wk2i * x0r;
00546 x0r = x1r - x3i;
00547 x0i = x1i + x3r;
00548 a[j + 2] = wk1r * x0r - wk1i * x0i;
00549 a[j + 3] = wk1r * x0i + wk1i * x0r;
00550 x0r = x1r + x3i;
00551 x0i = x1i - x3r;
00552 a[j + 6] = wk3r * x0r - wk3i * x0i;
00553 a[j + 7] = wk3r * x0i + wk3i * x0r;
00554 wk1r = w[k2 + 2];
00555 wk1i = w[k2 + 3];
00556 wk3r = wk1r - 2 * wk2r * wk1i;
00557 wk3i = 2 * wk2r * wk1r - wk1i;
00558 x0r = a[j + 8] + a[j + 10];
00559 x0i = a[j + 9] + a[j + 11];
00560 x1r = a[j + 8] - a[j + 10];
00561 x1i = a[j + 9] - a[j + 11];
00562 x2r = a[j + 12] + a[j + 14];
00563 x2i = a[j + 13] + a[j + 15];
00564 x3r = a[j + 12] - a[j + 14];
00565 x3i = a[j + 13] - a[j + 15];
00566 a[j + 8] = x0r + x2r;
00567 a[j + 9] = x0i + x2i;
00568 x0r -= x2r;
00569 x0i -= x2i;
00570 a[j + 12] = -wk2i * x0r - wk2r * x0i;
00571 a[j + 13] = -wk2i * x0i + wk2r * x0r;
00572 x0r = x1r - x3i;
00573 x0i = x1i + x3r;
00574 a[j + 10] = wk1r * x0r - wk1i * x0i;
00575 a[j + 11] = wk1r * x0i + wk1i * x0r;
00576 x0r = x1r + x3i;
00577 x0i = x1i - x3r;
00578 a[j + 14] = wk3r * x0r - wk3i * x0i;
00579 a[j + 15] = wk3r * x0i + wk3i * x0r;
00580 }
00581 }
00582
00583
00584 void FFT_ooura::cftmdl(int n, int l, TData *a, TData *w)
00585 {
00586 int j, j1, j2, j3, k, k1, k2, m, m2;
00587 TData wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
00588 TData x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
00589
00590 m = l << 2;
00591 for (j = 0; j < l; j += 2) {
00592 j1 = j + l;
00593 j2 = j1 + l;
00594 j3 = j2 + l;
00595 x0r = a[j] + a[j1];
00596 x0i = a[j + 1] + a[j1 + 1];
00597 x1r = a[j] - a[j1];
00598 x1i = a[j + 1] - a[j1 + 1];
00599 x2r = a[j2] + a[j3];
00600 x2i = a[j2 + 1] + a[j3 + 1];
00601 x3r = a[j2] - a[j3];
00602 x3i = a[j2 + 1] - a[j3 + 1];
00603 a[j] = x0r + x2r;
00604 a[j + 1] = x0i + x2i;
00605 a[j2] = x0r - x2r;
00606 a[j2 + 1] = x0i - x2i;
00607 a[j1] = x1r - x3i;
00608 a[j1 + 1] = x1i + x3r;
00609 a[j3] = x1r + x3i;
00610 a[j3 + 1] = x1i - x3r;
00611 }
00612 wk1r = w[2];
00613 for (j = m; j < l + m; j += 2) {
00614 j1 = j + l;
00615 j2 = j1 + l;
00616 j3 = j2 + l;
00617 x0r = a[j] + a[j1];
00618 x0i = a[j + 1] + a[j1 + 1];
00619 x1r = a[j] - a[j1];
00620 x1i = a[j + 1] - a[j1 + 1];
00621 x2r = a[j2] + a[j3];
00622 x2i = a[j2 + 1] + a[j3 + 1];
00623 x3r = a[j2] - a[j3];
00624 x3i = a[j2 + 1] - a[j3 + 1];
00625 a[j] = x0r + x2r;
00626 a[j + 1] = x0i + x2i;
00627 a[j2] = x2i - x0i;
00628 a[j2 + 1] = x0r - x2r;
00629 x0r = x1r - x3i;
00630 x0i = x1i + x3r;
00631 a[j1] = wk1r * (x0r - x0i);
00632 a[j1 + 1] = wk1r * (x0r + x0i);
00633 x0r = x3i + x1r;
00634 x0i = x3r - x1i;
00635 a[j3] = wk1r * (x0i - x0r);
00636 a[j3 + 1] = wk1r * (x0i + x0r);
00637 }
00638 k1 = 0;
00639 m2 = 2 * m;
00640 for (k = m2; k < n; k += m2) {
00641 k1 += 2;
00642 k2 = 2 * k1;
00643 wk2r = w[k1];
00644 wk2i = w[k1 + 1];
00645 wk1r = w[k2];
00646 wk1i = w[k2 + 1];
00647 wk3r = wk1r - 2 * wk2i * wk1i;
00648 wk3i = 2 * wk2i * wk1r - wk1i;
00649 for (j = k; j < l + k; j += 2) {
00650 j1 = j + l;
00651 j2 = j1 + l;
00652 j3 = j2 + l;
00653 x0r = a[j] + a[j1];
00654 x0i = a[j + 1] + a[j1 + 1];
00655 x1r = a[j] - a[j1];
00656 x1i = a[j + 1] - a[j1 + 1];
00657 x2r = a[j2] + a[j3];
00658 x2i = a[j2 + 1] + a[j3 + 1];
00659 x3r = a[j2] - a[j3];
00660 x3i = a[j2 + 1] - a[j3 + 1];
00661 a[j] = x0r + x2r;
00662 a[j + 1] = x0i + x2i;
00663 x0r -= x2r;
00664 x0i -= x2i;
00665 a[j2] = wk2r * x0r - wk2i * x0i;
00666 a[j2 + 1] = wk2r * x0i + wk2i * x0r;
00667 x0r = x1r - x3i;
00668 x0i = x1i + x3r;
00669 a[j1] = wk1r * x0r - wk1i * x0i;
00670 a[j1 + 1] = wk1r * x0i + wk1i * x0r;
00671 x0r = x1r + x3i;
00672 x0i = x1i - x3r;
00673 a[j3] = wk3r * x0r - wk3i * x0i;
00674 a[j3 + 1] = wk3r * x0i + wk3i * x0r;
00675 }
00676 wk1r = w[k2 + 2];
00677 wk1i = w[k2 + 3];
00678 wk3r = wk1r - 2 * wk2r * wk1i;
00679 wk3i = 2 * wk2r * wk1r - wk1i;
00680 for (j = k + m; j < l + (k + m); j += 2) {
00681 j1 = j + l;
00682 j2 = j1 + l;
00683 j3 = j2 + l;
00684 x0r = a[j] + a[j1];
00685 x0i = a[j + 1] + a[j1 + 1];
00686 x1r = a[j] - a[j1];
00687 x1i = a[j + 1] - a[j1 + 1];
00688 x2r = a[j2] + a[j3];
00689 x2i = a[j2 + 1] + a[j3 + 1];
00690 x3r = a[j2] - a[j3];
00691 x3i = a[j2 + 1] - a[j3 + 1];
00692 a[j] = x0r + x2r;
00693 a[j + 1] = x0i + x2i;
00694 x0r -= x2r;
00695 x0i -= x2i;
00696 a[j2] = -wk2i * x0r - wk2r * x0i;
00697 a[j2 + 1] = -wk2i * x0i + wk2r * x0r;
00698 x0r = x1r - x3i;
00699 x0i = x1i + x3r;
00700 a[j1] = wk1r * x0r - wk1i * x0i;
00701 a[j1 + 1] = wk1r * x0i + wk1i * x0r;
00702 x0r = x1r + x3i;
00703 x0i = x1i - x3r;
00704 a[j3] = wk3r * x0r - wk3i * x0i;
00705 a[j3 + 1] = wk3r * x0i + wk3i * x0r;
00706 }
00707 }
00708 }
00709
00710
00711 void FFT_ooura::rftfsub(int n, TData *a, int nc, TData *c)
00712 {
00713 int j, k, kk, ks, m;
00714 TData wkr, wki, xr, xi, yr, yi;
00715
00716 m = n >> 1;
00717 ks = 2 * nc / m;
00718 kk = 0;
00719 for (j = 2; j < m; j += 2) {
00720 k = n - j;
00721 kk += ks;
00722 wkr = 0.5 - c[nc - kk];
00723 wki = c[kk];
00724 xr = a[j] - a[k];
00725 xi = a[j + 1] + a[k + 1];
00726 yr = wkr * xr - wki * xi;
00727 yi = wkr * xi + wki * xr;
00728 a[j] -= yr;
00729 a[j + 1] -= yi;
00730 a[k] += yr;
00731 a[k + 1] -= yi;
00732 }
00733 }
00734
00735
00736 void FFT_ooura::rftbsub(int n, TData *a, int nc, TData *c)
00737 {
00738 int j, k, kk, ks, m;
00739 TData wkr, wki, xr, xi, yr, yi;
00740
00741 a[1] = -a[1];
00742 m = n >> 1;
00743 ks = 2 * nc / m;
00744 kk = 0;
00745 for (j = 2; j < m; j += 2) {
00746 k = n - j;
00747 kk += ks;
00748 wkr = 0.5 - c[nc - kk];
00749 wki = c[kk];
00750 xr = a[j] - a[k];
00751 xi = a[j + 1] + a[k + 1];
00752 yr = wkr * xr + wki * xi;
00753 yi = wkr * xi - wki * xr;
00754 a[j] -= yr;
00755 a[j + 1] = yi - a[j + 1];
00756 a[k] += yr;
00757 a[k + 1] = yi - a[k + 1];
00758 }
00759 a[m + 1] = -a[m + 1];
00760 }
00761
00762
00763 };
00764