001/* ***** BEGIN LICENSE BLOCK ***** 002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 003 * 004 * The contents of this file are subject to the Mozilla Public License Version 005 * 1.1 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * http://www.mozilla.org/MPL/ 008 * 009 * Software distributed under the License is distributed on an "AS IS" basis, 010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 011 * for the specific language governing rights and limitations under the 012 * License. 013 * 014 * The Original Code is JTransforms. 015 * 016 * The Initial Developer of the Original Code is 017 * Piotr Wendykier, Emory University. 018 * Portions created by the Initial Developer are Copyright (C) 2007-2009 019 * the Initial Developer. All Rights Reserved. 020 * 021 * Alternatively, the contents of this file may be used under the terms of 022 * either the GNU General Public License Version 2 or later (the "GPL"), or 023 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 024 * in which case the provisions of the GPL or the LGPL are applicable instead 025 * of those above. If you wish to allow use of your version of this file only 026 * under the terms of either the GPL or the LGPL, and not to allow others to 027 * use your version of this file under the terms of the MPL, indicate your 028 * decision by deleting the provisions above and replace them with the notice 029 * and other provisions required by the GPL or the LGPL. If you do not delete 030 * the provisions above, a recipient may use your version of this file under 031 * the terms of any one of the MPL, the GPL or the LGPL. 032 * 033 * ***** END LICENSE BLOCK ***** */ 034 035package edu.emory.mathcs.jtransforms.fft; 036 037import java.util.concurrent.Future; 038 039import edu.emory.mathcs.utils.ConcurrencyUtils; 040 041/** 042 * Computes 1D Discrete Fourier Transform (DFT) of complex and real, single 043 * precision data. The size of the data can be an arbitrary number. This is a 044 * parallel implementation of split-radix and mixed-radix algorithms optimized 045 * for SMP systems. <br> 046 * <br> 047 * This code is derived from General Purpose FFT Package written by Takuya Ooura 048 * (http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html) and from JFFTPack written 049 * by Baoshe Zhang (http://jfftpack.sourceforge.net/) 050 * 051 * @author Piotr Wendykier (piotr.wendykier@gmail.com) 052 * 053 */ 054public strictfp class FloatFFT_1D { 055 056 private static enum Plans { 057 SPLIT_RADIX, MIXED_RADIX, BLUESTEIN 058 } 059 060 private int n; 061 062 private int nBluestein; 063 064 private int[] ip; 065 066 private float[] w; 067 068 private int nw; 069 070 private int nc; 071 072 private float[] wtable; 073 074 private float[] wtable_r; 075 076 private float[] bk1; 077 078 private float[] bk2; 079 080 private Plans plan; 081 082 private static final int[] factors = { 4, 2, 3, 5 }; 083 084 private static final float PI = 3.14159265358979311599796346854418516f; 085 086 private static final float TWO_PI = 6.28318530717958623199592693708837032f; 087 088 /** 089 * Creates new instance of FloatFFT_1D. 090 * 091 * @param n 092 * size of data 093 */ 094 public FloatFFT_1D(int n) { 095 if (n < 1) { 096 throw new IllegalArgumentException("n must be greater than 0"); 097 } 098 this.n = n; 099 100 if (!ConcurrencyUtils.isPowerOf2(n)) { 101 if (getReminder(n, factors) >= 211) { 102 plan = Plans.BLUESTEIN; 103 nBluestein = ConcurrencyUtils.nextPow2(n * 2 - 1); 104 bk1 = new float[2 * nBluestein]; 105 bk2 = new float[2 * nBluestein]; 106 this.ip = new int[2 + (int) Math.ceil(2 + (1 << (int) (Math.log(nBluestein + 0.5) / Math.log(2)) / 2))]; 107 this.w = new float[nBluestein]; 108 int twon = 2 * nBluestein; 109 nw = ip[0]; 110 if (twon > (nw << 2)) { 111 nw = twon >> 2; 112 makewt(nw); 113 } 114 nc = ip[1]; 115 if (nBluestein > (nc << 2)) { 116 nc = nBluestein >> 2; 117 makect(nc, w, nw); 118 } 119 bluesteini(); 120 } else { 121 plan = Plans.MIXED_RADIX; 122 wtable = new float[4 * n + 15]; 123 wtable_r = new float[2 * n + 15]; 124 cffti(); 125 rffti(); 126 } 127 } else { 128 plan = Plans.SPLIT_RADIX; 129 this.ip = new int[2 + (int) Math.ceil(2 + (1 << (int) (Math.log(n + 0.5) / Math.log(2)) / 2))]; 130 this.w = new float[n]; 131 int twon = 2 * n; 132 nw = ip[0]; 133 if (twon > (nw << 2)) { 134 nw = twon >> 2; 135 makewt(nw); 136 } 137 nc = ip[1]; 138 if (n > (nc << 2)) { 139 nc = n >> 2; 140 makect(nc, w, nw); 141 } 142 } 143 } 144 145 /** 146 * Computes 1D forward DFT of complex data leaving the result in 147 * <code>a</code>. Complex number is stored as two float values in 148 * sequence: the real and imaginary part, i.e. the size of the input array 149 * must be greater or equal 2*n. The physical layout of the input data has 150 * to be as follows:<br> 151 * 152 * <pre> 153 * a[2*k] = Re[k], 154 * a[2*k+1] = Im[k], 0<=k<n 155 * </pre> 156 * 157 * @param a 158 * data to transform 159 */ 160 public void complexForward(float[] a) { 161 complexForward(a, 0); 162 } 163 164 /** 165 * Computes 1D forward DFT of complex data leaving the result in 166 * <code>a</code>. Complex number is stored as two float values in 167 * sequence: the real and imaginary part, i.e. the size of the input array 168 * must be greater or equal 2*n. The physical layout of the input data has 169 * to be as follows:<br> 170 * 171 * <pre> 172 * a[offa+2*k] = Re[k], 173 * a[offa+2*k+1] = Im[k], 0<=k<n 174 * </pre> 175 * 176 * @param a 177 * data to transform 178 * @param offa 179 * index of the first element in array <code>a</code> 180 */ 181 public void complexForward(float[] a, int offa) { 182 if (n == 1) 183 return; 184 switch (plan) { 185 case SPLIT_RADIX: 186 cftbsub(2 * n, a, offa, ip, nw, w); 187 break; 188 case MIXED_RADIX: 189 cfftf(a, offa, -1); 190 break; 191 case BLUESTEIN: 192 bluestein_complex(a, offa, -1); 193 break; 194 } 195 } 196 197 /** 198 * Computes 1D inverse DFT of complex data leaving the result in 199 * <code>a</code>. Complex number is stored as two float values in 200 * sequence: the real and imaginary part, i.e. the size of the input array 201 * must be greater or equal 2*n. The physical layout of the input data has 202 * to be as follows:<br> 203 * 204 * <pre> 205 * a[2*k] = Re[k], 206 * a[2*k+1] = Im[k], 0<=k<n 207 * </pre> 208 * 209 * @param a 210 * data to transform 211 * @param scale 212 * if true then scaling is performed 213 */ 214 public void complexInverse(float[] a, boolean scale) { 215 complexInverse(a, 0, scale); 216 } 217 218 /** 219 * Computes 1D inverse DFT of complex data leaving the result in 220 * <code>a</code>. Complex number is stored as two float values in 221 * sequence: the real and imaginary part, i.e. the size of the input array 222 * must be greater or equal 2*n. The physical layout of the input data has 223 * to be as follows:<br> 224 * 225 * <pre> 226 * a[offa+2*k] = Re[k], 227 * a[offa+2*k+1] = Im[k], 0<=k<n 228 * </pre> 229 * 230 * @param a 231 * data to transform 232 * @param offa 233 * index of the first element in array <code>a</code> 234 * @param scale 235 * if true then scaling is performed 236 */ 237 public void complexInverse(float[] a, int offa, boolean scale) { 238 if (n == 1) 239 return; 240 switch (plan) { 241 case SPLIT_RADIX: 242 cftfsub(2 * n, a, offa, ip, nw, w); 243 break; 244 case MIXED_RADIX: 245 cfftf(a, offa, +1); 246 break; 247 case BLUESTEIN: 248 bluestein_complex(a, offa, 1); 249 break; 250 } 251 if (scale) { 252 scale(n, a, offa, true); 253 } 254 } 255 256 /** 257 * Computes 1D forward DFT of real data leaving the result in <code>a</code> 258 * . The physical layout of the output data is as follows:<br> 259 * 260 * if n is even then 261 * 262 * <pre> 263 * a[2*k] = Re[k], 0<=k<n/2 264 * a[2*k+1] = Im[k], 0<k<n/2 265 * a[1] = Re[n/2] 266 * </pre> 267 * 268 * if n is odd then 269 * 270 * <pre> 271 * a[2*k] = Re[k], 0<=k<(n+1)/2 272 * a[2*k+1] = Im[k], 0<k<(n-1)/2 273 * a[1] = Im[(n-1)/2] 274 * </pre> 275 * 276 * This method computes only half of the elements of the real transform. The 277 * other half satisfies the symmetry condition. If you want the full real 278 * forward transform, use <code>realForwardFull</code>. To get back the 279 * original data, use <code>realInverse</code> on the output of this method. 280 * 281 * @param a 282 * data to transform 283 */ 284 public void realForward(float[] a) { 285 realForward(a, 0); 286 } 287 288 /** 289 * Computes 1D forward DFT of real data leaving the result in <code>a</code> 290 * . The physical layout of the output data is as follows:<br> 291 * 292 * if n is even then 293 * 294 * <pre> 295 * a[offa+2*k] = Re[k], 0<=k<n/2 296 * a[offa+2*k+1] = Im[k], 0<k<n/2 297 * a[offa+1] = Re[n/2] 298 * </pre> 299 * 300 * if n is odd then 301 * 302 * <pre> 303 * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 304 * a[offa+2*k+1] = Im[k], 0<k<(n-1)/2 305 * a[offa+1] = Im[(n-1)/2] 306 * </pre> 307 * 308 * This method computes only half of the elements of the real transform. The 309 * other half satisfies the symmetry condition. If you want the full real 310 * forward transform, use <code>realForwardFull</code>. To get back the 311 * original data, use <code>realInverse</code> on the output of this method. 312 * 313 * @param a 314 * data to transform 315 * @param offa 316 * index of the first element in array <code>a</code> 317 */ 318 public void realForward(float[] a, int offa) { 319 if (n == 1) 320 return; 321 322 switch (plan) { 323 case SPLIT_RADIX: 324 float xi; 325 326 if (n > 4) { 327 cftfsub(n, a, offa, ip, nw, w); 328 rftfsub(n, a, offa, nc, w, nw); 329 } else if (n == 4) { 330 cftx020(a, offa); 331 } 332 xi = a[offa] - a[offa + 1]; 333 a[offa] += a[offa + 1]; 334 a[offa + 1] = xi; 335 break; 336 case MIXED_RADIX: 337 rfftf(a, offa); 338 for (int k = n - 1; k >= 2; k--) { 339 int idx = offa + k; 340 float tmp = a[idx]; 341 a[idx] = a[idx - 1]; 342 a[idx - 1] = tmp; 343 } 344 break; 345 case BLUESTEIN: 346 bluestein_real_forward(a, offa); 347 break; 348 } 349 } 350 351 /** 352 * Computes 1D forward DFT of real data leaving the result in <code>a</code> 353 * . This method computes the full real forward transform, i.e. you will get 354 * the same result as from <code>complexForward</code> called with all 355 * imaginary parts equal 0. Because the result is stored in <code>a</code>, 356 * the size of the input array must greater or equal 2*n, with only the 357 * first n elements filled with real data. To get back the original data, 358 * use <code>complexInverse</code> on the output of this method. 359 * 360 * @param a 361 * data to transform 362 */ 363 public void realForwardFull(float[] a) { 364 realForwardFull(a, 0); 365 } 366 367 /** 368 * Computes 1D forward DFT of real data leaving the result in <code>a</code> 369 * . This method computes the full real forward transform, i.e. you will get 370 * the same result as from <code>complexForward</code> called with all 371 * imaginary part equal 0. Because the result is stored in <code>a</code>, 372 * the size of the input array must greater or equal 2*n, with only the 373 * first n elements filled with real data. To get back the original data, 374 * use <code>complexInverse</code> on the output of this method. 375 * 376 * @param a 377 * data to transform 378 * @param offa 379 * index of the first element in array <code>a</code> 380 */ 381 public void realForwardFull(final float[] a, final int offa) { 382 383 final int twon = 2 * n; 384 switch (plan) { 385 case SPLIT_RADIX: 386 realForward(a, offa); 387 int nthreads = ConcurrencyUtils.getNumberOfThreads(); 388 if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 389 Future<?>[] futures = new Future[nthreads]; 390 int k = n / 2 / nthreads; 391 for (int i = 0; i < nthreads; i++) { 392 final int firstIdx = i * k; 393 final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k; 394 futures[i] = ConcurrencyUtils.submit(new Runnable() { 395 public void run() { 396 int idx1, idx2; 397 for (int k = firstIdx; k < lastIdx; k++) { 398 idx1 = 2 * k; 399 idx2 = offa + ((twon - idx1) % twon); 400 a[idx2] = a[offa + idx1]; 401 a[idx2 + 1] = -a[offa + idx1 + 1]; 402 } 403 } 404 }); 405 } 406 ConcurrencyUtils.waitForCompletion(futures); 407 } else { 408 int idx1, idx2; 409 for (int k = 0; k < n / 2; k++) { 410 idx1 = 2 * k; 411 idx2 = offa + ((twon - idx1) % twon); 412 a[idx2] = a[offa + idx1]; 413 a[idx2 + 1] = -a[offa + idx1 + 1]; 414 } 415 } 416 a[offa + n] = -a[offa + 1]; 417 a[offa + 1] = 0; 418 break; 419 case MIXED_RADIX: 420 rfftf(a, offa); 421 int m; 422 if (n % 2 == 0) { 423 m = n / 2; 424 } else { 425 m = (n + 1) / 2; 426 } 427 for (int k = 1; k < m; k++) { 428 int idx1 = offa + twon - 2 * k; 429 int idx2 = offa + 2 * k; 430 a[idx1 + 1] = -a[idx2]; 431 a[idx1] = a[idx2 - 1]; 432 } 433 for (int k = 1; k < n; k++) { 434 int idx = offa + n - k; 435 float tmp = a[idx + 1]; 436 a[idx + 1] = a[idx]; 437 a[idx] = tmp; 438 } 439 a[offa + 1] = 0; 440 break; 441 case BLUESTEIN: 442 bluestein_real_full(a, offa, -1); 443 break; 444 } 445 } 446 447 /** 448 * Computes 1D inverse DFT of real data leaving the result in <code>a</code> 449 * . The physical layout of the input data has to be as follows:<br> 450 * 451 * if n is even then 452 * 453 * <pre> 454 * a[2*k] = Re[k], 0<=k<n/2 455 * a[2*k+1] = Im[k], 0<k<n/2 456 * a[1] = Re[n/2] 457 * </pre> 458 * 459 * if n is odd then 460 * 461 * <pre> 462 * a[2*k] = Re[k], 0<=k<(n+1)/2 463 * a[2*k+1] = Im[k], 0<k<(n-1)/2 464 * a[1] = Im[(n-1)/2] 465 * </pre> 466 * 467 * This method computes only half of the elements of the real transform. The 468 * other half satisfies the symmetry condition. If you want the full real 469 * inverse transform, use <code>realInverseFull</code>. 470 * 471 * @param a 472 * data to transform 473 * 474 * @param scale 475 * if true then scaling is performed 476 * 477 */ 478 public void realInverse(float[] a, boolean scale) { 479 realInverse(a, 0, scale); 480 } 481 482 /** 483 * Computes 1D inverse DFT of real data leaving the result in <code>a</code> 484 * . The physical layout of the input data has to be as follows:<br> 485 * 486 * if n is even then 487 * 488 * <pre> 489 * a[offa+2*k] = Re[k], 0<=k<n/2 490 * a[offa+2*k+1] = Im[k], 0<k<n/2 491 * a[offa+1] = Re[n/2] 492 * </pre> 493 * 494 * if n is odd then 495 * 496 * <pre> 497 * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 498 * a[offa+2*k+1] = Im[k], 0<k<(n-1)/2 499 * a[offa+1] = Im[(n-1)/2] 500 * </pre> 501 * 502 * This method computes only half of the elements of the real transform. The 503 * other half satisfies the symmetry condition. If you want the full real 504 * inverse transform, use <code>realInverseFull</code>. 505 * 506 * @param a 507 * data to transform 508 * @param offa 509 * index of the first element in array <code>a</code> 510 * @param scale 511 * if true then scaling is performed 512 * 513 */ 514 public void realInverse(float[] a, int offa, boolean scale) { 515 if (n == 1) 516 return; 517 switch (plan) { 518 case SPLIT_RADIX: 519 a[offa + 1] = (float)(0.5 * (a[offa] - a[offa + 1])); 520 a[offa] -= a[offa + 1]; 521 if (n > 4) { 522 rftfsub(n, a, offa, nc, w, nw); 523 cftbsub(n, a, offa, ip, nw, w); 524 } else if (n == 4) { 525 cftxc020(a, offa); 526 } 527 if (scale) { 528 scale(n / 2, a, offa, false); 529 } 530 break; 531 case MIXED_RADIX: 532 for (int k = 2; k < n; k++) { 533 int idx = offa + k; 534 float tmp = a[idx - 1]; 535 a[idx - 1] = a[idx]; 536 a[idx] = tmp; 537 } 538 rfftb(a, offa); 539 if (scale) { 540 scale(n, a, offa, false); 541 } 542 break; 543 case BLUESTEIN: 544 bluestein_real_inverse(a, offa); 545 if (scale) { 546 scale(n, a, offa, false); 547 } 548 break; 549 } 550 551 } 552 553 /** 554 * Computes 1D inverse DFT of real data leaving the result in <code>a</code> 555 * . This method computes the full real inverse transform, i.e. you will get 556 * the same result as from <code>complexInverse</code> called with all 557 * imaginary part equal 0. Because the result is stored in <code>a</code>, 558 * the size of the input array must greater or equal 2*n, with only the 559 * first n elements filled with real data. 560 * 561 * @param a 562 * data to transform 563 * @param scale 564 * if true then scaling is performed 565 */ 566 public void realInverseFull(float[] a, boolean scale) { 567 realInverseFull(a, 0, scale); 568 } 569 570 /** 571 * Computes 1D inverse DFT of real data leaving the result in <code>a</code> 572 * . This method computes the full real inverse transform, i.e. you will get 573 * the same result as from <code>complexInverse</code> called with all 574 * imaginary part equal 0. Because the result is stored in <code>a</code>, 575 * the size of the input array must greater or equal 2*n, with only the 576 * first n elements filled with real data. 577 * 578 * @param a 579 * data to transform 580 * @param offa 581 * index of the first element in array <code>a</code> 582 * @param scale 583 * if true then scaling is performed 584 */ 585 public void realInverseFull(final float[] a, final int offa, boolean scale) { 586 final int twon = 2 * n; 587 switch (plan) { 588 case SPLIT_RADIX: 589 realInverse2(a, offa, scale); 590 int nthreads = ConcurrencyUtils.getNumberOfThreads(); 591 if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 592 Future<?>[] futures = new Future[nthreads]; 593 int k = n / 2 / nthreads; 594 for (int i = 0; i < nthreads; i++) { 595 final int firstIdx = i * k; 596 final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k; 597 futures[i] = ConcurrencyUtils.submit(new Runnable() { 598 public void run() { 599 int idx1, idx2; 600 for (int k = firstIdx; k < lastIdx; k++) { 601 idx1 = 2 * k; 602 idx2 = offa + ((twon - idx1) % twon); 603 a[idx2] = a[offa + idx1]; 604 a[idx2 + 1] = -a[offa + idx1 + 1]; 605 } 606 } 607 }); 608 } 609 ConcurrencyUtils.waitForCompletion(futures); 610 } else { 611 int idx1, idx2; 612 for (int k = 0; k < n / 2; k++) { 613 idx1 = 2 * k; 614 idx2 = offa + ((twon - idx1) % twon); 615 a[idx2] = a[offa + idx1]; 616 a[idx2 + 1] = -a[offa + idx1 + 1]; 617 } 618 } 619 a[offa + n] = -a[offa + 1]; 620 a[offa + 1] = 0; 621 break; 622 case MIXED_RADIX: 623 rfftf(a, offa); 624 if (scale) { 625 scale(n, a, offa, false); 626 } 627 int m; 628 if (n % 2 == 0) { 629 m = n / 2; 630 } else { 631 m = (n + 1) / 2; 632 } 633 for (int k = 1; k < m; k++) { 634 int idx1 = offa + 2 * k; 635 int idx2 = offa + twon - 2 * k; 636 a[idx1] = -a[idx1]; 637 a[idx2 + 1] = -a[idx1]; 638 a[idx2] = a[idx1 - 1]; 639 } 640 for (int k = 1; k < n; k++) { 641 int idx = offa + n - k; 642 float tmp = a[idx + 1]; 643 a[idx + 1] = a[idx]; 644 a[idx] = tmp; 645 } 646 a[offa + 1] = 0; 647 break; 648 case BLUESTEIN: 649 bluestein_real_full(a, offa, 1); 650 if (scale) { 651 scale(n, a, offa, true); 652 } 653 break; 654 } 655 } 656 657 protected void realInverse2(float[] a, int offa, boolean scale) { 658 if (n == 1) 659 return; 660 switch (plan) { 661 case SPLIT_RADIX: 662 float xi; 663 664 if (n > 4) { 665 cftfsub(n, a, offa, ip, nw, w); 666 rftbsub(n, a, offa, nc, w, nw); 667 } else if (n == 4) { 668 cftbsub(n, a, offa, ip, nw, w); 669 } 670 xi = a[offa] - a[offa + 1]; 671 a[offa] += a[offa + 1]; 672 a[offa + 1] = xi; 673 if (scale) { 674 scale(n, a, offa, false); 675 } 676 break; 677 case MIXED_RADIX: 678 rfftf(a, offa); 679 for (int k = n - 1; k >= 2; k--) { 680 int idx = offa + k; 681 float tmp = a[idx]; 682 a[idx] = a[idx - 1]; 683 a[idx - 1] = tmp; 684 } 685 if (scale) { 686 scale(n, a, offa, false); 687 } 688 int m; 689 if (n % 2 == 0) { 690 m = n / 2; 691 for (int i = 1; i < m; i++) { 692 int idx = offa + 2 * i + 1; 693 a[idx] = -a[idx]; 694 } 695 } else { 696 m = (n - 1) / 2; 697 for (int i = 0; i < m; i++) { 698 int idx = offa + 2 * i + 1; 699 a[idx] = -a[idx]; 700 } 701 } 702 break; 703 case BLUESTEIN: 704 bluestein_real_inverse2(a, offa); 705 if (scale) { 706 scale(n, a, offa, false); 707 } 708 break; 709 } 710 } 711 712 private static int getReminder(int n, int factors[]) { 713 int reminder = n; 714 715 if (n <= 0) { 716 throw new IllegalArgumentException("n must be positive integer"); 717 } 718 719 for (int i = 0; i < factors.length && reminder != 1; i++) { 720 int factor = factors[i]; 721 while ((reminder % factor) == 0) { 722 reminder /= factor; 723 } 724 } 725 return reminder; 726 } 727 728 /* -------- initializing routines -------- */ 729 730 /*--------------------------------------------------------- 731 cffti: initialization of Complex FFT 732 --------------------------------------------------------*/ 733 734 void cffti(int n, int offw) { 735 if (n == 1) 736 return; 737 738 final int twon = 2 * n; 739 final int fourn = 4 * n; 740 float argh; 741 int idot, ntry = 0, i, j; 742 float argld; 743 int i1, k1, l1, l2, ib; 744 float fi; 745 int ld, ii, nf, ip, nl, nq, nr; 746 float arg; 747 int ido, ipm; 748 749 nl = n; 750 nf = 0; 751 j = 0; 752 753 factorize_loop: while (true) { 754 j++; 755 if (j <= 4) 756 ntry = factors[j - 1]; 757 else 758 ntry += 2; 759 do { 760 nq = nl / ntry; 761 nr = nl - ntry * nq; 762 if (nr != 0) 763 continue factorize_loop; 764 nf++; 765 wtable[offw + nf + 1 + fourn] = ntry; 766 nl = nq; 767 if (ntry == 2 && nf != 1) { 768 for (i = 2; i <= nf; i++) { 769 ib = nf - i + 2; 770 int idx = ib + fourn; 771 wtable[offw + idx + 1] = wtable[offw + idx]; 772 } 773 wtable[offw + 2 + fourn] = 2; 774 } 775 } while (nl != 1); 776 break factorize_loop; 777 } 778 wtable[offw + fourn] = n; 779 wtable[offw + 1 + fourn] = nf; 780 argh = TWO_PI / (float) n; 781 i = 1; 782 l1 = 1; 783 for (k1 = 1; k1 <= nf; k1++) { 784 ip = (int) wtable[offw + k1 + 1 + fourn]; 785 ld = 0; 786 l2 = l1 * ip; 787 ido = n / l2; 788 idot = ido + ido + 2; 789 ipm = ip - 1; 790 for (j = 1; j <= ipm; j++) { 791 i1 = i; 792 wtable[offw + i - 1 + twon] = 1; 793 wtable[offw + i + twon] = 0; 794 ld += l1; 795 fi = 0; 796 argld = ld * argh; 797 for (ii = 4; ii <= idot; ii += 2) { 798 i += 2; 799 fi += 1; 800 arg = fi * argld; 801 int idx = i + twon; 802 wtable[offw + idx - 1] = (float)Math.cos(arg); 803 wtable[offw + idx] = (float)Math.sin(arg); 804 } 805 if (ip > 5) { 806 int idx1 = i1 + twon; 807 int idx2 = i + twon; 808 wtable[offw + idx1 - 1] = wtable[offw + idx2 - 1]; 809 wtable[offw + idx1] = wtable[offw + idx2]; 810 } 811 } 812 l1 = l2; 813 } 814 815 } 816 817 void cffti() { 818 if (n == 1) 819 return; 820 821 final int twon = 2 * n; 822 final int fourn = 4 * n; 823 float argh; 824 int idot, ntry = 0, i, j; 825 float argld; 826 int i1, k1, l1, l2, ib; 827 float fi; 828 int ld, ii, nf, ip, nl, nq, nr; 829 float arg; 830 int ido, ipm; 831 832 nl = n; 833 nf = 0; 834 j = 0; 835 836 factorize_loop: while (true) { 837 j++; 838 if (j <= 4) 839 ntry = factors[j - 1]; 840 else 841 ntry += 2; 842 do { 843 nq = nl / ntry; 844 nr = nl - ntry * nq; 845 if (nr != 0) 846 continue factorize_loop; 847 nf++; 848 wtable[nf + 1 + fourn] = ntry; 849 nl = nq; 850 if (ntry == 2 && nf != 1) { 851 for (i = 2; i <= nf; i++) { 852 ib = nf - i + 2; 853 int idx = ib + fourn; 854 wtable[idx + 1] = wtable[idx]; 855 } 856 wtable[2 + fourn] = 2; 857 } 858 } while (nl != 1); 859 break factorize_loop; 860 } 861 wtable[fourn] = n; 862 wtable[1 + fourn] = nf; 863 argh = TWO_PI / (float) n; 864 i = 1; 865 l1 = 1; 866 for (k1 = 1; k1 <= nf; k1++) { 867 ip = (int) wtable[k1 + 1 + fourn]; 868 ld = 0; 869 l2 = l1 * ip; 870 ido = n / l2; 871 idot = ido + ido + 2; 872 ipm = ip - 1; 873 for (j = 1; j <= ipm; j++) { 874 i1 = i; 875 wtable[i - 1 + twon] = 1; 876 wtable[i + twon] = 0; 877 ld += l1; 878 fi = 0; 879 argld = ld * argh; 880 for (ii = 4; ii <= idot; ii += 2) { 881 i += 2; 882 fi += 1; 883 arg = fi * argld; 884 int idx = i + twon; 885 wtable[idx - 1] = (float)Math.cos(arg); 886 wtable[idx] = (float)Math.sin(arg); 887 } 888 if (ip > 5) { 889 int idx1 = i1 + twon; 890 int idx2 = i + twon; 891 wtable[idx1 - 1] = wtable[idx2 - 1]; 892 wtable[idx1] = wtable[idx2]; 893 } 894 } 895 l1 = l2; 896 } 897 898 } 899 900 void rffti() { 901 902 if (n == 1) 903 return; 904 final int twon = 2 * n; 905 float argh; 906 int ntry = 0, i, j; 907 float argld; 908 int k1, l1, l2, ib; 909 float fi; 910 int ld, ii, nf, ip, nl, is, nq, nr; 911 float arg; 912 int ido, ipm; 913 int nfm1; 914 915 nl = n; 916 nf = 0; 917 j = 0; 918 919 factorize_loop: while (true) { 920 ++j; 921 if (j <= 4) 922 ntry = factors[j - 1]; 923 else 924 ntry += 2; 925 do { 926 nq = nl / ntry; 927 nr = nl - ntry * nq; 928 if (nr != 0) 929 continue factorize_loop; 930 ++nf; 931 wtable_r[nf + 1 + twon] = ntry; 932 933 nl = nq; 934 if (ntry == 2 && nf != 1) { 935 for (i = 2; i <= nf; i++) { 936 ib = nf - i + 2; 937 int idx = ib + twon; 938 wtable_r[idx + 1] = wtable_r[idx]; 939 } 940 wtable_r[2 + twon] = 2; 941 } 942 } while (nl != 1); 943 break factorize_loop; 944 } 945 wtable_r[twon] = n; 946 wtable_r[1 + twon] = nf; 947 argh = TWO_PI / (float) (n); 948 is = 0; 949 nfm1 = nf - 1; 950 l1 = 1; 951 if (nfm1 == 0) 952 return; 953 for (k1 = 1; k1 <= nfm1; k1++) { 954 ip = (int) wtable_r[k1 + 1 + twon]; 955 ld = 0; 956 l2 = l1 * ip; 957 ido = n / l2; 958 ipm = ip - 1; 959 for (j = 1; j <= ipm; ++j) { 960 ld += l1; 961 i = is; 962 argld = (float) ld * argh; 963 964 fi = 0; 965 for (ii = 3; ii <= ido; ii += 2) { 966 i += 2; 967 fi += 1; 968 arg = fi * argld; 969 int idx = i + n; 970 wtable_r[idx - 2] = (float)Math.cos(arg); 971 wtable_r[idx - 1] = (float)Math.sin(arg); 972 } 973 is += ido; 974 } 975 l1 = l2; 976 } 977 } 978 979 private void bluesteini() { 980 int k = 0; 981 float arg; 982 float pi_n = PI / n; 983 bk1[0] = 1; 984 bk1[1] = 0; 985 for (int i = 1; i < n; i++) { 986 k += 2 * i - 1; 987 if (k >= 2 * n) 988 k -= 2 * n; 989 arg = pi_n * k; 990 bk1[2 * i] = (float)Math.cos(arg); 991 bk1[2 * i + 1] = (float)Math.sin(arg); 992 } 993 float scale = (float)(1.0 / nBluestein); 994 bk2[0] = bk1[0] * scale; 995 bk2[1] = bk1[1] * scale; 996 for (int i = 2; i < 2 * n; i += 2) { 997 bk2[i] = bk1[i] * scale; 998 bk2[i + 1] = bk1[i + 1] * scale; 999 bk2[2 * nBluestein - i] = bk2[i]; 1000 bk2[2 * nBluestein - i + 1] = bk2[i + 1]; 1001 } 1002 cftbsub(2 * nBluestein, bk2, 0, ip, nw, w); 1003 } 1004 1005 private void makewt(int nw) { 1006 int j, nwh, nw0, nw1; 1007 float delta, wn4r, wk1r, wk1i, wk3r, wk3i; 1008 float delta2, deltaj, deltaj3; 1009 1010 ip[0] = nw; 1011 ip[1] = 1; 1012 if (nw > 2) { 1013 nwh = nw >> 1; 1014 delta = (float)(0.785398163397448278999490867136046290 / nwh); 1015 delta2 = delta * 2; 1016 wn4r = (float)Math.cos(delta * nwh); 1017 w[0] = 1; 1018 w[1] = wn4r; 1019 if (nwh == 4) { 1020 w[2] = (float)Math.cos(delta2); 1021 w[3] = (float)Math.sin(delta2); 1022 } else if (nwh > 4) { 1023 makeipt(nw); 1024 w[2] = (float)(0.5 / Math.cos(delta2)); 1025 w[3] = (float)(0.5 / Math.cos(delta * 6)); 1026 for (j = 4; j < nwh; j += 4) { 1027 deltaj = delta * j; 1028 deltaj3 = 3 * deltaj; 1029 w[j] = (float)Math.cos(deltaj); 1030 w[j + 1] = (float)Math.sin(deltaj); 1031 w[j + 2] = (float)Math.cos(deltaj3); 1032 w[j + 3] = (float)-Math.sin(deltaj3); 1033 } 1034 } 1035 nw0 = 0; 1036 while (nwh > 2) { 1037 nw1 = nw0 + nwh; 1038 nwh >>= 1; 1039 w[nw1] = 1; 1040 w[nw1 + 1] = wn4r; 1041 if (nwh == 4) { 1042 wk1r = w[nw0 + 4]; 1043 wk1i = w[nw0 + 5]; 1044 w[nw1 + 2] = wk1r; 1045 w[nw1 + 3] = wk1i; 1046 } else if (nwh > 4) { 1047 wk1r = w[nw0 + 4]; 1048 wk3r = w[nw0 + 6]; 1049 w[nw1 + 2] = (float)(0.5 / wk1r); 1050 w[nw1 + 3] = (float)(0.5 / wk3r); 1051 for (j = 4; j < nwh; j += 4) { 1052 int idx1 = nw0 + 2 * j; 1053 int idx2 = nw1 + j; 1054 wk1r = w[idx1]; 1055 wk1i = w[idx1 + 1]; 1056 wk3r = w[idx1 + 2]; 1057 wk3i = w[idx1 + 3]; 1058 w[idx2] = wk1r; 1059 w[idx2 + 1] = wk1i; 1060 w[idx2 + 2] = wk3r; 1061 w[idx2 + 3] = wk3i; 1062 } 1063 } 1064 nw0 = nw1; 1065 } 1066 } 1067 } 1068 1069 private void makeipt(int nw) { 1070 int j, l, m, m2, p, q; 1071 1072 ip[2] = 0; 1073 ip[3] = 16; 1074 m = 2; 1075 for (l = nw; l > 32; l >>= 2) { 1076 m2 = m << 1; 1077 q = m2 << 3; 1078 for (j = m; j < m2; j++) { 1079 p = ip[j] << 2; 1080 ip[m + j] = p; 1081 ip[m2 + j] = p + q; 1082 } 1083 m = m2; 1084 } 1085 } 1086 1087 private void makect(int nc, float[] c, int startc) { 1088 int j, nch; 1089 float delta, deltaj; 1090 1091 ip[1] = nc; 1092 if (nc > 1) { 1093 nch = nc >> 1; 1094 delta = (float)(0.785398163397448278999490867136046290 / nch); 1095 c[startc] = (float)Math.cos(delta * nch); 1096 c[startc + nch] = (float)(0.5 * c[startc]); 1097 for (j = 1; j < nch; j++) { 1098 deltaj = delta * j; 1099 c[startc + j] = (float)(0.5 * Math.cos(deltaj)); 1100 c[startc + nc - j] = (float)(0.5 * Math.sin(deltaj)); 1101 } 1102 } 1103 } 1104 1105 private void bluestein_complex(final float[] a, final int offa, final int isign) { 1106 final float[] ak = new float[2 * nBluestein]; 1107 int nthreads = 1; 1108 int threads = ConcurrencyUtils.getNumberOfThreads(); 1109 if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 1110 nthreads = 2; 1111 if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) { 1112 nthreads = 4; 1113 } 1114 Future<?>[] futures = new Future[nthreads]; 1115 int k = n / nthreads; 1116 for (int i = 0; i < nthreads; i++) { 1117 final int firstIdx = i * k; 1118 final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k; 1119 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1120 public void run() { 1121 if (isign > 0) { 1122 for (int i = firstIdx; i < lastIdx; i++) { 1123 int idx1 = 2 * i; 1124 int idx2 = idx1 + 1; 1125 int idx3 = offa + idx1; 1126 int idx4 = offa + idx2; 1127 ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2]; 1128 ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1]; 1129 } 1130 } else { 1131 for (int i = firstIdx; i < lastIdx; i++) { 1132 int idx1 = 2 * i; 1133 int idx2 = idx1 + 1; 1134 int idx3 = offa + idx1; 1135 int idx4 = offa + idx2; 1136 ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2]; 1137 ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1]; 1138 } 1139 } 1140 } 1141 }); 1142 } 1143 ConcurrencyUtils.waitForCompletion(futures); 1144 1145 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1146 1147 k = nBluestein / nthreads; 1148 for (int i = 0; i < nthreads; i++) { 1149 final int firstIdx = i * k; 1150 final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k; 1151 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1152 public void run() { 1153 if (isign > 0) { 1154 for (int i = firstIdx; i < lastIdx; i++) { 1155 int idx1 = 2 * i; 1156 int idx2 = idx1 + 1; 1157 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1158 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1159 ak[idx2] = im; 1160 } 1161 } else { 1162 for (int i = firstIdx; i < lastIdx; i++) { 1163 int idx1 = 2 * i; 1164 int idx2 = idx1 + 1; 1165 float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1166 ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2]; 1167 ak[idx2] = im; 1168 } 1169 } 1170 } 1171 }); 1172 } 1173 ConcurrencyUtils.waitForCompletion(futures); 1174 1175 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1176 1177 k = n / nthreads; 1178 for (int i = 0; i < nthreads; i++) { 1179 final int firstIdx = i * k; 1180 final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k; 1181 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1182 public void run() { 1183 if (isign > 0) { 1184 for (int i = firstIdx; i < lastIdx; i++) { 1185 int idx1 = 2 * i; 1186 int idx2 = idx1 + 1; 1187 int idx3 = offa + idx1; 1188 int idx4 = offa + idx2; 1189 a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1190 a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1191 } 1192 } else { 1193 for (int i = firstIdx; i < lastIdx; i++) { 1194 int idx1 = 2 * i; 1195 int idx2 = idx1 + 1; 1196 int idx3 = offa + idx1; 1197 int idx4 = offa + idx2; 1198 a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2]; 1199 a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1200 } 1201 } 1202 } 1203 }); 1204 } 1205 ConcurrencyUtils.waitForCompletion(futures); 1206 } else { 1207 if (isign > 0) { 1208 for (int i = 0; i < n; i++) { 1209 int idx1 = 2 * i; 1210 int idx2 = idx1 + 1; 1211 int idx3 = offa + idx1; 1212 int idx4 = offa + idx2; 1213 ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2]; 1214 ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1]; 1215 } 1216 } else { 1217 for (int i = 0; i < n; i++) { 1218 int idx1 = 2 * i; 1219 int idx2 = idx1 + 1; 1220 int idx3 = offa + idx1; 1221 int idx4 = offa + idx2; 1222 ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2]; 1223 ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1]; 1224 } 1225 } 1226 1227 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1228 1229 if (isign > 0) { 1230 for (int i = 0; i < nBluestein; i++) { 1231 int idx1 = 2 * i; 1232 int idx2 = idx1 + 1; 1233 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1234 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1235 ak[idx2] = im; 1236 } 1237 } else { 1238 for (int i = 0; i < nBluestein; i++) { 1239 int idx1 = 2 * i; 1240 int idx2 = idx1 + 1; 1241 float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1242 ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2]; 1243 ak[idx2] = im; 1244 } 1245 } 1246 1247 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1248 if (isign > 0) { 1249 for (int i = 0; i < n; i++) { 1250 int idx1 = 2 * i; 1251 int idx2 = idx1 + 1; 1252 int idx3 = offa + idx1; 1253 int idx4 = offa + idx2; 1254 a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1255 a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1256 } 1257 } else { 1258 for (int i = 0; i < n; i++) { 1259 int idx1 = 2 * i; 1260 int idx2 = idx1 + 1; 1261 int idx3 = offa + idx1; 1262 int idx4 = offa + idx2; 1263 a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2]; 1264 a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1265 } 1266 } 1267 } 1268 } 1269 1270 private void bluestein_real_full(final float[] a, final int offa, final int isign) { 1271 final float[] ak = new float[2 * nBluestein]; 1272 int nthreads = 1; 1273 int threads = ConcurrencyUtils.getNumberOfThreads(); 1274 if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 1275 nthreads = 2; 1276 if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) { 1277 nthreads = 4; 1278 } 1279 Future<?>[] futures = new Future[nthreads]; 1280 int k = n / nthreads; 1281 for (int i = 0; i < nthreads; i++) { 1282 final int firstIdx = i * k; 1283 final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k; 1284 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1285 public void run() { 1286 if (isign > 0) { 1287 for (int i = firstIdx; i < lastIdx; i++) { 1288 int idx1 = 2 * i; 1289 int idx2 = idx1 + 1; 1290 int idx3 = offa + i; 1291 ak[idx1] = a[idx3] * bk1[idx1]; 1292 ak[idx2] = a[idx3] * bk1[idx2]; 1293 } 1294 } else { 1295 for (int i = firstIdx; i < lastIdx; i++) { 1296 int idx1 = 2 * i; 1297 int idx2 = idx1 + 1; 1298 int idx3 = offa + i; 1299 ak[idx1] = a[idx3] * bk1[idx1]; 1300 ak[idx2] = -a[idx3] * bk1[idx2]; 1301 } 1302 } 1303 } 1304 }); 1305 } 1306 ConcurrencyUtils.waitForCompletion(futures); 1307 1308 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1309 1310 k = nBluestein / nthreads; 1311 for (int i = 0; i < nthreads; i++) { 1312 final int firstIdx = i * k; 1313 final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k; 1314 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1315 public void run() { 1316 if (isign > 0) { 1317 for (int i = firstIdx; i < lastIdx; i++) { 1318 int idx1 = 2 * i; 1319 int idx2 = idx1 + 1; 1320 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1321 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1322 ak[idx2] = im; 1323 } 1324 } else { 1325 for (int i = firstIdx; i < lastIdx; i++) { 1326 int idx1 = 2 * i; 1327 int idx2 = idx1 + 1; 1328 float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1329 ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2]; 1330 ak[idx2] = im; 1331 } 1332 } 1333 } 1334 }); 1335 } 1336 ConcurrencyUtils.waitForCompletion(futures); 1337 1338 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1339 1340 k = n / nthreads; 1341 for (int i = 0; i < nthreads; i++) { 1342 final int firstIdx = i * k; 1343 final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k; 1344 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1345 public void run() { 1346 if (isign > 0) { 1347 for (int i = firstIdx; i < lastIdx; i++) { 1348 int idx1 = 2 * i; 1349 int idx2 = idx1 + 1; 1350 a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1351 a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1352 } 1353 } else { 1354 for (int i = firstIdx; i < lastIdx; i++) { 1355 int idx1 = 2 * i; 1356 int idx2 = idx1 + 1; 1357 a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2]; 1358 a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1359 } 1360 } 1361 } 1362 }); 1363 } 1364 ConcurrencyUtils.waitForCompletion(futures); 1365 } else { 1366 if (isign > 0) { 1367 for (int i = 0; i < n; i++) { 1368 int idx1 = 2 * i; 1369 int idx2 = idx1 + 1; 1370 int idx3 = offa + i; 1371 ak[idx1] = a[idx3] * bk1[idx1]; 1372 ak[idx2] = a[idx3] * bk1[idx2]; 1373 } 1374 } else { 1375 for (int i = 0; i < n; i++) { 1376 int idx1 = 2 * i; 1377 int idx2 = idx1 + 1; 1378 int idx3 = offa + i; 1379 ak[idx1] = a[idx3] * bk1[idx1]; 1380 ak[idx2] = -a[idx3] * bk1[idx2]; 1381 } 1382 } 1383 1384 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1385 1386 if (isign > 0) { 1387 for (int i = 0; i < nBluestein; i++) { 1388 int idx1 = 2 * i; 1389 int idx2 = idx1 + 1; 1390 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1391 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1392 ak[idx2] = im; 1393 } 1394 } else { 1395 for (int i = 0; i < nBluestein; i++) { 1396 int idx1 = 2 * i; 1397 int idx2 = idx1 + 1; 1398 float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1399 ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2]; 1400 ak[idx2] = im; 1401 } 1402 } 1403 1404 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1405 1406 if (isign > 0) { 1407 for (int i = 0; i < n; i++) { 1408 int idx1 = 2 * i; 1409 int idx2 = idx1 + 1; 1410 a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1411 a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1412 } 1413 } else { 1414 for (int i = 0; i < n; i++) { 1415 int idx1 = 2 * i; 1416 int idx2 = idx1 + 1; 1417 a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2]; 1418 a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1419 } 1420 } 1421 } 1422 } 1423 1424 private void bluestein_real_forward(final float[] a, final int offa) { 1425 final float[] ak = new float[2 * nBluestein]; 1426 int nthreads = 1; 1427 int threads = ConcurrencyUtils.getNumberOfThreads(); 1428 if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 1429 nthreads = 2; 1430 if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) { 1431 nthreads = 4; 1432 } 1433 Future<?>[] futures = new Future[nthreads]; 1434 int k = n / nthreads; 1435 for (int i = 0; i < nthreads; i++) { 1436 final int firstIdx = i * k; 1437 final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k; 1438 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1439 public void run() { 1440 for (int i = firstIdx; i < lastIdx; i++) { 1441 int idx1 = 2 * i; 1442 int idx2 = idx1 + 1; 1443 int idx3 = offa + i; 1444 ak[idx1] = a[idx3] * bk1[idx1]; 1445 ak[idx2] = -a[idx3] * bk1[idx2]; 1446 } 1447 } 1448 }); 1449 } 1450 ConcurrencyUtils.waitForCompletion(futures); 1451 1452 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1453 1454 k = nBluestein / nthreads; 1455 for (int i = 0; i < nthreads; i++) { 1456 final int firstIdx = i * k; 1457 final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k; 1458 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1459 public void run() { 1460 for (int i = firstIdx; i < lastIdx; i++) { 1461 int idx1 = 2 * i; 1462 int idx2 = idx1 + 1; 1463 float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1464 ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2]; 1465 ak[idx2] = im; 1466 } 1467 } 1468 }); 1469 } 1470 ConcurrencyUtils.waitForCompletion(futures); 1471 1472 } else { 1473 1474 for (int i = 0; i < n; i++) { 1475 int idx1 = 2 * i; 1476 int idx2 = idx1 + 1; 1477 int idx3 = offa + i; 1478 ak[idx1] = a[idx3] * bk1[idx1]; 1479 ak[idx2] = -a[idx3] * bk1[idx2]; 1480 } 1481 1482 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1483 1484 for (int i = 0; i < nBluestein; i++) { 1485 int idx1 = 2 * i; 1486 int idx2 = idx1 + 1; 1487 float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1488 ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2]; 1489 ak[idx2] = im; 1490 } 1491 } 1492 1493 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1494 1495 if (n % 2 == 0) { 1496 a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1]; 1497 a[offa + 1] = bk1[n] * ak[n] + bk1[n + 1] * ak[n + 1]; 1498 for (int i = 1; i < n / 2; i++) { 1499 int idx1 = 2 * i; 1500 int idx2 = idx1 + 1; 1501 a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2]; 1502 a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1503 } 1504 } else { 1505 a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1]; 1506 a[offa + 1] = -bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n]; 1507 for (int i = 1; i < (n - 1) / 2; i++) { 1508 int idx1 = 2 * i; 1509 int idx2 = idx1 + 1; 1510 a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2]; 1511 a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1512 } 1513 a[offa + n - 1] = bk1[n - 1] * ak[n - 1] + bk1[n] * ak[n]; 1514 } 1515 1516 } 1517 1518 private void bluestein_real_inverse(final float[] a, final int offa) { 1519 final float[] ak = new float[2 * nBluestein]; 1520 if (n % 2 == 0) { 1521 ak[0] = a[offa] * bk1[0]; 1522 ak[1] = a[offa] * bk1[1]; 1523 1524 for (int i = 1; i < n / 2; i++) { 1525 int idx1 = 2 * i; 1526 int idx2 = idx1 + 1; 1527 int idx3 = offa + idx1; 1528 int idx4 = offa + idx2; 1529 ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2]; 1530 ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1]; 1531 } 1532 1533 ak[n] = a[offa + 1] * bk1[n]; 1534 ak[n + 1] = a[offa + 1] * bk1[n + 1]; 1535 1536 for (int i = n / 2 + 1; i < n; i++) { 1537 int idx1 = 2 * i; 1538 int idx2 = idx1 + 1; 1539 int idx3 = offa + 2 * n - idx1; 1540 int idx4 = idx3 + 1; 1541 ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2]; 1542 ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1]; 1543 } 1544 1545 } else { 1546 ak[0] = a[offa] * bk1[0]; 1547 ak[1] = a[offa] * bk1[1]; 1548 1549 for (int i = 1; i < (n - 1) / 2; i++) { 1550 int idx1 = 2 * i; 1551 int idx2 = idx1 + 1; 1552 int idx3 = offa + idx1; 1553 int idx4 = offa + idx2; 1554 ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2]; 1555 ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1]; 1556 } 1557 1558 ak[n - 1] = a[offa + n - 1] * bk1[n - 1] - a[offa + 1] * bk1[n]; 1559 ak[n] = a[offa + n - 1] * bk1[n] + a[offa + 1] * bk1[n - 1]; 1560 1561 ak[n + 1] = a[offa + n - 1] * bk1[n + 1] + a[offa + 1] * bk1[n + 2]; 1562 ak[n + 2] = a[offa + n - 1] * bk1[n + 2] - a[offa + 1] * bk1[n + 1]; 1563 1564 for (int i = (n - 1) / 2 + 2; i < n; i++) { 1565 int idx1 = 2 * i; 1566 int idx2 = idx1 + 1; 1567 int idx3 = offa + 2 * n - idx1; 1568 int idx4 = idx3 + 1; 1569 ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2]; 1570 ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1]; 1571 } 1572 } 1573 1574 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1575 1576 int nthreads = 1; 1577 int threads = ConcurrencyUtils.getNumberOfThreads(); 1578 if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 1579 nthreads = 2; 1580 if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) { 1581 nthreads = 4; 1582 } 1583 Future<?>[] futures = new Future[nthreads]; 1584 int k = nBluestein / nthreads; 1585 for (int i = 0; i < nthreads; i++) { 1586 final int firstIdx = i * k; 1587 final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k; 1588 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1589 public void run() { 1590 for (int i = firstIdx; i < lastIdx; i++) { 1591 int idx1 = 2 * i; 1592 int idx2 = idx1 + 1; 1593 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1594 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1595 ak[idx2] = im; 1596 } 1597 } 1598 }); 1599 } 1600 ConcurrencyUtils.waitForCompletion(futures); 1601 1602 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1603 1604 k = n / nthreads; 1605 for (int i = 0; i < nthreads; i++) { 1606 final int firstIdx = i * k; 1607 final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k; 1608 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1609 public void run() { 1610 for (int i = firstIdx; i < lastIdx; i++) { 1611 int idx1 = 2 * i; 1612 int idx2 = idx1 + 1; 1613 a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1614 } 1615 } 1616 }); 1617 } 1618 ConcurrencyUtils.waitForCompletion(futures); 1619 1620 } else { 1621 1622 for (int i = 0; i < nBluestein; i++) { 1623 int idx1 = 2 * i; 1624 int idx2 = idx1 + 1; 1625 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1626 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1627 ak[idx2] = im; 1628 } 1629 1630 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1631 1632 for (int i = 0; i < n; i++) { 1633 int idx1 = 2 * i; 1634 int idx2 = idx1 + 1; 1635 a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1636 } 1637 } 1638 } 1639 1640 private void bluestein_real_inverse2(final float[] a, final int offa) { 1641 final float[] ak = new float[2 * nBluestein]; 1642 int nthreads = 1; 1643 int threads = ConcurrencyUtils.getNumberOfThreads(); 1644 if ((threads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 1645 nthreads = 2; 1646 if ((threads >= 4) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) { 1647 nthreads = 4; 1648 } 1649 Future<?>[] futures = new Future[nthreads]; 1650 int k = n / nthreads; 1651 for (int i = 0; i < nthreads; i++) { 1652 final int firstIdx = i * k; 1653 final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k; 1654 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1655 public void run() { 1656 for (int i = firstIdx; i < lastIdx; i++) { 1657 int idx1 = 2 * i; 1658 int idx2 = idx1 + 1; 1659 int idx3 = offa + i; 1660 ak[idx1] = a[idx3] * bk1[idx1]; 1661 ak[idx2] = a[idx3] * bk1[idx2]; 1662 } 1663 } 1664 }); 1665 } 1666 ConcurrencyUtils.waitForCompletion(futures); 1667 1668 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1669 1670 k = nBluestein / nthreads; 1671 for (int i = 0; i < nthreads; i++) { 1672 final int firstIdx = i * k; 1673 final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k; 1674 futures[i] = ConcurrencyUtils.submit(new Runnable() { 1675 public void run() { 1676 for (int i = firstIdx; i < lastIdx; i++) { 1677 int idx1 = 2 * i; 1678 int idx2 = idx1 + 1; 1679 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1680 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1681 ak[idx2] = im; 1682 } 1683 } 1684 }); 1685 } 1686 ConcurrencyUtils.waitForCompletion(futures); 1687 1688 } else { 1689 1690 for (int i = 0; i < n; i++) { 1691 int idx1 = 2 * i; 1692 int idx2 = idx1 + 1; 1693 int idx3 = offa + i; 1694 ak[idx1] = a[idx3] * bk1[idx1]; 1695 ak[idx2] = a[idx3] * bk1[idx2]; 1696 } 1697 1698 cftbsub(2 * nBluestein, ak, 0, ip, nw, w); 1699 1700 for (int i = 0; i < nBluestein; i++) { 1701 int idx1 = 2 * i; 1702 int idx2 = idx1 + 1; 1703 float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1]; 1704 ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2]; 1705 ak[idx2] = im; 1706 } 1707 } 1708 1709 cftfsub(2 * nBluestein, ak, 0, ip, nw, w); 1710 1711 if (n % 2 == 0) { 1712 a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1]; 1713 a[offa + 1] = bk1[n] * ak[n] - bk1[n + 1] * ak[n + 1]; 1714 for (int i = 1; i < n / 2; i++) { 1715 int idx1 = 2 * i; 1716 int idx2 = idx1 + 1; 1717 a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1718 a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1719 } 1720 } else { 1721 a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1]; 1722 a[offa + 1] = bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n]; 1723 for (int i = 1; i < (n - 1) / 2; i++) { 1724 int idx1 = 2 * i; 1725 int idx2 = idx1 + 1; 1726 a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2]; 1727 a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2]; 1728 } 1729 a[offa + n - 1] = bk1[n - 1] * ak[n - 1] - bk1[n] * ak[n]; 1730 } 1731 } 1732 1733 /*--------------------------------------------------------- 1734 rfftf1: further processing of Real forward FFT 1735 --------------------------------------------------------*/ 1736 void rfftf(final float a[], final int offa) { 1737 if (n == 1) 1738 return; 1739 int l1, l2, na, kh, nf, ip, iw, ido, idl1; 1740 1741 final float[] ch = new float[n]; 1742 final int twon = 2 * n; 1743 nf = (int) wtable_r[1 + twon]; 1744 na = 1; 1745 l2 = n; 1746 iw = twon - 1; 1747 for (int k1 = 1; k1 <= nf; ++k1) { 1748 kh = nf - k1; 1749 ip = (int) wtable_r[kh + 2 + twon]; 1750 l1 = l2 / ip; 1751 ido = n / l2; 1752 idl1 = ido * l1; 1753 iw -= (ip - 1) * ido; 1754 na = 1 - na; 1755 switch (ip) { 1756 case 2: 1757 if (na == 0) { 1758 radf2(ido, l1, a, offa, ch, 0, iw); 1759 } else { 1760 radf2(ido, l1, ch, 0, a, offa, iw); 1761 } 1762 break; 1763 case 3: 1764 if (na == 0) { 1765 radf3(ido, l1, a, offa, ch, 0, iw); 1766 } else { 1767 radf3(ido, l1, ch, 0, a, offa, iw); 1768 } 1769 break; 1770 case 4: 1771 if (na == 0) { 1772 radf4(ido, l1, a, offa, ch, 0, iw); 1773 } else { 1774 radf4(ido, l1, ch, 0, a, offa, iw); 1775 } 1776 break; 1777 case 5: 1778 if (na == 0) { 1779 radf5(ido, l1, a, offa, ch, 0, iw); 1780 } else { 1781 radf5(ido, l1, ch, 0, a, offa, iw); 1782 } 1783 break; 1784 default: 1785 if (ido == 1) 1786 na = 1 - na; 1787 if (na == 0) { 1788 radfg(ido, ip, l1, idl1, a, offa, ch, 0, iw); 1789 na = 1; 1790 } else { 1791 radfg(ido, ip, l1, idl1, ch, 0, a, offa, iw); 1792 na = 0; 1793 } 1794 break; 1795 } 1796 l2 = l1; 1797 } 1798 if (na == 1) 1799 return; 1800 System.arraycopy(ch, 0, a, offa, n); 1801 } 1802 1803 /*--------------------------------------------------------- 1804 rfftb1: further processing of Real backward FFT 1805 --------------------------------------------------------*/ 1806 void rfftb(final float a[], final int offa) { 1807 if (n == 1) 1808 return; 1809 int l1, l2, na, nf, ip, iw, ido, idl1; 1810 1811 float[] ch = new float[n]; 1812 final int twon = 2 * n; 1813 nf = (int) wtable_r[1 + twon]; 1814 na = 0; 1815 l1 = 1; 1816 iw = n; 1817 for (int k1 = 1; k1 <= nf; k1++) { 1818 ip = (int) wtable_r[k1 + 1 + twon]; 1819 l2 = ip * l1; 1820 ido = n / l2; 1821 idl1 = ido * l1; 1822 switch (ip) { 1823 case 2: 1824 if (na == 0) { 1825 radb2(ido, l1, a, offa, ch, 0, iw); 1826 } else { 1827 radb2(ido, l1, ch, 0, a, offa, iw); 1828 } 1829 na = 1 - na; 1830 break; 1831 case 3: 1832 if (na == 0) { 1833 radb3(ido, l1, a, offa, ch, 0, iw); 1834 } else { 1835 radb3(ido, l1, ch, 0, a, offa, iw); 1836 } 1837 na = 1 - na; 1838 break; 1839 case 4: 1840 if (na == 0) { 1841 radb4(ido, l1, a, offa, ch, 0, iw); 1842 } else { 1843 radb4(ido, l1, ch, 0, a, offa, iw); 1844 } 1845 na = 1 - na; 1846 break; 1847 case 5: 1848 if (na == 0) { 1849 radb5(ido, l1, a, offa, ch, 0, iw); 1850 } else { 1851 radb5(ido, l1, ch, 0, a, offa, iw); 1852 } 1853 na = 1 - na; 1854 break; 1855 default: 1856 if (na == 0) { 1857 radbg(ido, ip, l1, idl1, a, offa, ch, 0, iw); 1858 } else { 1859 radbg(ido, ip, l1, idl1, ch, 0, a, offa, iw); 1860 } 1861 if (ido == 1) 1862 na = 1 - na; 1863 break; 1864 } 1865 l1 = l2; 1866 iw += (ip - 1) * ido; 1867 } 1868 if (na == 0) 1869 return; 1870 System.arraycopy(ch, 0, a, offa, n); 1871 } 1872 1873 /*------------------------------------------------- 1874 radf2: Real FFT's forward processing of factor 2 1875 -------------------------------------------------*/ 1876 void radf2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 1877 int i, ic, idx0, idx1, idx2, idx3, idx4; 1878 float t1i, t1r, w1r, w1i; 1879 int iw1; 1880 iw1 = offset; 1881 idx0 = l1 * ido; 1882 idx1 = 2 * ido; 1883 for (int k = 0; k < l1; k++) { 1884 int oidx1 = out_off + k * idx1; 1885 int oidx2 = oidx1 + idx1 - 1; 1886 int iidx1 = in_off + k * ido; 1887 int iidx2 = iidx1 + idx0; 1888 1889 float i1r = in[iidx1]; 1890 float i2r = in[iidx2]; 1891 1892 out[oidx1] = i1r + i2r; 1893 out[oidx2] = i1r - i2r; 1894 } 1895 if (ido < 2) 1896 return; 1897 if (ido != 2) { 1898 for (int k = 0; k < l1; k++) { 1899 idx1 = k * ido; 1900 idx2 = 2 * idx1; 1901 idx3 = idx2 + ido; 1902 idx4 = idx1 + idx0; 1903 for (i = 2; i < ido; i += 2) { 1904 ic = ido - i; 1905 int widx1 = i - 1 + iw1; 1906 int oidx1 = out_off + i + idx2; 1907 int oidx2 = out_off + ic + idx3; 1908 int iidx1 = in_off + i + idx1; 1909 int iidx2 = in_off + i + idx4; 1910 1911 float a1i = in[iidx1 - 1]; 1912 float a1r = in[iidx1]; 1913 float a2i = in[iidx2 - 1]; 1914 float a2r = in[iidx2]; 1915 1916 w1r = wtable_r[widx1 - 1]; 1917 w1i = wtable_r[widx1]; 1918 1919 t1r = w1r * a2i + w1i * a2r; 1920 t1i = w1r * a2r - w1i * a2i; 1921 1922 out[oidx1] = a1r + t1i; 1923 out[oidx1 - 1] = a1i + t1r; 1924 1925 out[oidx2] = t1i - a1r; 1926 out[oidx2 - 1] = a1i - t1r; 1927 } 1928 } 1929 if (ido % 2 == 1) 1930 return; 1931 } 1932 idx2 = 2 * idx1; 1933 for (int k = 0; k < l1; k++) { 1934 idx1 = k * ido; 1935 int oidx1 = out_off + idx2 + ido; 1936 int iidx1 = in_off + ido - 1 + idx1; 1937 1938 out[oidx1] = -in[iidx1 + idx0]; 1939 out[oidx1 - 1] = in[iidx1]; 1940 } 1941 } 1942 1943 /*------------------------------------------------- 1944 radb2: Real FFT's backward processing of factor 2 1945 -------------------------------------------------*/ 1946 void radb2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 1947 int i, ic; 1948 float t1i, t1r, w1r, w1i; 1949 int iw1 = offset; 1950 1951 int idx0 = l1 * ido; 1952 for (int k = 0; k < l1; k++) { 1953 int idx1 = k * ido; 1954 int idx2 = 2 * idx1; 1955 int idx3 = idx2 + ido; 1956 int oidx1 = out_off + idx1; 1957 int iidx1 = in_off + idx2; 1958 int iidx2 = in_off + ido - 1 + idx3; 1959 float i1r = in[iidx1]; 1960 float i2r = in[iidx2]; 1961 out[oidx1] = i1r + i2r; 1962 out[oidx1 + idx0] = i1r - i2r; 1963 } 1964 if (ido < 2) 1965 return; 1966 if (ido != 2) { 1967 for (int k = 0; k < l1; ++k) { 1968 int idx1 = k * ido; 1969 int idx2 = 2 * idx1; 1970 int idx3 = idx2 + ido; 1971 int idx4 = idx1 + idx0; 1972 for (i = 2; i < ido; i += 2) { 1973 ic = ido - i; 1974 int idx5 = i - 1 + iw1; 1975 int idx6 = out_off + i; 1976 int idx7 = in_off + i; 1977 int idx8 = in_off + ic; 1978 w1r = wtable_r[idx5 - 1]; 1979 w1i = wtable_r[idx5]; 1980 int iidx1 = idx7 + idx2; 1981 int iidx2 = idx8 + idx3; 1982 int oidx1 = idx6 + idx1; 1983 int oidx2 = idx6 + idx4; 1984 t1r = in[iidx1 - 1] - in[iidx2 - 1]; 1985 t1i = in[iidx1] + in[iidx2]; 1986 float i1i = in[iidx1]; 1987 float i1r = in[iidx1 - 1]; 1988 float i2i = in[iidx2]; 1989 float i2r = in[iidx2 - 1]; 1990 1991 out[oidx1 - 1] = i1r + i2r; 1992 out[oidx1] = i1i - i2i; 1993 out[oidx2 - 1] = w1r * t1r - w1i * t1i; 1994 out[oidx2] = w1r * t1i + w1i * t1r; 1995 } 1996 } 1997 if (ido % 2 == 1) 1998 return; 1999 } 2000 for (int k = 0; k < l1; k++) { 2001 int idx1 = k * ido; 2002 int idx2 = 2 * idx1; 2003 int oidx1 = out_off + ido - 1 + idx1; 2004 int iidx1 = in_off + idx2 + ido; 2005 out[oidx1] = 2 * in[iidx1 - 1]; 2006 out[oidx1 + idx0] = -2 * in[iidx1]; 2007 } 2008 } 2009 2010 /*------------------------------------------------- 2011 radf3: Real FFT's forward processing of factor 3 2012 -------------------------------------------------*/ 2013 void radf3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 2014 final float taur = -0.5f; 2015 final float taui = 0.866025403784438707610604524234076962f; 2016 int i, ic; 2017 float ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i; 2018 int iw1, iw2; 2019 iw1 = offset; 2020 iw2 = iw1 + ido; 2021 2022 int idx0 = l1 * ido; 2023 for (int k = 0; k < l1; k++) { 2024 int idx1 = k * ido; 2025 int idx3 = 2 * idx0; 2026 int idx4 = (3 * k + 1) * ido; 2027 int iidx1 = in_off + idx1; 2028 int iidx2 = iidx1 + idx0; 2029 int iidx3 = iidx1 + idx3; 2030 float i1r = in[iidx1]; 2031 float i2r = in[iidx2]; 2032 float i3r = in[iidx3]; 2033 cr2 = i2r + i3r; 2034 out[out_off + 3 * idx1] = i1r + cr2; 2035 out[out_off + idx4 + ido] = taui * (i3r - i2r); 2036 out[out_off + ido - 1 + idx4] = i1r + taur * cr2; 2037 } 2038 if (ido == 1) 2039 return; 2040 for (int k = 0; k < l1; k++) { 2041 int idx3 = k * ido; 2042 int idx4 = 3 * idx3; 2043 int idx5 = idx3 + idx0; 2044 int idx6 = idx5 + idx0; 2045 int idx7 = idx4 + ido; 2046 int idx8 = idx7 + ido; 2047 for (i = 2; i < ido; i += 2) { 2048 ic = ido - i; 2049 int widx1 = i - 1 + iw1; 2050 int widx2 = i - 1 + iw2; 2051 2052 w1r = wtable_r[widx1 - 1]; 2053 w1i = wtable_r[widx1]; 2054 w2r = wtable_r[widx2 - 1]; 2055 w2i = wtable_r[widx2]; 2056 2057 int idx9 = in_off + i; 2058 int idx10 = out_off + i; 2059 int idx11 = out_off + ic; 2060 int iidx1 = idx9 + idx3; 2061 int iidx2 = idx9 + idx5; 2062 int iidx3 = idx9 + idx6; 2063 2064 float i1i = in[iidx1 - 1]; 2065 float i1r = in[iidx1]; 2066 float i2i = in[iidx2 - 1]; 2067 float i2r = in[iidx2]; 2068 float i3i = in[iidx3 - 1]; 2069 float i3r = in[iidx3]; 2070 2071 dr2 = w1r * i2i + w1i * i2r; 2072 di2 = w1r * i2r - w1i * i2i; 2073 dr3 = w2r * i3i + w2i * i3r; 2074 di3 = w2r * i3r - w2i * i3i; 2075 cr2 = dr2 + dr3; 2076 ci2 = di2 + di3; 2077 tr2 = i1i + taur * cr2; 2078 ti2 = i1r + taur * ci2; 2079 tr3 = taui * (di2 - di3); 2080 ti3 = taui * (dr3 - dr2); 2081 2082 int oidx1 = idx10 + idx4; 2083 int oidx2 = idx11 + idx7; 2084 int oidx3 = idx10 + idx8; 2085 2086 out[oidx1 - 1] = i1i + cr2; 2087 out[oidx1] = i1r + ci2; 2088 out[oidx2 - 1] = tr2 - tr3; 2089 out[oidx2] = ti3 - ti2; 2090 out[oidx3 - 1] = tr2 + tr3; 2091 out[oidx3] = ti2 + ti3; 2092 } 2093 } 2094 } 2095 2096 /*------------------------------------------------- 2097 radb3: Real FFT's backward processing of factor 3 2098 -------------------------------------------------*/ 2099 void radb3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 2100 final float taur = -0.5f; 2101 final float taui = 0.866025403784438707610604524234076962f; 2102 int i, ic; 2103 float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i; 2104 int iw1, iw2; 2105 iw1 = offset; 2106 iw2 = iw1 + ido; 2107 2108 for (int k = 0; k < l1; k++) { 2109 int idx1 = k * ido; 2110 int iidx1 = in_off + 3 * idx1; 2111 int iidx2 = iidx1 + 2 * ido; 2112 float i1i = in[iidx1]; 2113 2114 tr2 = 2 * in[iidx2 - 1]; 2115 cr2 = i1i + taur * tr2; 2116 ci3 = 2 * taui * in[iidx2]; 2117 2118 out[out_off + idx1] = i1i + tr2; 2119 out[out_off + (k + l1) * ido] = cr2 - ci3; 2120 out[out_off + (k + 2 * l1) * ido] = cr2 + ci3; 2121 } 2122 if (ido == 1) 2123 return; 2124 int idx0 = l1 * ido; 2125 for (int k = 0; k < l1; k++) { 2126 int idx1 = k * ido; 2127 int idx2 = 3 * idx1; 2128 int idx3 = idx2 + ido; 2129 int idx4 = idx3 + ido; 2130 int idx5 = idx1 + idx0; 2131 int idx6 = idx5 + idx0; 2132 for (i = 2; i < ido; i += 2) { 2133 ic = ido - i; 2134 int idx7 = in_off + i; 2135 int idx8 = in_off + ic; 2136 int idx9 = out_off + i; 2137 int iidx1 = idx7 + idx2; 2138 int iidx2 = idx7 + idx4; 2139 int iidx3 = idx8 + idx3; 2140 2141 float i1i = in[iidx1 - 1]; 2142 float i1r = in[iidx1]; 2143 float i2i = in[iidx2 - 1]; 2144 float i2r = in[iidx2]; 2145 float i3i = in[iidx3 - 1]; 2146 float i3r = in[iidx3]; 2147 2148 tr2 = i2i + i3i; 2149 cr2 = i1i + taur * tr2; 2150 ti2 = i2r - i3r; 2151 ci2 = i1r + taur * ti2; 2152 cr3 = taui * (i2i - i3i); 2153 ci3 = taui * (i2r + i3r); 2154 dr2 = cr2 - ci3; 2155 dr3 = cr2 + ci3; 2156 di2 = ci2 + cr3; 2157 di3 = ci2 - cr3; 2158 2159 int widx1 = i - 1 + iw1; 2160 int widx2 = i - 1 + iw2; 2161 2162 w1r = wtable_r[widx1 - 1]; 2163 w1i = wtable_r[widx1]; 2164 w2r = wtable_r[widx2 - 1]; 2165 w2i = wtable_r[widx2]; 2166 2167 int oidx1 = idx9 + idx1; 2168 int oidx2 = idx9 + idx5; 2169 int oidx3 = idx9 + idx6; 2170 2171 out[oidx1 - 1] = i1i + tr2; 2172 out[oidx1] = i1r + ti2; 2173 out[oidx2 - 1] = w1r * dr2 - w1i * di2; 2174 out[oidx2] = w1r * di2 + w1i * dr2; 2175 out[oidx3 - 1] = w2r * dr3 - w2i * di3; 2176 out[oidx3] = w2r * di3 + w2i * dr3; 2177 } 2178 } 2179 } 2180 2181 /*------------------------------------------------- 2182 radf4: Real FFT's forward processing of factor 4 2183 -------------------------------------------------*/ 2184 void radf4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 2185 final float hsqt2 = 0.707106781186547572737310929369414225f; 2186 int i, ic; 2187 float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i; 2188 int iw1, iw2, iw3; 2189 iw1 = offset; 2190 iw2 = offset + ido; 2191 iw3 = iw2 + ido; 2192 int idx0 = l1 * ido; 2193 for (int k = 0; k < l1; k++) { 2194 int idx1 = k * ido; 2195 int idx2 = 4 * idx1; 2196 int idx3 = idx1 + idx0; 2197 int idx4 = idx3 + idx0; 2198 int idx5 = idx4 + idx0; 2199 int idx6 = idx2 + ido; 2200 float i1r = in[in_off + idx1]; 2201 float i2r = in[in_off + idx3]; 2202 float i3r = in[in_off + idx4]; 2203 float i4r = in[in_off + idx5]; 2204 2205 tr1 = i2r + i4r; 2206 tr2 = i1r + i3r; 2207 2208 int oidx1 = out_off + idx2; 2209 int oidx2 = out_off + idx6 + ido; 2210 2211 out[oidx1] = tr1 + tr2; 2212 out[oidx2 - 1 + ido + ido] = tr2 - tr1; 2213 out[oidx2 - 1] = i1r - i3r; 2214 out[oidx2] = i4r - i2r; 2215 } 2216 if (ido < 2) 2217 return; 2218 if (ido != 2) { 2219 for (int k = 0; k < l1; k++) { 2220 int idx1 = k * ido; 2221 int idx2 = idx1 + idx0; 2222 int idx3 = idx2 + idx0; 2223 int idx4 = idx3 + idx0; 2224 int idx5 = 4 * idx1; 2225 int idx6 = idx5 + ido; 2226 int idx7 = idx6 + ido; 2227 int idx8 = idx7 + ido; 2228 for (i = 2; i < ido; i += 2) { 2229 ic = ido - i; 2230 int widx1 = i - 1 + iw1; 2231 int widx2 = i - 1 + iw2; 2232 int widx3 = i - 1 + iw3; 2233 w1r = wtable_r[widx1 - 1]; 2234 w1i = wtable_r[widx1]; 2235 w2r = wtable_r[widx2 - 1]; 2236 w2i = wtable_r[widx2]; 2237 w3r = wtable_r[widx3 - 1]; 2238 w3i = wtable_r[widx3]; 2239 2240 int idx9 = in_off + i; 2241 int idx10 = out_off + i; 2242 int idx11 = out_off + ic; 2243 int iidx1 = idx9 + idx1; 2244 int iidx2 = idx9 + idx2; 2245 int iidx3 = idx9 + idx3; 2246 int iidx4 = idx9 + idx4; 2247 2248 float i1i = in[iidx1 - 1]; 2249 float i1r = in[iidx1]; 2250 float i2i = in[iidx2 - 1]; 2251 float i2r = in[iidx2]; 2252 float i3i = in[iidx3 - 1]; 2253 float i3r = in[iidx3]; 2254 float i4i = in[iidx4 - 1]; 2255 float i4r = in[iidx4]; 2256 2257 cr2 = w1r * i2i + w1i * i2r; 2258 ci2 = w1r * i2r - w1i * i2i; 2259 cr3 = w2r * i3i + w2i * i3r; 2260 ci3 = w2r * i3r - w2i * i3i; 2261 cr4 = w3r * i4i + w3i * i4r; 2262 ci4 = w3r * i4r - w3i * i4i; 2263 tr1 = cr2 + cr4; 2264 tr4 = cr4 - cr2; 2265 ti1 = ci2 + ci4; 2266 ti4 = ci2 - ci4; 2267 ti2 = i1r + ci3; 2268 ti3 = i1r - ci3; 2269 tr2 = i1i + cr3; 2270 tr3 = i1i - cr3; 2271 2272 int oidx1 = idx10 + idx5; 2273 int oidx2 = idx11 + idx6; 2274 int oidx3 = idx10 + idx7; 2275 int oidx4 = idx11 + idx8; 2276 2277 out[oidx1 - 1] = tr1 + tr2; 2278 out[oidx4 - 1] = tr2 - tr1; 2279 out[oidx1] = ti1 + ti2; 2280 out[oidx4] = ti1 - ti2; 2281 out[oidx3 - 1] = ti4 + tr3; 2282 out[oidx2 - 1] = tr3 - ti4; 2283 out[oidx3] = tr4 + ti3; 2284 out[oidx2] = tr4 - ti3; 2285 } 2286 } 2287 if (ido % 2 == 1) 2288 return; 2289 } 2290 for (int k = 0; k < l1; k++) { 2291 int idx1 = k * ido; 2292 int idx2 = 4 * idx1; 2293 int idx3 = idx1 + idx0; 2294 int idx4 = idx3 + idx0; 2295 int idx5 = idx4 + idx0; 2296 int idx6 = idx2 + ido; 2297 int idx7 = idx6 + ido; 2298 int idx8 = idx7 + ido; 2299 int idx9 = in_off + ido; 2300 int idx10 = out_off + ido; 2301 2302 float i1i = in[idx9 - 1 + idx1]; 2303 float i2i = in[idx9 - 1 + idx3]; 2304 float i3i = in[idx9 - 1 + idx4]; 2305 float i4i = in[idx9 - 1 + idx5]; 2306 2307 ti1 = -hsqt2 * (i2i + i4i); 2308 tr1 = hsqt2 * (i2i - i4i); 2309 2310 out[idx10 - 1 + idx2] = tr1 + i1i; 2311 out[idx10 - 1 + idx7] = i1i - tr1; 2312 out[out_off + idx6] = ti1 - i3i; 2313 out[out_off + idx8] = ti1 + i3i; 2314 } 2315 } 2316 2317 /*------------------------------------------------- 2318 radb4: Real FFT's backward processing of factor 4 2319 -------------------------------------------------*/ 2320 void radb4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 2321 final float sqrt2 = 1.41421356237309514547462185873882845f; 2322 int i, ic; 2323 float ci2, ci3, ci4, cr2, cr3, cr4; 2324 float ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i; 2325 int iw1, iw2, iw3; 2326 iw1 = offset; 2327 iw2 = iw1 + ido; 2328 iw3 = iw2 + ido; 2329 2330 int idx0 = l1 * ido; 2331 for (int k = 0; k < l1; k++) { 2332 int idx1 = k * ido; 2333 int idx2 = 4 * idx1; 2334 int idx3 = idx1 + idx0; 2335 int idx4 = idx3 + idx0; 2336 int idx5 = idx4 + idx0; 2337 int idx6 = idx2 + ido; 2338 int idx7 = idx6 + ido; 2339 int idx8 = idx7 + ido; 2340 2341 float i1r = in[in_off + idx2]; 2342 float i2r = in[in_off + idx7]; 2343 float i3r = in[in_off + ido - 1 + idx8]; 2344 float i4r = in[in_off + ido - 1 + idx6]; 2345 2346 tr1 = i1r - i3r; 2347 tr2 = i1r + i3r; 2348 tr3 = i4r + i4r; 2349 tr4 = i2r + i2r; 2350 2351 out[out_off + idx1] = tr2 + tr3; 2352 out[out_off + idx3] = tr1 - tr4; 2353 out[out_off + idx4] = tr2 - tr3; 2354 out[out_off + idx5] = tr1 + tr4; 2355 } 2356 if (ido < 2) 2357 return; 2358 if (ido != 2) { 2359 for (int k = 0; k < l1; ++k) { 2360 int idx1 = k * ido; 2361 int idx2 = idx1 + idx0; 2362 int idx3 = idx2 + idx0; 2363 int idx4 = idx3 + idx0; 2364 int idx5 = 4 * idx1; 2365 int idx6 = idx5 + ido; 2366 int idx7 = idx6 + ido; 2367 int idx8 = idx7 + ido; 2368 for (i = 2; i < ido; i += 2) { 2369 ic = ido - i; 2370 int widx1 = i - 1 + iw1; 2371 int widx2 = i - 1 + iw2; 2372 int widx3 = i - 1 + iw3; 2373 w1r = wtable_r[widx1 - 1]; 2374 w1i = wtable_r[widx1]; 2375 w2r = wtable_r[widx2 - 1]; 2376 w2i = wtable_r[widx2]; 2377 w3r = wtable_r[widx3 - 1]; 2378 w3i = wtable_r[widx3]; 2379 2380 int idx12 = in_off + i; 2381 int idx13 = in_off + ic; 2382 int idx14 = out_off + i; 2383 2384 int iidx1 = idx12 + idx5; 2385 int iidx2 = idx13 + idx6; 2386 int iidx3 = idx12 + idx7; 2387 int iidx4 = idx13 + idx8; 2388 2389 float i1i = in[iidx1 - 1]; 2390 float i1r = in[iidx1]; 2391 float i2i = in[iidx2 - 1]; 2392 float i2r = in[iidx2]; 2393 float i3i = in[iidx3 - 1]; 2394 float i3r = in[iidx3]; 2395 float i4i = in[iidx4 - 1]; 2396 float i4r = in[iidx4]; 2397 2398 ti1 = i1r + i4r; 2399 ti2 = i1r - i4r; 2400 ti3 = i3r - i2r; 2401 tr4 = i3r + i2r; 2402 tr1 = i1i - i4i; 2403 tr2 = i1i + i4i; 2404 ti4 = i3i - i2i; 2405 tr3 = i3i + i2i; 2406 cr3 = tr2 - tr3; 2407 ci3 = ti2 - ti3; 2408 cr2 = tr1 - tr4; 2409 cr4 = tr1 + tr4; 2410 ci2 = ti1 + ti4; 2411 ci4 = ti1 - ti4; 2412 2413 int oidx1 = idx14 + idx1; 2414 int oidx2 = idx14 + idx2; 2415 int oidx3 = idx14 + idx3; 2416 int oidx4 = idx14 + idx4; 2417 2418 out[oidx1 - 1] = tr2 + tr3; 2419 out[oidx1] = ti2 + ti3; 2420 out[oidx2 - 1] = w1r * cr2 - w1i * ci2; 2421 out[oidx2] = w1r * ci2 + w1i * cr2; 2422 out[oidx3 - 1] = w2r * cr3 - w2i * ci3; 2423 out[oidx3] = w2r * ci3 + w2i * cr3; 2424 out[oidx4 - 1] = w3r * cr4 - w3i * ci4; 2425 out[oidx4] = w3r * ci4 + w3i * cr4; 2426 } 2427 } 2428 if (ido % 2 == 1) 2429 return; 2430 } 2431 for (int k = 0; k < l1; k++) { 2432 int idx1 = k * ido; 2433 int idx2 = 4 * idx1; 2434 int idx3 = idx1 + idx0; 2435 int idx4 = idx3 + idx0; 2436 int idx5 = idx4 + idx0; 2437 int idx6 = idx2 + ido; 2438 int idx7 = idx6 + ido; 2439 int idx8 = idx7 + ido; 2440 int idx9 = in_off + ido; 2441 int idx10 = out_off + ido; 2442 2443 float i1r = in[idx9 - 1 + idx2]; 2444 float i2r = in[idx9 - 1 + idx7]; 2445 float i3r = in[in_off + idx6]; 2446 float i4r = in[in_off + idx8]; 2447 2448 ti1 = i3r + i4r; 2449 ti2 = i4r - i3r; 2450 tr1 = i1r - i2r; 2451 tr2 = i1r + i2r; 2452 2453 out[idx10 - 1 + idx1] = tr2 + tr2; 2454 out[idx10 - 1 + idx3] = sqrt2 * (tr1 - ti1); 2455 out[idx10 - 1 + idx4] = ti2 + ti2; 2456 out[idx10 - 1 + idx5] = -sqrt2 * (tr1 + ti1); 2457 } 2458 } 2459 2460 /*------------------------------------------------- 2461 radf5: Real FFT's forward processing of factor 5 2462 -------------------------------------------------*/ 2463 void radf5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 2464 final float tr11 = 0.309016994374947451262869435595348477f; 2465 final float ti11 = 0.951056516295153531181938433292089030f; 2466 final float tr12 = -0.809016994374947340240566973079694435f; 2467 final float ti12 = 0.587785252292473248125759255344746634f; 2468 int i, ic; 2469 float ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i; 2470 int iw1, iw2, iw3, iw4; 2471 iw1 = offset; 2472 iw2 = iw1 + ido; 2473 iw3 = iw2 + ido; 2474 iw4 = iw3 + ido; 2475 2476 int idx0 = l1 * ido; 2477 for (int k = 0; k < l1; k++) { 2478 int idx1 = k * ido; 2479 int idx2 = 5 * idx1; 2480 int idx3 = idx2 + ido; 2481 int idx4 = idx3 + ido; 2482 int idx5 = idx4 + ido; 2483 int idx6 = idx5 + ido; 2484 int idx7 = idx1 + idx0; 2485 int idx8 = idx7 + idx0; 2486 int idx9 = idx8 + idx0; 2487 int idx10 = idx9 + idx0; 2488 int idx11 = out_off + ido - 1; 2489 2490 float i1r = in[in_off + idx1]; 2491 float i2r = in[in_off + idx7]; 2492 float i3r = in[in_off + idx8]; 2493 float i4r = in[in_off + idx9]; 2494 float i5r = in[in_off + idx10]; 2495 2496 cr2 = i5r + i2r; 2497 ci5 = i5r - i2r; 2498 cr3 = i4r + i3r; 2499 ci4 = i4r - i3r; 2500 2501 out[out_off + idx2] = i1r + cr2 + cr3; 2502 out[idx11 + idx3] = i1r + tr11 * cr2 + tr12 * cr3; 2503 out[out_off + idx4] = ti11 * ci5 + ti12 * ci4; 2504 out[idx11 + idx5] = i1r + tr12 * cr2 + tr11 * cr3; 2505 out[out_off + idx6] = ti12 * ci5 - ti11 * ci4; 2506 } 2507 if (ido == 1) 2508 return; 2509 for (int k = 0; k < l1; ++k) { 2510 int idx1 = k * ido; 2511 int idx2 = 5 * idx1; 2512 int idx3 = idx2 + ido; 2513 int idx4 = idx3 + ido; 2514 int idx5 = idx4 + ido; 2515 int idx6 = idx5 + ido; 2516 int idx7 = idx1 + idx0; 2517 int idx8 = idx7 + idx0; 2518 int idx9 = idx8 + idx0; 2519 int idx10 = idx9 + idx0; 2520 for (i = 2; i < ido; i += 2) { 2521 int widx1 = i - 1 + iw1; 2522 int widx2 = i - 1 + iw2; 2523 int widx3 = i - 1 + iw3; 2524 int widx4 = i - 1 + iw4; 2525 w1r = wtable_r[widx1 - 1]; 2526 w1i = wtable_r[widx1]; 2527 w2r = wtable_r[widx2 - 1]; 2528 w2i = wtable_r[widx2]; 2529 w3r = wtable_r[widx3 - 1]; 2530 w3i = wtable_r[widx3]; 2531 w4r = wtable_r[widx4 - 1]; 2532 w4i = wtable_r[widx4]; 2533 2534 ic = ido - i; 2535 int idx15 = in_off + i; 2536 int idx16 = out_off + i; 2537 int idx17 = out_off + ic; 2538 2539 int iidx1 = idx15 + idx1; 2540 int iidx2 = idx15 + idx7; 2541 int iidx3 = idx15 + idx8; 2542 int iidx4 = idx15 + idx9; 2543 int iidx5 = idx15 + idx10; 2544 2545 float i1i = in[iidx1 - 1]; 2546 float i1r = in[iidx1]; 2547 float i2i = in[iidx2 - 1]; 2548 float i2r = in[iidx2]; 2549 float i3i = in[iidx3 - 1]; 2550 float i3r = in[iidx3]; 2551 float i4i = in[iidx4 - 1]; 2552 float i4r = in[iidx4]; 2553 float i5i = in[iidx5 - 1]; 2554 float i5r = in[iidx5]; 2555 2556 dr2 = w1r * i2i + w1i * i2r; 2557 di2 = w1r * i2r - w1i * i2i; 2558 dr3 = w2r * i3i + w2i * i3r; 2559 di3 = w2r * i3r - w2i * i3i; 2560 dr4 = w3r * i4i + w3i * i4r; 2561 di4 = w3r * i4r - w3i * i4i; 2562 dr5 = w4r * i5i + w4i * i5r; 2563 di5 = w4r * i5r - w4i * i5i; 2564 2565 cr2 = dr2 + dr5; 2566 ci5 = dr5 - dr2; 2567 cr5 = di2 - di5; 2568 ci2 = di2 + di5; 2569 cr3 = dr3 + dr4; 2570 ci4 = dr4 - dr3; 2571 cr4 = di3 - di4; 2572 ci3 = di3 + di4; 2573 2574 tr2 = i1i + tr11 * cr2 + tr12 * cr3; 2575 ti2 = i1r + tr11 * ci2 + tr12 * ci3; 2576 tr3 = i1i + tr12 * cr2 + tr11 * cr3; 2577 ti3 = i1r + tr12 * ci2 + tr11 * ci3; 2578 tr5 = ti11 * cr5 + ti12 * cr4; 2579 ti5 = ti11 * ci5 + ti12 * ci4; 2580 tr4 = ti12 * cr5 - ti11 * cr4; 2581 ti4 = ti12 * ci5 - ti11 * ci4; 2582 2583 int oidx1 = idx16 + idx2; 2584 int oidx2 = idx17 + idx3; 2585 int oidx3 = idx16 + idx4; 2586 int oidx4 = idx17 + idx5; 2587 int oidx5 = idx16 + idx6; 2588 2589 out[oidx1 - 1] = i1i + cr2 + cr3; 2590 out[oidx1] = i1r + ci2 + ci3; 2591 out[oidx3 - 1] = tr2 + tr5; 2592 out[oidx2 - 1] = tr2 - tr5; 2593 out[oidx3] = ti2 + ti5; 2594 out[oidx2] = ti5 - ti2; 2595 out[oidx5 - 1] = tr3 + tr4; 2596 out[oidx4 - 1] = tr3 - tr4; 2597 out[oidx5] = ti3 + ti4; 2598 out[oidx4] = ti4 - ti3; 2599 } 2600 } 2601 } 2602 2603 /*------------------------------------------------- 2604 radb5: Real FFT's backward processing of factor 5 2605 -------------------------------------------------*/ 2606 void radb5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 2607 final float tr11 = 0.309016994374947451262869435595348477f; 2608 final float ti11 = 0.951056516295153531181938433292089030f; 2609 final float tr12 = -0.809016994374947340240566973079694435f; 2610 final float ti12 = 0.587785252292473248125759255344746634f; 2611 int i, ic; 2612 float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i; 2613 int iw1, iw2, iw3, iw4; 2614 iw1 = offset; 2615 iw2 = iw1 + ido; 2616 iw3 = iw2 + ido; 2617 iw4 = iw3 + ido; 2618 2619 int idx0 = l1 * ido; 2620 for (int k = 0; k < l1; k++) { 2621 int idx1 = k * ido; 2622 int idx2 = 5 * idx1; 2623 int idx3 = idx2 + ido; 2624 int idx4 = idx3 + ido; 2625 int idx5 = idx4 + ido; 2626 int idx6 = idx5 + ido; 2627 int idx7 = idx1 + idx0; 2628 int idx8 = idx7 + idx0; 2629 int idx9 = idx8 + idx0; 2630 int idx10 = idx9 + idx0; 2631 int idx11 = in_off + ido - 1; 2632 2633 float i1r = in[in_off + idx2]; 2634 2635 ti5 = 2 * in[in_off + idx4]; 2636 ti4 = 2 * in[in_off + idx6]; 2637 tr2 = 2 * in[idx11 + idx3]; 2638 tr3 = 2 * in[idx11 + idx5]; 2639 cr2 = i1r + tr11 * tr2 + tr12 * tr3; 2640 cr3 = i1r + tr12 * tr2 + tr11 * tr3; 2641 ci5 = ti11 * ti5 + ti12 * ti4; 2642 ci4 = ti12 * ti5 - ti11 * ti4; 2643 2644 out[out_off + idx1] = i1r + tr2 + tr3; 2645 out[out_off + idx7] = cr2 - ci5; 2646 out[out_off + idx8] = cr3 - ci4; 2647 out[out_off + idx9] = cr3 + ci4; 2648 out[out_off + idx10] = cr2 + ci5; 2649 } 2650 if (ido == 1) 2651 return; 2652 for (int k = 0; k < l1; ++k) { 2653 int idx1 = k * ido; 2654 int idx2 = 5 * idx1; 2655 int idx3 = idx2 + ido; 2656 int idx4 = idx3 + ido; 2657 int idx5 = idx4 + ido; 2658 int idx6 = idx5 + ido; 2659 int idx7 = idx1 + idx0; 2660 int idx8 = idx7 + idx0; 2661 int idx9 = idx8 + idx0; 2662 int idx10 = idx9 + idx0; 2663 for (i = 2; i < ido; i += 2) { 2664 ic = ido - i; 2665 int widx1 = i - 1 + iw1; 2666 int widx2 = i - 1 + iw2; 2667 int widx3 = i - 1 + iw3; 2668 int widx4 = i - 1 + iw4; 2669 w1r = wtable_r[widx1 - 1]; 2670 w1i = wtable_r[widx1]; 2671 w2r = wtable_r[widx2 - 1]; 2672 w2i = wtable_r[widx2]; 2673 w3r = wtable_r[widx3 - 1]; 2674 w3i = wtable_r[widx3]; 2675 w4r = wtable_r[widx4 - 1]; 2676 w4i = wtable_r[widx4]; 2677 2678 int idx15 = in_off + i; 2679 int idx16 = in_off + ic; 2680 int idx17 = out_off + i; 2681 2682 int iidx1 = idx15 + idx2; 2683 int iidx2 = idx16 + idx3; 2684 int iidx3 = idx15 + idx4; 2685 int iidx4 = idx16 + idx5; 2686 int iidx5 = idx15 + idx6; 2687 2688 float i1i = in[iidx1 - 1]; 2689 float i1r = in[iidx1]; 2690 float i2i = in[iidx2 - 1]; 2691 float i2r = in[iidx2]; 2692 float i3i = in[iidx3 - 1]; 2693 float i3r = in[iidx3]; 2694 float i4i = in[iidx4 - 1]; 2695 float i4r = in[iidx4]; 2696 float i5i = in[iidx5 - 1]; 2697 float i5r = in[iidx5]; 2698 2699 ti5 = i3r + i2r; 2700 ti2 = i3r - i2r; 2701 ti4 = i5r + i4r; 2702 ti3 = i5r - i4r; 2703 tr5 = i3i - i2i; 2704 tr2 = i3i + i2i; 2705 tr4 = i5i - i4i; 2706 tr3 = i5i + i4i; 2707 2708 cr2 = i1i + tr11 * tr2 + tr12 * tr3; 2709 ci2 = i1r + tr11 * ti2 + tr12 * ti3; 2710 cr3 = i1i + tr12 * tr2 + tr11 * tr3; 2711 ci3 = i1r + tr12 * ti2 + tr11 * ti3; 2712 cr5 = ti11 * tr5 + ti12 * tr4; 2713 ci5 = ti11 * ti5 + ti12 * ti4; 2714 cr4 = ti12 * tr5 - ti11 * tr4; 2715 ci4 = ti12 * ti5 - ti11 * ti4; 2716 dr3 = cr3 - ci4; 2717 dr4 = cr3 + ci4; 2718 di3 = ci3 + cr4; 2719 di4 = ci3 - cr4; 2720 dr5 = cr2 + ci5; 2721 dr2 = cr2 - ci5; 2722 di5 = ci2 - cr5; 2723 di2 = ci2 + cr5; 2724 2725 int oidx1 = idx17 + idx1; 2726 int oidx2 = idx17 + idx7; 2727 int oidx3 = idx17 + idx8; 2728 int oidx4 = idx17 + idx9; 2729 int oidx5 = idx17 + idx10; 2730 2731 out[oidx1 - 1] = i1i + tr2 + tr3; 2732 out[oidx1] = i1r + ti2 + ti3; 2733 out[oidx2 - 1] = w1r * dr2 - w1i * di2; 2734 out[oidx2] = w1r * di2 + w1i * dr2; 2735 out[oidx3 - 1] = w2r * dr3 - w2i * di3; 2736 out[oidx3] = w2r * di3 + w2i * dr3; 2737 out[oidx4 - 1] = w3r * dr4 - w3i * di4; 2738 out[oidx4] = w3r * di4 + w3i * dr4; 2739 out[oidx5 - 1] = w4r * dr5 - w4i * di5; 2740 out[oidx5] = w4r * di5 + w4i * dr5; 2741 } 2742 } 2743 } 2744 2745 /*--------------------------------------------------------- 2746 radfg: Real FFT's forward processing of general factor 2747 --------------------------------------------------------*/ 2748 void radfg(final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 2749 int idij, ipph, j2, ic, jc, lc, is, nbd; 2750 float dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i; 2751 int iw1 = offset; 2752 2753 arg = TWO_PI / (float) ip; 2754 dcp = (float)Math.cos(arg); 2755 dsp = (float)Math.sin(arg); 2756 ipph = (ip + 1) / 2; 2757 nbd = (ido - 1) / 2; 2758 if (ido != 1) { 2759 for (int ik = 0; ik < idl1; ik++) 2760 out[out_off + ik] = in[in_off + ik]; 2761 for (int j = 1; j < ip; j++) { 2762 int idx1 = j * l1 * ido; 2763 for (int k = 0; k < l1; k++) { 2764 int idx2 = k * ido + idx1; 2765 out[out_off + idx2] = in[in_off + idx2]; 2766 } 2767 } 2768 if (nbd <= l1) { 2769 is = -ido; 2770 for (int j = 1; j < ip; j++) { 2771 is += ido; 2772 idij = is - 1; 2773 int idx1 = j * l1 * ido; 2774 for (int i = 2; i < ido; i += 2) { 2775 idij += 2; 2776 int idx2 = idij + iw1; 2777 int idx4 = in_off + i; 2778 int idx5 = out_off + i; 2779 w1r = wtable_r[idx2 - 1]; 2780 w1i = wtable_r[idx2]; 2781 for (int k = 0; k < l1; k++) { 2782 int idx3 = k * ido + idx1; 2783 int oidx1 = idx5 + idx3; 2784 int iidx1 = idx4 + idx3; 2785 float i1i = in[iidx1 - 1]; 2786 float i1r = in[iidx1]; 2787 2788 out[oidx1 - 1] = w1r * i1i + w1i * i1r; 2789 out[oidx1] = w1r * i1r - w1i * i1i; 2790 } 2791 } 2792 } 2793 } else { 2794 is = -ido; 2795 for (int j = 1; j < ip; j++) { 2796 is += ido; 2797 int idx1 = j * l1 * ido; 2798 for (int k = 0; k < l1; k++) { 2799 idij = is - 1; 2800 int idx3 = k * ido + idx1; 2801 for (int i = 2; i < ido; i += 2) { 2802 idij += 2; 2803 int idx2 = idij + iw1; 2804 w1r = wtable_r[idx2 - 1]; 2805 w1i = wtable_r[idx2]; 2806 int oidx1 = out_off + i + idx3; 2807 int iidx1 = in_off + i + idx3; 2808 float i1i = in[iidx1 - 1]; 2809 float i1r = in[iidx1]; 2810 2811 out[oidx1 - 1] = w1r * i1i + w1i * i1r; 2812 out[oidx1] = w1r * i1r - w1i * i1i; 2813 } 2814 } 2815 } 2816 } 2817 if (nbd >= l1) { 2818 for (int j = 1; j < ipph; j++) { 2819 jc = ip - j; 2820 int idx1 = j * l1 * ido; 2821 int idx2 = jc * l1 * ido; 2822 for (int k = 0; k < l1; k++) { 2823 int idx3 = k * ido + idx1; 2824 int idx4 = k * ido + idx2; 2825 for (int i = 2; i < ido; i += 2) { 2826 int idx5 = in_off + i; 2827 int idx6 = out_off + i; 2828 int iidx1 = idx5 + idx3; 2829 int iidx2 = idx5 + idx4; 2830 int oidx1 = idx6 + idx3; 2831 int oidx2 = idx6 + idx4; 2832 float o1i = out[oidx1 - 1]; 2833 float o1r = out[oidx1]; 2834 float o2i = out[oidx2 - 1]; 2835 float o2r = out[oidx2]; 2836 2837 in[iidx1 - 1] = o1i + o2i; 2838 in[iidx1] = o1r + o2r; 2839 2840 in[iidx2 - 1] = o1r - o2r; 2841 in[iidx2] = o2i - o1i; 2842 } 2843 } 2844 } 2845 } else { 2846 for (int j = 1; j < ipph; j++) { 2847 jc = ip - j; 2848 int idx1 = j * l1 * ido; 2849 int idx2 = jc * l1 * ido; 2850 for (int i = 2; i < ido; i += 2) { 2851 int idx5 = in_off + i; 2852 int idx6 = out_off + i; 2853 for (int k = 0; k < l1; k++) { 2854 int idx3 = k * ido + idx1; 2855 int idx4 = k * ido + idx2; 2856 int iidx1 = idx5 + idx3; 2857 int iidx2 = idx5 + idx4; 2858 int oidx1 = idx6 + idx3; 2859 int oidx2 = idx6 + idx4; 2860 float o1i = out[oidx1 - 1]; 2861 float o1r = out[oidx1]; 2862 float o2i = out[oidx2 - 1]; 2863 float o2r = out[oidx2]; 2864 2865 in[iidx1 - 1] = o1i + o2i; 2866 in[iidx1] = o1r + o2r; 2867 in[iidx2 - 1] = o1r - o2r; 2868 in[iidx2] = o2i - o1i; 2869 } 2870 } 2871 } 2872 } 2873 } else { 2874 System.arraycopy(out, out_off, in, in_off, idl1); 2875 } 2876 for (int j = 1; j < ipph; j++) { 2877 jc = ip - j; 2878 int idx1 = j * l1 * ido; 2879 int idx2 = jc * l1 * ido; 2880 for (int k = 0; k < l1; k++) { 2881 int idx3 = k * ido + idx1; 2882 int idx4 = k * ido + idx2; 2883 int oidx1 = out_off + idx3; 2884 int oidx2 = out_off + idx4; 2885 float o1r = out[oidx1]; 2886 float o2r = out[oidx2]; 2887 2888 in[in_off + idx3] = o1r + o2r; 2889 in[in_off + idx4] = o2r - o1r; 2890 } 2891 } 2892 2893 ar1 = 1; 2894 ai1 = 0; 2895 int idx0 = (ip - 1) * idl1; 2896 for (int l = 1; l < ipph; l++) { 2897 lc = ip - l; 2898 ar1h = dcp * ar1 - dsp * ai1; 2899 ai1 = dcp * ai1 + dsp * ar1; 2900 ar1 = ar1h; 2901 int idx1 = l * idl1; 2902 int idx2 = lc * idl1; 2903 for (int ik = 0; ik < idl1; ik++) { 2904 int idx3 = out_off + ik; 2905 int idx4 = in_off + ik; 2906 out[idx3 + idx1] = in[idx4] + ar1 * in[idx4 + idl1]; 2907 out[idx3 + idx2] = ai1 * in[idx4 + idx0]; 2908 } 2909 dc2 = ar1; 2910 ds2 = ai1; 2911 ar2 = ar1; 2912 ai2 = ai1; 2913 for (int j = 2; j < ipph; j++) { 2914 jc = ip - j; 2915 ar2h = dc2 * ar2 - ds2 * ai2; 2916 ai2 = dc2 * ai2 + ds2 * ar2; 2917 ar2 = ar2h; 2918 int idx3 = j * idl1; 2919 int idx4 = jc * idl1; 2920 for (int ik = 0; ik < idl1; ik++) { 2921 int idx5 = out_off + ik; 2922 int idx6 = in_off + ik; 2923 out[idx5 + idx1] += ar2 * in[idx6 + idx3]; 2924 out[idx5 + idx2] += ai2 * in[idx6 + idx4]; 2925 } 2926 } 2927 } 2928 for (int j = 1; j < ipph; j++) { 2929 int idx1 = j * idl1; 2930 for (int ik = 0; ik < idl1; ik++) { 2931 out[out_off + ik] += in[in_off + ik + idx1]; 2932 } 2933 } 2934 2935 if (ido >= l1) { 2936 for (int k = 0; k < l1; k++) { 2937 int idx1 = k * ido; 2938 int idx2 = idx1 * ip; 2939 for (int i = 0; i < ido; i++) { 2940 in[in_off + i + idx2] = out[out_off + i + idx1]; 2941 } 2942 } 2943 } else { 2944 for (int i = 0; i < ido; i++) { 2945 for (int k = 0; k < l1; k++) { 2946 int idx1 = k * ido; 2947 in[in_off + i + idx1 * ip] = out[out_off + i + idx1]; 2948 } 2949 } 2950 } 2951 int idx01 = ip * ido; 2952 for (int j = 1; j < ipph; j++) { 2953 jc = ip - j; 2954 j2 = 2 * j; 2955 int idx1 = j * l1 * ido; 2956 int idx2 = jc * l1 * ido; 2957 int idx3 = j2 * ido; 2958 for (int k = 0; k < l1; k++) { 2959 int idx4 = k * ido; 2960 int idx5 = idx4 + idx1; 2961 int idx6 = idx4 + idx2; 2962 int idx7 = k * idx01; 2963 in[in_off + ido - 1 + idx3 - ido + idx7] = out[out_off + idx5]; 2964 in[in_off + idx3 + idx7] = out[out_off + idx6]; 2965 } 2966 } 2967 if (ido == 1) 2968 return; 2969 if (nbd >= l1) { 2970 for (int j = 1; j < ipph; j++) { 2971 jc = ip - j; 2972 j2 = 2 * j; 2973 int idx1 = j * l1 * ido; 2974 int idx2 = jc * l1 * ido; 2975 int idx3 = j2 * ido; 2976 for (int k = 0; k < l1; k++) { 2977 int idx4 = k * idx01; 2978 int idx5 = k * ido; 2979 for (int i = 2; i < ido; i += 2) { 2980 ic = ido - i; 2981 int idx6 = in_off + i; 2982 int idx7 = in_off + ic; 2983 int idx8 = out_off + i; 2984 int iidx1 = idx6 + idx3 + idx4; 2985 int iidx2 = idx7 + idx3 - ido + idx4; 2986 int oidx1 = idx8 + idx5 + idx1; 2987 int oidx2 = idx8 + idx5 + idx2; 2988 float o1i = out[oidx1 - 1]; 2989 float o1r = out[oidx1]; 2990 float o2i = out[oidx2 - 1]; 2991 float o2r = out[oidx2]; 2992 2993 in[iidx1 - 1] = o1i + o2i; 2994 in[iidx2 - 1] = o1i - o2i; 2995 in[iidx1] = o1r + o2r; 2996 in[iidx2] = o2r - o1r; 2997 } 2998 } 2999 } 3000 } else { 3001 for (int j = 1; j < ipph; j++) { 3002 jc = ip - j; 3003 j2 = 2 * j; 3004 int idx1 = j * l1 * ido; 3005 int idx2 = jc * l1 * ido; 3006 int idx3 = j2 * ido; 3007 for (int i = 2; i < ido; i += 2) { 3008 ic = ido - i; 3009 int idx6 = in_off + i; 3010 int idx7 = in_off + ic; 3011 int idx8 = out_off + i; 3012 for (int k = 0; k < l1; k++) { 3013 int idx4 = k * idx01; 3014 int idx5 = k * ido; 3015 int iidx1 = idx6 + idx3 + idx4; 3016 int iidx2 = idx7 + idx3 - ido + idx4; 3017 int oidx1 = idx8 + idx5 + idx1; 3018 int oidx2 = idx8 + idx5 + idx2; 3019 float o1i = out[oidx1 - 1]; 3020 float o1r = out[oidx1]; 3021 float o2i = out[oidx2 - 1]; 3022 float o2r = out[oidx2]; 3023 3024 in[iidx1 - 1] = o1i + o2i; 3025 in[iidx2 - 1] = o1i - o2i; 3026 in[iidx1] = o1r + o2r; 3027 in[iidx2] = o2r - o1r; 3028 } 3029 } 3030 } 3031 } 3032 } 3033 3034 /*--------------------------------------------------------- 3035 radbg: Real FFT's backward processing of general factor 3036 --------------------------------------------------------*/ 3037 void radbg(final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset) { 3038 int idij, ipph, j2, ic, jc, lc, is; 3039 float dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i; 3040 int nbd; 3041 float dcp, arg, dsp, ar1h, ar2h; 3042 int iw1 = offset; 3043 3044 arg = TWO_PI / (float) ip; 3045 dcp = (float)Math.cos(arg); 3046 dsp = (float)Math.sin(arg); 3047 nbd = (ido - 1) / 2; 3048 ipph = (ip + 1) / 2; 3049 int idx0 = ip * ido; 3050 if (ido >= l1) { 3051 for (int k = 0; k < l1; k++) { 3052 int idx1 = k * ido; 3053 int idx2 = k * idx0; 3054 for (int i = 0; i < ido; i++) { 3055 out[out_off + i + idx1] = in[in_off + i + idx2]; 3056 } 3057 } 3058 } else { 3059 for (int i = 0; i < ido; i++) { 3060 int idx1 = out_off + i; 3061 int idx2 = in_off + i; 3062 for (int k = 0; k < l1; k++) { 3063 out[idx1 + k * ido] = in[idx2 + k * idx0]; 3064 } 3065 } 3066 } 3067 int iidx0 = in_off + ido - 1; 3068 for (int j = 1; j < ipph; j++) { 3069 jc = ip - j; 3070 j2 = 2 * j; 3071 int idx1 = j * l1 * ido; 3072 int idx2 = jc * l1 * ido; 3073 int idx3 = j2 * ido; 3074 for (int k = 0; k < l1; k++) { 3075 int idx4 = k * ido; 3076 int idx5 = idx4 * ip; 3077 int iidx1 = iidx0 + idx3 + idx5 - ido; 3078 int iidx2 = in_off + idx3 + idx5; 3079 float i1r = in[iidx1]; 3080 float i2r = in[iidx2]; 3081 3082 out[out_off + idx4 + idx1] = i1r + i1r; 3083 out[out_off + idx4 + idx2] = i2r + i2r; 3084 } 3085 } 3086 3087 if (ido != 1) { 3088 if (nbd >= l1) { 3089 for (int j = 1; j < ipph; j++) { 3090 jc = ip - j; 3091 int idx1 = j * l1 * ido; 3092 int idx2 = jc * l1 * ido; 3093 int idx3 = 2 * j * ido; 3094 for (int k = 0; k < l1; k++) { 3095 int idx4 = k * ido + idx1; 3096 int idx5 = k * ido + idx2; 3097 int idx6 = k * ip * ido + idx3; 3098 for (int i = 2; i < ido; i += 2) { 3099 ic = ido - i; 3100 int idx7 = out_off + i; 3101 int idx8 = in_off + ic; 3102 int idx9 = in_off + i; 3103 int oidx1 = idx7 + idx4; 3104 int oidx2 = idx7 + idx5; 3105 int iidx1 = idx9 + idx6; 3106 int iidx2 = idx8 + idx6 - ido; 3107 float a1i = in[iidx1 - 1]; 3108 float a1r = in[iidx1]; 3109 float a2i = in[iidx2 - 1]; 3110 float a2r = in[iidx2]; 3111 3112 out[oidx1 - 1] = a1i + a2i; 3113 out[oidx2 - 1] = a1i - a2i; 3114 out[oidx1] = a1r - a2r; 3115 out[oidx2] = a1r + a2r; 3116 } 3117 } 3118 } 3119 } else { 3120 for (int j = 1; j < ipph; j++) { 3121 jc = ip - j; 3122 int idx1 = j * l1 * ido; 3123 int idx2 = jc * l1 * ido; 3124 int idx3 = 2 * j * ido; 3125 for (int i = 2; i < ido; i += 2) { 3126 ic = ido - i; 3127 int idx7 = out_off + i; 3128 int idx8 = in_off + ic; 3129 int idx9 = in_off + i; 3130 for (int k = 0; k < l1; k++) { 3131 int idx4 = k * ido + idx1; 3132 int idx5 = k * ido + idx2; 3133 int idx6 = k * ip * ido + idx3; 3134 int oidx1 = idx7 + idx4; 3135 int oidx2 = idx7 + idx5; 3136 int iidx1 = idx9 + idx6; 3137 int iidx2 = idx8 + idx6 - ido; 3138 float a1i = in[iidx1 - 1]; 3139 float a1r = in[iidx1]; 3140 float a2i = in[iidx2 - 1]; 3141 float a2r = in[iidx2]; 3142 3143 out[oidx1 - 1] = a1i + a2i; 3144 out[oidx2 - 1] = a1i - a2i; 3145 out[oidx1] = a1r - a2r; 3146 out[oidx2] = a1r + a2r; 3147 } 3148 } 3149 } 3150 } 3151 } 3152 3153 ar1 = 1; 3154 ai1 = 0; 3155 int idx01 = (ip - 1) * idl1; 3156 for (int l = 1; l < ipph; l++) { 3157 lc = ip - l; 3158 ar1h = dcp * ar1 - dsp * ai1; 3159 ai1 = dcp * ai1 + dsp * ar1; 3160 ar1 = ar1h; 3161 int idx1 = l * idl1; 3162 int idx2 = lc * idl1; 3163 for (int ik = 0; ik < idl1; ik++) { 3164 int idx3 = in_off + ik; 3165 int idx4 = out_off + ik; 3166 in[idx3 + idx1] = out[idx4] + ar1 * out[idx4 + idl1]; 3167 in[idx3 + idx2] = ai1 * out[idx4 + idx01]; 3168 } 3169 dc2 = ar1; 3170 ds2 = ai1; 3171 ar2 = ar1; 3172 ai2 = ai1; 3173 for (int j = 2; j < ipph; j++) { 3174 jc = ip - j; 3175 ar2h = dc2 * ar2 - ds2 * ai2; 3176 ai2 = dc2 * ai2 + ds2 * ar2; 3177 ar2 = ar2h; 3178 int idx5 = j * idl1; 3179 int idx6 = jc * idl1; 3180 for (int ik = 0; ik < idl1; ik++) { 3181 int idx7 = in_off + ik; 3182 int idx8 = out_off + ik; 3183 in[idx7 + idx1] += ar2 * out[idx8 + idx5]; 3184 in[idx7 + idx2] += ai2 * out[idx8 + idx6]; 3185 } 3186 } 3187 } 3188 for (int j = 1; j < ipph; j++) { 3189 int idx1 = j * idl1; 3190 for (int ik = 0; ik < idl1; ik++) { 3191 int idx2 = out_off + ik; 3192 out[idx2] += out[idx2 + idx1]; 3193 } 3194 } 3195 for (int j = 1; j < ipph; j++) { 3196 jc = ip - j; 3197 int idx1 = j * l1 * ido; 3198 int idx2 = jc * l1 * ido; 3199 for (int k = 0; k < l1; k++) { 3200 int idx3 = k * ido; 3201 int oidx1 = out_off + idx3; 3202 int iidx1 = in_off + idx3 + idx1; 3203 int iidx2 = in_off + idx3 + idx2; 3204 float i1r = in[iidx1]; 3205 float i2r = in[iidx2]; 3206 3207 out[oidx1 + idx1] = i1r - i2r; 3208 out[oidx1 + idx2] = i1r + i2r; 3209 } 3210 } 3211 3212 if (ido == 1) 3213 return; 3214 if (nbd >= l1) { 3215 for (int j = 1; j < ipph; j++) { 3216 jc = ip - j; 3217 int idx1 = j * l1 * ido; 3218 int idx2 = jc * l1 * ido; 3219 for (int k = 0; k < l1; k++) { 3220 int idx3 = k * ido; 3221 for (int i = 2; i < ido; i += 2) { 3222 int idx4 = out_off + i; 3223 int idx5 = in_off + i; 3224 int oidx1 = idx4 + idx3 + idx1; 3225 int oidx2 = idx4 + idx3 + idx2; 3226 int iidx1 = idx5 + idx3 + idx1; 3227 int iidx2 = idx5 + idx3 + idx2; 3228 float i1i = in[iidx1 - 1]; 3229 float i1r = in[iidx1]; 3230 float i2i = in[iidx2 - 1]; 3231 float i2r = in[iidx2]; 3232 3233 out[oidx1 - 1] = i1i - i2r; 3234 out[oidx2 - 1] = i1i + i2r; 3235 out[oidx1] = i1r + i2i; 3236 out[oidx2] = i1r - i2i; 3237 } 3238 } 3239 } 3240 } else { 3241 for (int j = 1; j < ipph; j++) { 3242 jc = ip - j; 3243 int idx1 = j * l1 * ido; 3244 int idx2 = jc * l1 * ido; 3245 for (int i = 2; i < ido; i += 2) { 3246 int idx4 = out_off + i; 3247 int idx5 = in_off + i; 3248 for (int k = 0; k < l1; k++) { 3249 int idx3 = k * ido; 3250 int oidx1 = idx4 + idx3 + idx1; 3251 int oidx2 = idx4 + idx3 + idx2; 3252 int iidx1 = idx5 + idx3 + idx1; 3253 int iidx2 = idx5 + idx3 + idx2; 3254 float i1i = in[iidx1 - 1]; 3255 float i1r = in[iidx1]; 3256 float i2i = in[iidx2 - 1]; 3257 float i2r = in[iidx2]; 3258 3259 out[oidx1 - 1] = i1i - i2r; 3260 out[oidx2 - 1] = i1i + i2r; 3261 out[oidx1] = i1r + i2i; 3262 out[oidx2] = i1r - i2i; 3263 } 3264 } 3265 } 3266 } 3267 System.arraycopy(out, out_off, in, in_off, idl1); 3268 for (int j = 1; j < ip; j++) { 3269 int idx1 = j * l1 * ido; 3270 for (int k = 0; k < l1; k++) { 3271 int idx2 = k * ido + idx1; 3272 in[in_off + idx2] = out[out_off + idx2]; 3273 } 3274 } 3275 if (nbd <= l1) { 3276 is = -ido; 3277 for (int j = 1; j < ip; j++) { 3278 is += ido; 3279 idij = is - 1; 3280 int idx1 = j * l1 * ido; 3281 for (int i = 2; i < ido; i += 2) { 3282 idij += 2; 3283 int idx2 = idij + iw1; 3284 w1r = wtable_r[idx2 - 1]; 3285 w1i = wtable_r[idx2]; 3286 int idx4 = in_off + i; 3287 int idx5 = out_off + i; 3288 for (int k = 0; k < l1; k++) { 3289 int idx3 = k * ido + idx1; 3290 int iidx1 = idx4 + idx3; 3291 int oidx1 = idx5 + idx3; 3292 float o1i = out[oidx1 - 1]; 3293 float o1r = out[oidx1]; 3294 3295 in[iidx1 - 1] = w1r * o1i - w1i * o1r; 3296 in[iidx1] = w1r * o1r + w1i * o1i; 3297 } 3298 } 3299 } 3300 } else { 3301 is = -ido; 3302 for (int j = 1; j < ip; j++) { 3303 is += ido; 3304 int idx1 = j * l1 * ido; 3305 for (int k = 0; k < l1; k++) { 3306 idij = is - 1; 3307 int idx3 = k * ido + idx1; 3308 for (int i = 2; i < ido; i += 2) { 3309 idij += 2; 3310 int idx2 = idij + iw1; 3311 w1r = wtable_r[idx2 - 1]; 3312 w1i = wtable_r[idx2]; 3313 int idx4 = in_off + i; 3314 int idx5 = out_off + i; 3315 int iidx1 = idx4 + idx3; 3316 int oidx1 = idx5 + idx3; 3317 float o1i = out[oidx1 - 1]; 3318 float o1r = out[oidx1]; 3319 3320 in[iidx1 - 1] = w1r * o1i - w1i * o1r; 3321 in[iidx1] = w1r * o1r + w1i * o1i; 3322 3323 } 3324 } 3325 } 3326 } 3327 } 3328 3329 /*--------------------------------------------------------- 3330 cfftf1: further processing of Complex forward FFT 3331 --------------------------------------------------------*/ 3332 void cfftf(float a[], int offa, int isign) { 3333 int idot; 3334 int l1, l2; 3335 int na, nf, ip, iw, ido, idl1; 3336 int[] nac = new int[1]; 3337 final int twon = 2 * n; 3338 3339 int iw1, iw2; 3340 float[] ch = new float[twon]; 3341 3342 iw1 = twon; 3343 iw2 = 4 * n; 3344 nac[0] = 0; 3345 nf = (int) wtable[1 + iw2]; 3346 na = 0; 3347 l1 = 1; 3348 iw = iw1; 3349 for (int k1 = 2; k1 <= nf + 1; k1++) { 3350 ip = (int) wtable[k1 + iw2]; 3351 l2 = ip * l1; 3352 ido = n / l2; 3353 idot = ido + ido; 3354 idl1 = idot * l1; 3355 switch (ip) { 3356 case 4: 3357 if (na == 0) { 3358 passf4(idot, l1, a, offa, ch, 0, iw, isign); 3359 } else { 3360 passf4(idot, l1, ch, 0, a, offa, iw, isign); 3361 } 3362 na = 1 - na; 3363 break; 3364 case 2: 3365 if (na == 0) { 3366 passf2(idot, l1, a, offa, ch, 0, iw, isign); 3367 } else { 3368 passf2(idot, l1, ch, 0, a, offa, iw, isign); 3369 } 3370 na = 1 - na; 3371 break; 3372 case 3: 3373 if (na == 0) { 3374 passf3(idot, l1, a, offa, ch, 0, iw, isign); 3375 } else { 3376 passf3(idot, l1, ch, 0, a, offa, iw, isign); 3377 } 3378 na = 1 - na; 3379 break; 3380 case 5: 3381 if (na == 0) { 3382 passf5(idot, l1, a, offa, ch, 0, iw, isign); 3383 } else { 3384 passf5(idot, l1, ch, 0, a, offa, iw, isign); 3385 } 3386 na = 1 - na; 3387 break; 3388 default: 3389 if (na == 0) { 3390 passfg(nac, idot, ip, l1, idl1, a, offa, ch, 0, iw, isign); 3391 } else { 3392 passfg(nac, idot, ip, l1, idl1, ch, 0, a, offa, iw, isign); 3393 } 3394 if (nac[0] != 0) 3395 na = 1 - na; 3396 break; 3397 } 3398 l1 = l2; 3399 iw += (ip - 1) * idot; 3400 } 3401 if (na == 0) 3402 return; 3403 System.arraycopy(ch, 0, a, offa, twon); 3404 3405 } 3406 3407 /*---------------------------------------------------------------------- 3408 passf2: Complex FFT's forward/backward processing of factor 2; 3409 isign is +1 for backward and -1 for forward transforms 3410 ----------------------------------------------------------------------*/ 3411 3412 void passf2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) { 3413 float t1i, t1r; 3414 int iw1; 3415 iw1 = offset; 3416 int idx = ido * l1; 3417 if (ido <= 2) { 3418 for (int k = 0; k < l1; k++) { 3419 int idx0 = k * ido; 3420 int iidx1 = in_off + 2 * idx0; 3421 int iidx2 = iidx1 + ido; 3422 float a1r = in[iidx1]; 3423 float a1i = in[iidx1 + 1]; 3424 float a2r = in[iidx2]; 3425 float a2i = in[iidx2 + 1]; 3426 3427 int oidx1 = out_off + idx0; 3428 int oidx2 = oidx1 + idx; 3429 out[oidx1] = a1r + a2r; 3430 out[oidx1 + 1] = a1i + a2i; 3431 out[oidx2] = a1r - a2r; 3432 out[oidx2 + 1] = a1i - a2i; 3433 } 3434 } else { 3435 for (int k = 0; k < l1; k++) { 3436 for (int i = 0; i < ido - 1; i += 2) { 3437 int idx0 = k * ido; 3438 int iidx1 = in_off + i + 2 * idx0; 3439 int iidx2 = iidx1 + ido; 3440 float i1r = in[iidx1]; 3441 float i1i = in[iidx1 + 1]; 3442 float i2r = in[iidx2]; 3443 float i2i = in[iidx2 + 1]; 3444 3445 int widx1 = i + iw1; 3446 float w1r = wtable[widx1]; 3447 float w1i = isign * wtable[widx1 + 1]; 3448 3449 t1r = i1r - i2r; 3450 t1i = i1i - i2i; 3451 3452 int oidx1 = out_off + i + idx0; 3453 int oidx2 = oidx1 + idx; 3454 out[oidx1] = i1r + i2r; 3455 out[oidx1 + 1] = i1i + i2i; 3456 out[oidx2] = w1r * t1r - w1i * t1i; 3457 out[oidx2 + 1] = w1r * t1i + w1i * t1r; 3458 } 3459 } 3460 } 3461 } 3462 3463 /*---------------------------------------------------------------------- 3464 passf3: Complex FFT's forward/backward processing of factor 3; 3465 isign is +1 for backward and -1 for forward transforms 3466 ----------------------------------------------------------------------*/ 3467 void passf3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) { 3468 final float taur = -0.5f; 3469 final float taui = 0.866025403784438707610604524234076962f; 3470 float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2; 3471 int iw1, iw2; 3472 3473 iw1 = offset; 3474 iw2 = iw1 + ido; 3475 3476 final int idxt = l1 * ido; 3477 3478 if (ido == 2) { 3479 for (int k = 1; k <= l1; k++) { 3480 int iidx1 = in_off + (3 * k - 2) * ido; 3481 int iidx2 = iidx1 + ido; 3482 int iidx3 = iidx1 - ido; 3483 float i1r = in[iidx1]; 3484 float i1i = in[iidx1 + 1]; 3485 float i2r = in[iidx2]; 3486 float i2i = in[iidx2 + 1]; 3487 float i3r = in[iidx3]; 3488 float i3i = in[iidx3 + 1]; 3489 3490 tr2 = i1r + i2r; 3491 cr2 = i3r + taur * tr2; 3492 ti2 = i1i + i2i; 3493 ci2 = i3i + taur * ti2; 3494 cr3 = isign * taui * (i1r - i2r); 3495 ci3 = isign * taui * (i1i - i2i); 3496 3497 int oidx1 = out_off + (k - 1) * ido; 3498 int oidx2 = oidx1 + idxt; 3499 int oidx3 = oidx2 + idxt; 3500 out[oidx1] = in[iidx3] + tr2; 3501 out[oidx1 + 1] = i3i + ti2; 3502 out[oidx2] = cr2 - ci3; 3503 out[oidx2 + 1] = ci2 + cr3; 3504 out[oidx3] = cr2 + ci3; 3505 out[oidx3 + 1] = ci2 - cr3; 3506 } 3507 } else { 3508 for (int k = 1; k <= l1; k++) { 3509 int idx1 = in_off + (3 * k - 2) * ido; 3510 int idx2 = out_off + (k - 1) * ido; 3511 for (int i = 0; i < ido - 1; i += 2) { 3512 int iidx1 = i + idx1; 3513 int iidx2 = iidx1 + ido; 3514 int iidx3 = iidx1 - ido; 3515 float a1r = in[iidx1]; 3516 float a1i = in[iidx1 + 1]; 3517 float a2r = in[iidx2]; 3518 float a2i = in[iidx2 + 1]; 3519 float a3r = in[iidx3]; 3520 float a3i = in[iidx3 + 1]; 3521 3522 tr2 = a1r + a2r; 3523 cr2 = a3r + taur * tr2; 3524 ti2 = a1i + a2i; 3525 ci2 = a3i + taur * ti2; 3526 cr3 = isign * taui * (a1r - a2r); 3527 ci3 = isign * taui * (a1i - a2i); 3528 dr2 = cr2 - ci3; 3529 dr3 = cr2 + ci3; 3530 di2 = ci2 + cr3; 3531 di3 = ci2 - cr3; 3532 3533 int widx1 = i + iw1; 3534 int widx2 = i + iw2; 3535 float w1r = wtable[widx1]; 3536 float w1i = isign * wtable[widx1 + 1]; 3537 float w2r = wtable[widx2]; 3538 float w2i = isign * wtable[widx2 + 1]; 3539 3540 int oidx1 = i + idx2; 3541 int oidx2 = oidx1 + idxt; 3542 int oidx3 = oidx2 + idxt; 3543 out[oidx1] = a3r + tr2; 3544 out[oidx1 + 1] = a3i + ti2; 3545 out[oidx2] = w1r * dr2 - w1i * di2; 3546 out[oidx2 + 1] = w1r * di2 + w1i * dr2; 3547 out[oidx3] = w2r * dr3 - w2i * di3; 3548 out[oidx3 + 1] = w2r * di3 + w2i * dr3; 3549 } 3550 } 3551 } 3552 } 3553 3554 /*---------------------------------------------------------------------- 3555 passf4: Complex FFT's forward/backward processing of factor 4; 3556 isign is +1 for backward and -1 for forward transforms 3557 ----------------------------------------------------------------------*/ 3558 void passf4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) { 3559 float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4; 3560 int iw1, iw2, iw3; 3561 iw1 = offset; 3562 iw2 = iw1 + ido; 3563 iw3 = iw2 + ido; 3564 3565 int idx0 = l1 * ido; 3566 if (ido == 2) { 3567 for (int k = 0; k < l1; k++) { 3568 int idxt1 = k * ido; 3569 int iidx1 = in_off + 4 * idxt1 + 1; 3570 int iidx2 = iidx1 + ido; 3571 int iidx3 = iidx2 + ido; 3572 int iidx4 = iidx3 + ido; 3573 3574 float i1i = in[iidx1 - 1]; 3575 float i1r = in[iidx1]; 3576 float i2i = in[iidx2 - 1]; 3577 float i2r = in[iidx2]; 3578 float i3i = in[iidx3 - 1]; 3579 float i3r = in[iidx3]; 3580 float i4i = in[iidx4 - 1]; 3581 float i4r = in[iidx4]; 3582 3583 ti1 = i1r - i3r; 3584 ti2 = i1r + i3r; 3585 tr4 = i4r - i2r; 3586 ti3 = i2r + i4r; 3587 tr1 = i1i - i3i; 3588 tr2 = i1i + i3i; 3589 ti4 = i2i - i4i; 3590 tr3 = i2i + i4i; 3591 3592 int oidx1 = out_off + idxt1; 3593 int oidx2 = oidx1 + idx0; 3594 int oidx3 = oidx2 + idx0; 3595 int oidx4 = oidx3 + idx0; 3596 out[oidx1] = tr2 + tr3; 3597 out[oidx1 + 1] = ti2 + ti3; 3598 out[oidx2] = tr1 + isign * tr4; 3599 out[oidx2 + 1] = ti1 + isign * ti4; 3600 out[oidx3] = tr2 - tr3; 3601 out[oidx3 + 1] = ti2 - ti3; 3602 out[oidx4] = tr1 - isign * tr4; 3603 out[oidx4 + 1] = ti1 - isign * ti4; 3604 } 3605 } else { 3606 for (int k = 0; k < l1; k++) { 3607 int idx1 = k * ido; 3608 int idx2 = in_off + 1 + 4 * idx1; 3609 for (int i = 0; i < ido - 1; i += 2) { 3610 int iidx1 = i + idx2; 3611 int iidx2 = iidx1 + ido; 3612 int iidx3 = iidx2 + ido; 3613 int iidx4 = iidx3 + ido; 3614 float i1i = in[iidx1 - 1]; 3615 float i1r = in[iidx1]; 3616 float i2i = in[iidx2 - 1]; 3617 float i2r = in[iidx2]; 3618 float i3i = in[iidx3 - 1]; 3619 float i3r = in[iidx3]; 3620 float i4i = in[iidx4 - 1]; 3621 float i4r = in[iidx4]; 3622 3623 ti1 = i1r - i3r; 3624 ti2 = i1r + i3r; 3625 ti3 = i2r + i4r; 3626 tr4 = i4r - i2r; 3627 tr1 = i1i - i3i; 3628 tr2 = i1i + i3i; 3629 ti4 = i2i - i4i; 3630 tr3 = i2i + i4i; 3631 cr3 = tr2 - tr3; 3632 ci3 = ti2 - ti3; 3633 cr2 = tr1 + isign * tr4; 3634 cr4 = tr1 - isign * tr4; 3635 ci2 = ti1 + isign * ti4; 3636 ci4 = ti1 - isign * ti4; 3637 3638 int widx1 = i + iw1; 3639 int widx2 = i + iw2; 3640 int widx3 = i + iw3; 3641 float w1r = wtable[widx1]; 3642 float w1i = isign * wtable[widx1 + 1]; 3643 float w2r = wtable[widx2]; 3644 float w2i = isign * wtable[widx2 + 1]; 3645 float w3r = wtable[widx3]; 3646 float w3i = isign * wtable[widx3 + 1]; 3647 3648 int oidx1 = out_off + i + idx1; 3649 int oidx2 = oidx1 + idx0; 3650 int oidx3 = oidx2 + idx0; 3651 int oidx4 = oidx3 + idx0; 3652 out[oidx1] = tr2 + tr3; 3653 out[oidx1 + 1] = ti2 + ti3; 3654 out[oidx2] = w1r * cr2 - w1i * ci2; 3655 out[oidx2 + 1] = w1r * ci2 + w1i * cr2; 3656 out[oidx3] = w2r * cr3 - w2i * ci3; 3657 out[oidx3 + 1] = w2r * ci3 + w2i * cr3; 3658 out[oidx4] = w3r * cr4 - w3i * ci4; 3659 out[oidx4 + 1] = w3r * ci4 + w3i * cr4; 3660 } 3661 } 3662 } 3663 } 3664 3665 /*---------------------------------------------------------------------- 3666 passf5: Complex FFT's forward/backward processing of factor 5; 3667 isign is +1 for backward and -1 for forward transforms 3668 ----------------------------------------------------------------------*/ 3669 void passf5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) 3670 /* isign==-1 for forward transform and+1 for backward transform */ 3671 { 3672 final float tr11 = 0.309016994374947451262869435595348477f; 3673 final float ti11 = 0.951056516295153531181938433292089030f; 3674 final float tr12 = -0.809016994374947340240566973079694435f; 3675 final float ti12 = 0.587785252292473248125759255344746634f; 3676 float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5; 3677 int iw1, iw2, iw3, iw4; 3678 3679 iw1 = offset; 3680 iw2 = iw1 + ido; 3681 iw3 = iw2 + ido; 3682 iw4 = iw3 + ido; 3683 3684 int idx0 = l1 * ido; 3685 3686 if (ido == 2) { 3687 for (int k = 1; k <= l1; ++k) { 3688 int iidx1 = in_off + (5 * k - 4) * ido + 1; 3689 int iidx2 = iidx1 + ido; 3690 int iidx3 = iidx1 - ido; 3691 int iidx4 = iidx2 + ido; 3692 int iidx5 = iidx4 + ido; 3693 3694 float i1i = in[iidx1 - 1]; 3695 float i1r = in[iidx1]; 3696 float i2i = in[iidx2 - 1]; 3697 float i2r = in[iidx2]; 3698 float i3i = in[iidx3 - 1]; 3699 float i3r = in[iidx3]; 3700 float i4i = in[iidx4 - 1]; 3701 float i4r = in[iidx4]; 3702 float i5i = in[iidx5 - 1]; 3703 float i5r = in[iidx5]; 3704 3705 ti5 = i1r - i5r; 3706 ti2 = i1r + i5r; 3707 ti4 = i2r - i4r; 3708 ti3 = i2r + i4r; 3709 tr5 = i1i - i5i; 3710 tr2 = i1i + i5i; 3711 tr4 = i2i - i4i; 3712 tr3 = i2i + i4i; 3713 cr2 = i3i + tr11 * tr2 + tr12 * tr3; 3714 ci2 = i3r + tr11 * ti2 + tr12 * ti3; 3715 cr3 = i3i + tr12 * tr2 + tr11 * tr3; 3716 ci3 = i3r + tr12 * ti2 + tr11 * ti3; 3717 cr5 = isign * (ti11 * tr5 + ti12 * tr4); 3718 ci5 = isign * (ti11 * ti5 + ti12 * ti4); 3719 cr4 = isign * (ti12 * tr5 - ti11 * tr4); 3720 ci4 = isign * (ti12 * ti5 - ti11 * ti4); 3721 3722 int oidx1 = out_off + (k - 1) * ido; 3723 int oidx2 = oidx1 + idx0; 3724 int oidx3 = oidx2 + idx0; 3725 int oidx4 = oidx3 + idx0; 3726 int oidx5 = oidx4 + idx0; 3727 out[oidx1] = i3i + tr2 + tr3; 3728 out[oidx1 + 1] = i3r + ti2 + ti3; 3729 out[oidx2] = cr2 - ci5; 3730 out[oidx2 + 1] = ci2 + cr5; 3731 out[oidx3] = cr3 - ci4; 3732 out[oidx3 + 1] = ci3 + cr4; 3733 out[oidx4] = cr3 + ci4; 3734 out[oidx4 + 1] = ci3 - cr4; 3735 out[oidx5] = cr2 + ci5; 3736 out[oidx5 + 1] = ci2 - cr5; 3737 } 3738 } else { 3739 for (int k = 1; k <= l1; k++) { 3740 int idx1 = in_off + 1 + (k * 5 - 4) * ido; 3741 int idx2 = out_off + (k - 1) * ido; 3742 for (int i = 0; i < ido - 1; i += 2) { 3743 int iidx1 = i + idx1; 3744 int iidx2 = iidx1 + ido; 3745 int iidx3 = iidx1 - ido; 3746 int iidx4 = iidx2 + ido; 3747 int iidx5 = iidx4 + ido; 3748 float i1i = in[iidx1 - 1]; 3749 float i1r = in[iidx1]; 3750 float i2i = in[iidx2 - 1]; 3751 float i2r = in[iidx2]; 3752 float i3i = in[iidx3 - 1]; 3753 float i3r = in[iidx3]; 3754 float i4i = in[iidx4 - 1]; 3755 float i4r = in[iidx4]; 3756 float i5i = in[iidx5 - 1]; 3757 float i5r = in[iidx5]; 3758 3759 ti5 = i1r - i5r; 3760 ti2 = i1r + i5r; 3761 ti4 = i2r - i4r; 3762 ti3 = i2r + i4r; 3763 tr5 = i1i - i5i; 3764 tr2 = i1i + i5i; 3765 tr4 = i2i - i4i; 3766 tr3 = i2i + i4i; 3767 cr2 = i3i + tr11 * tr2 + tr12 * tr3; 3768 ci2 = i3r + tr11 * ti2 + tr12 * ti3; 3769 cr3 = i3i + tr12 * tr2 + tr11 * tr3; 3770 ci3 = i3r + tr12 * ti2 + tr11 * ti3; 3771 cr5 = isign * (ti11 * tr5 + ti12 * tr4); 3772 ci5 = isign * (ti11 * ti5 + ti12 * ti4); 3773 cr4 = isign * (ti12 * tr5 - ti11 * tr4); 3774 ci4 = isign * (ti12 * ti5 - ti11 * ti4); 3775 dr3 = cr3 - ci4; 3776 dr4 = cr3 + ci4; 3777 di3 = ci3 + cr4; 3778 di4 = ci3 - cr4; 3779 dr5 = cr2 + ci5; 3780 dr2 = cr2 - ci5; 3781 di5 = ci2 - cr5; 3782 di2 = ci2 + cr5; 3783 3784 int widx1 = i + iw1; 3785 int widx2 = i + iw2; 3786 int widx3 = i + iw3; 3787 int widx4 = i + iw4; 3788 float w1r = wtable[widx1]; 3789 float w1i = isign * wtable[widx1 + 1]; 3790 float w2r = wtable[widx2]; 3791 float w2i = isign * wtable[widx2 + 1]; 3792 float w3r = wtable[widx3]; 3793 float w3i = isign * wtable[widx3 + 1]; 3794 float w4r = wtable[widx4]; 3795 float w4i = isign * wtable[widx4 + 1]; 3796 3797 int oidx1 = i + idx2; 3798 int oidx2 = oidx1 + idx0; 3799 int oidx3 = oidx2 + idx0; 3800 int oidx4 = oidx3 + idx0; 3801 int oidx5 = oidx4 + idx0; 3802 out[oidx1] = i3i + tr2 + tr3; 3803 out[oidx1 + 1] = i3r + ti2 + ti3; 3804 out[oidx2] = w1r * dr2 - w1i * di2; 3805 out[oidx2 + 1] = w1r * di2 + w1i * dr2; 3806 out[oidx3] = w2r * dr3 - w2i * di3; 3807 out[oidx3 + 1] = w2r * di3 + w2i * dr3; 3808 out[oidx4] = w3r * dr4 - w3i * di4; 3809 out[oidx4 + 1] = w3r * di4 + w3i * dr4; 3810 out[oidx5] = w4r * dr5 - w4i * di5; 3811 out[oidx5 + 1] = w4r * di5 + w4i * dr5; 3812 } 3813 } 3814 } 3815 } 3816 3817 /*---------------------------------------------------------------------- 3818 passfg: Complex FFT's forward/backward processing of general factor; 3819 isign is +1 for backward and -1 for forward transforms 3820 ----------------------------------------------------------------------*/ 3821 void passfg(final int nac[], final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) { 3822 int idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp; 3823 float w1r, w1i, w2i, w2r; 3824 int iw1; 3825 3826 iw1 = offset; 3827 idot = ido / 2; 3828 ipph = (ip + 1) / 2; 3829 idp = ip * ido; 3830 if (ido >= l1) { 3831 for (int j = 1; j < ipph; j++) { 3832 jc = ip - j; 3833 int idx1 = j * ido; 3834 int idx2 = jc * ido; 3835 for (int k = 0; k < l1; k++) { 3836 int idx3 = k * ido; 3837 int idx4 = idx3 + idx1 * l1; 3838 int idx5 = idx3 + idx2 * l1; 3839 int idx6 = idx3 * ip; 3840 for (int i = 0; i < ido; i++) { 3841 int oidx1 = out_off + i; 3842 float i1r = in[in_off + i + idx1 + idx6]; 3843 float i2r = in[in_off + i + idx2 + idx6]; 3844 out[oidx1 + idx4] = i1r + i2r; 3845 out[oidx1 + idx5] = i1r - i2r; 3846 } 3847 } 3848 } 3849 for (int k = 0; k < l1; k++) { 3850 int idxt1 = k * ido; 3851 int idxt2 = idxt1 * ip; 3852 for (int i = 0; i < ido; i++) { 3853 out[out_off + i + idxt1] = in[in_off + i + idxt2]; 3854 } 3855 } 3856 } else { 3857 for (int j = 1; j < ipph; j++) { 3858 jc = ip - j; 3859 int idxt1 = j * l1 * ido; 3860 int idxt2 = jc * l1 * ido; 3861 int idxt3 = j * ido; 3862 int idxt4 = jc * ido; 3863 for (int i = 0; i < ido; i++) { 3864 for (int k = 0; k < l1; k++) { 3865 int idx1 = k * ido; 3866 int idx2 = idx1 * ip; 3867 int idx3 = out_off + i; 3868 int idx4 = in_off + i; 3869 float i1r = in[idx4 + idxt3 + idx2]; 3870 float i2r = in[idx4 + idxt4 + idx2]; 3871 out[idx3 + idx1 + idxt1] = i1r + i2r; 3872 out[idx3 + idx1 + idxt2] = i1r - i2r; 3873 } 3874 } 3875 } 3876 for (int i = 0; i < ido; i++) { 3877 for (int k = 0; k < l1; k++) { 3878 int idx1 = k * ido; 3879 out[out_off + i + idx1] = in[in_off + i + idx1 * ip]; 3880 } 3881 } 3882 } 3883 3884 idl = 2 - ido; 3885 inc = 0; 3886 int idxt0 = (ip - 1) * idl1; 3887 for (l = 1; l < ipph; l++) { 3888 lc = ip - l; 3889 idl += ido; 3890 int idxt1 = l * idl1; 3891 int idxt2 = lc * idl1; 3892 int idxt3 = idl + iw1; 3893 w1r = wtable[idxt3 - 2]; 3894 w1i = isign * wtable[idxt3 - 1]; 3895 for (int ik = 0; ik < idl1; ik++) { 3896 int idx1 = in_off + ik; 3897 int idx2 = out_off + ik; 3898 in[idx1 + idxt1] = out[idx2] + w1r * out[idx2 + idl1]; 3899 in[idx1 + idxt2] = w1i * out[idx2 + idxt0]; 3900 } 3901 idlj = idl; 3902 inc += ido; 3903 for (int j = 2; j < ipph; j++) { 3904 jc = ip - j; 3905 idlj += inc; 3906 if (idlj > idp) 3907 idlj -= idp; 3908 int idxt4 = idlj + iw1; 3909 w2r = wtable[idxt4 - 2]; 3910 w2i = isign * wtable[idxt4 - 1]; 3911 int idxt5 = j * idl1; 3912 int idxt6 = jc * idl1; 3913 for (int ik = 0; ik < idl1; ik++) { 3914 int idx1 = in_off + ik; 3915 int idx2 = out_off + ik; 3916 in[idx1 + idxt1] += w2r * out[idx2 + idxt5]; 3917 in[idx1 + idxt2] += w2i * out[idx2 + idxt6]; 3918 } 3919 } 3920 } 3921 for (int j = 1; j < ipph; j++) { 3922 int idxt1 = j * idl1; 3923 for (int ik = 0; ik < idl1; ik++) { 3924 int idx1 = out_off + ik; 3925 out[idx1] += out[idx1 + idxt1]; 3926 } 3927 } 3928 for (int j = 1; j < ipph; j++) { 3929 jc = ip - j; 3930 int idx1 = j * idl1; 3931 int idx2 = jc * idl1; 3932 for (int ik = 1; ik < idl1; ik += 2) { 3933 int idx3 = out_off + ik; 3934 int idx4 = in_off + ik; 3935 int iidx1 = idx4 + idx1; 3936 int iidx2 = idx4 + idx2; 3937 float i1i = in[iidx1 - 1]; 3938 float i1r = in[iidx1]; 3939 float i2i = in[iidx2 - 1]; 3940 float i2r = in[iidx2]; 3941 3942 int oidx1 = idx3 + idx1; 3943 int oidx2 = idx3 + idx2; 3944 out[oidx1 - 1] = i1i - i2r; 3945 out[oidx2 - 1] = i1i + i2r; 3946 out[oidx1] = i1r + i2i; 3947 out[oidx2] = i1r - i2i; 3948 } 3949 } 3950 nac[0] = 1; 3951 if (ido == 2) 3952 return; 3953 nac[0] = 0; 3954 System.arraycopy(out, out_off, in, in_off, idl1); 3955 int idx0 = l1 * ido; 3956 for (int j = 1; j < ip; j++) { 3957 int idx1 = j * idx0; 3958 for (int k = 0; k < l1; k++) { 3959 int idx2 = k * ido; 3960 int oidx1 = out_off + idx2 + idx1; 3961 int iidx1 = in_off + idx2 + idx1; 3962 in[iidx1] = out[oidx1]; 3963 in[iidx1 + 1] = out[oidx1 + 1]; 3964 } 3965 } 3966 if (idot <= l1) { 3967 idij = 0; 3968 for (int j = 1; j < ip; j++) { 3969 idij += 2; 3970 int idx1 = j * l1 * ido; 3971 for (int i = 3; i < ido; i += 2) { 3972 idij += 2; 3973 int idx2 = idij + iw1 - 1; 3974 w1r = wtable[idx2 - 1]; 3975 w1i = isign * wtable[idx2]; 3976 int idx3 = in_off + i; 3977 int idx4 = out_off + i; 3978 for (int k = 0; k < l1; k++) { 3979 int idx5 = k * ido + idx1; 3980 int iidx1 = idx3 + idx5; 3981 int oidx1 = idx4 + idx5; 3982 float o1i = out[oidx1 - 1]; 3983 float o1r = out[oidx1]; 3984 in[iidx1 - 1] = w1r * o1i - w1i * o1r; 3985 in[iidx1] = w1r * o1r + w1i * o1i; 3986 } 3987 } 3988 } 3989 } else { 3990 idj = 2 - ido; 3991 for (int j = 1; j < ip; j++) { 3992 idj += ido; 3993 int idx1 = j * l1 * ido; 3994 for (int k = 0; k < l1; k++) { 3995 idij = idj; 3996 int idx3 = k * ido + idx1; 3997 for (int i = 3; i < ido; i += 2) { 3998 idij += 2; 3999 int idx2 = idij - 1 + iw1; 4000 w1r = wtable[idx2 - 1]; 4001 w1i = isign * wtable[idx2]; 4002 int iidx1 = in_off + i + idx3; 4003 int oidx1 = out_off + i + idx3; 4004 float o1i = out[oidx1 - 1]; 4005 float o1r = out[oidx1]; 4006 in[iidx1 - 1] = w1r * o1i - w1i * o1r; 4007 in[iidx1] = w1r * o1r + w1i * o1i; 4008 } 4009 } 4010 } 4011 } 4012 } 4013 4014 private void cftfsub(int n, float[] a, int offa, int[] ip, int nw, float[] w) { 4015 if (n > 8) { 4016 if (n > 32) { 4017 cftf1st(n, a, offa, w, nw - (n >> 2)); 4018 if ((ConcurrencyUtils.getNumberOfThreads() > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 4019 cftrec4_th(n, a, offa, nw, w); 4020 } else if (n > 512) { 4021 cftrec4(n, a, offa, nw, w); 4022 } else if (n > 128) { 4023 cftleaf(n, 1, a, offa, nw, w); 4024 } else { 4025 cftfx41(n, a, offa, nw, w); 4026 } 4027 bitrv2(n, ip, a, offa); 4028 } else if (n == 32) { 4029 cftf161(a, offa, w, nw - 8); 4030 bitrv216(a, offa); 4031 } else { 4032 cftf081(a, offa, w, 0); 4033 bitrv208(a, offa); 4034 } 4035 } else if (n == 8) { 4036 cftf040(a, offa); 4037 } else if (n == 4) { 4038 cftxb020(a, offa); 4039 } 4040 } 4041 4042 private void cftbsub(int n, float[] a, int offa, int[] ip, int nw, float[] w) { 4043 if (n > 8) { 4044 if (n > 32) { 4045 cftb1st(n, a, offa, w, nw - (n >> 2)); 4046 if ((ConcurrencyUtils.getNumberOfThreads() > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 4047 cftrec4_th(n, a, offa, nw, w); 4048 } else if (n > 512) { 4049 cftrec4(n, a, offa, nw, w); 4050 } else if (n > 128) { 4051 cftleaf(n, 1, a, offa, nw, w); 4052 } else { 4053 cftfx41(n, a, offa, nw, w); 4054 } 4055 bitrv2conj(n, ip, a, offa); 4056 } else if (n == 32) { 4057 cftf161(a, offa, w, nw - 8); 4058 bitrv216neg(a, offa); 4059 } else { 4060 cftf081(a, offa, w, 0); 4061 bitrv208neg(a, offa); 4062 } 4063 } else if (n == 8) { 4064 cftb040(a, offa); 4065 } else if (n == 4) { 4066 cftxb020(a, offa); 4067 } 4068 } 4069 4070 private void bitrv2(int n, int[] ip, float[] a, int offa) { 4071 int j1, k1, l, m, nh, nm; 4072 float xr, xi, yr, yi; 4073 int idx0, idx1, idx2; 4074 4075 m = 1; 4076 for (l = n >> 2; l > 8; l >>= 2) { 4077 m <<= 1; 4078 } 4079 nh = n >> 1; 4080 nm = 4 * m; 4081 if (l == 8) { 4082 for (int k = 0; k < m; k++) { 4083 idx0 = 4 * k; 4084 for (int j = 0; j < k; j++) { 4085 j1 = 4 * j + 2 * ip[m + k]; 4086 k1 = idx0 + 2 * ip[m + j]; 4087 idx1 = offa + j1; 4088 idx2 = offa + k1; 4089 xr = a[idx1]; 4090 xi = a[idx1 + 1]; 4091 yr = a[idx2]; 4092 yi = a[idx2 + 1]; 4093 a[idx1] = yr; 4094 a[idx1 + 1] = yi; 4095 a[idx2] = xr; 4096 a[idx2 + 1] = xi; 4097 j1 += nm; 4098 k1 += 2 * nm; 4099 idx1 = offa + j1; 4100 idx2 = offa + k1; 4101 xr = a[idx1]; 4102 xi = a[idx1 + 1]; 4103 yr = a[idx2]; 4104 yi = a[idx2 + 1]; 4105 a[idx1] = yr; 4106 a[idx1 + 1] = yi; 4107 a[idx2] = xr; 4108 a[idx2 + 1] = xi; 4109 j1 += nm; 4110 k1 -= nm; 4111 idx1 = offa + j1; 4112 idx2 = offa + k1; 4113 xr = a[idx1]; 4114 xi = a[idx1 + 1]; 4115 yr = a[idx2]; 4116 yi = a[idx2 + 1]; 4117 a[idx1] = yr; 4118 a[idx1 + 1] = yi; 4119 a[idx2] = xr; 4120 a[idx2 + 1] = xi; 4121 j1 += nm; 4122 k1 += 2 * nm; 4123 idx1 = offa + j1; 4124 idx2 = offa + k1; 4125 xr = a[idx1]; 4126 xi = a[idx1 + 1]; 4127 yr = a[idx2]; 4128 yi = a[idx2 + 1]; 4129 a[idx1] = yr; 4130 a[idx1 + 1] = yi; 4131 a[idx2] = xr; 4132 a[idx2 + 1] = xi; 4133 j1 += nh; 4134 k1 += 2; 4135 idx1 = offa + j1; 4136 idx2 = offa + k1; 4137 xr = a[idx1]; 4138 xi = a[idx1 + 1]; 4139 yr = a[idx2]; 4140 yi = a[idx2 + 1]; 4141 a[idx1] = yr; 4142 a[idx1 + 1] = yi; 4143 a[idx2] = xr; 4144 a[idx2 + 1] = xi; 4145 j1 -= nm; 4146 k1 -= 2 * nm; 4147 idx1 = offa + j1; 4148 idx2 = offa + k1; 4149 xr = a[idx1]; 4150 xi = a[idx1 + 1]; 4151 yr = a[idx2]; 4152 yi = a[idx2 + 1]; 4153 a[idx1] = yr; 4154 a[idx1 + 1] = yi; 4155 a[idx2] = xr; 4156 a[idx2 + 1] = xi; 4157 j1 -= nm; 4158 k1 += nm; 4159 idx1 = offa + j1; 4160 idx2 = offa + k1; 4161 xr = a[idx1]; 4162 xi = a[idx1 + 1]; 4163 yr = a[idx2]; 4164 yi = a[idx2 + 1]; 4165 a[idx1] = yr; 4166 a[idx1 + 1] = yi; 4167 a[idx2] = xr; 4168 a[idx2 + 1] = xi; 4169 j1 -= nm; 4170 k1 -= 2 * nm; 4171 idx1 = offa + j1; 4172 idx2 = offa + k1; 4173 xr = a[idx1]; 4174 xi = a[idx1 + 1]; 4175 yr = a[idx2]; 4176 yi = a[idx2 + 1]; 4177 a[idx1] = yr; 4178 a[idx1 + 1] = yi; 4179 a[idx2] = xr; 4180 a[idx2 + 1] = xi; 4181 j1 += 2; 4182 k1 += nh; 4183 idx1 = offa + j1; 4184 idx2 = offa + k1; 4185 xr = a[idx1]; 4186 xi = a[idx1 + 1]; 4187 yr = a[idx2]; 4188 yi = a[idx2 + 1]; 4189 a[idx1] = yr; 4190 a[idx1 + 1] = yi; 4191 a[idx2] = xr; 4192 a[idx2 + 1] = xi; 4193 j1 += nm; 4194 k1 += 2 * nm; 4195 idx1 = offa + j1; 4196 idx2 = offa + k1; 4197 xr = a[idx1]; 4198 xi = a[idx1 + 1]; 4199 yr = a[idx2]; 4200 yi = a[idx2 + 1]; 4201 a[idx1] = yr; 4202 a[idx1 + 1] = yi; 4203 a[idx2] = xr; 4204 a[idx2 + 1] = xi; 4205 j1 += nm; 4206 k1 -= nm; 4207 idx1 = offa + j1; 4208 idx2 = offa + k1; 4209 xr = a[idx1]; 4210 xi = a[idx1 + 1]; 4211 yr = a[idx2]; 4212 yi = a[idx2 + 1]; 4213 a[idx1] = yr; 4214 a[idx1 + 1] = yi; 4215 a[idx2] = xr; 4216 a[idx2 + 1] = xi; 4217 j1 += nm; 4218 k1 += 2 * nm; 4219 idx1 = offa + j1; 4220 idx2 = offa + k1; 4221 xr = a[idx1]; 4222 xi = a[idx1 + 1]; 4223 yr = a[idx2]; 4224 yi = a[idx2 + 1]; 4225 a[idx1] = yr; 4226 a[idx1 + 1] = yi; 4227 a[idx2] = xr; 4228 a[idx2 + 1] = xi; 4229 j1 -= nh; 4230 k1 -= 2; 4231 idx1 = offa + j1; 4232 idx2 = offa + k1; 4233 xr = a[idx1]; 4234 xi = a[idx1 + 1]; 4235 yr = a[idx2]; 4236 yi = a[idx2 + 1]; 4237 a[idx1] = yr; 4238 a[idx1 + 1] = yi; 4239 a[idx2] = xr; 4240 a[idx2 + 1] = xi; 4241 j1 -= nm; 4242 k1 -= 2 * nm; 4243 idx1 = offa + j1; 4244 idx2 = offa + k1; 4245 xr = a[idx1]; 4246 xi = a[idx1 + 1]; 4247 yr = a[idx2]; 4248 yi = a[idx2 + 1]; 4249 a[idx1] = yr; 4250 a[idx1 + 1] = yi; 4251 a[idx2] = xr; 4252 a[idx2 + 1] = xi; 4253 j1 -= nm; 4254 k1 += nm; 4255 idx1 = offa + j1; 4256 idx2 = offa + k1; 4257 xr = a[idx1]; 4258 xi = a[idx1 + 1]; 4259 yr = a[idx2]; 4260 yi = a[idx2 + 1]; 4261 a[idx1] = yr; 4262 a[idx1 + 1] = yi; 4263 a[idx2] = xr; 4264 a[idx2 + 1] = xi; 4265 j1 -= nm; 4266 k1 -= 2 * nm; 4267 idx1 = offa + j1; 4268 idx2 = offa + k1; 4269 xr = a[idx1]; 4270 xi = a[idx1 + 1]; 4271 yr = a[idx2]; 4272 yi = a[idx2 + 1]; 4273 a[idx1] = yr; 4274 a[idx1 + 1] = yi; 4275 a[idx2] = xr; 4276 a[idx2 + 1] = xi; 4277 } 4278 k1 = idx0 + 2 * ip[m + k]; 4279 j1 = k1 + 2; 4280 k1 += nh; 4281 idx1 = offa + j1; 4282 idx2 = offa + k1; 4283 xr = a[idx1]; 4284 xi = a[idx1 + 1]; 4285 yr = a[idx2]; 4286 yi = a[idx2 + 1]; 4287 a[idx1] = yr; 4288 a[idx1 + 1] = yi; 4289 a[idx2] = xr; 4290 a[idx2 + 1] = xi; 4291 j1 += nm; 4292 k1 += 2 * nm; 4293 idx1 = offa + j1; 4294 idx2 = offa + k1; 4295 xr = a[idx1]; 4296 xi = a[idx1 + 1]; 4297 yr = a[idx2]; 4298 yi = a[idx2 + 1]; 4299 a[idx1] = yr; 4300 a[idx1 + 1] = yi; 4301 a[idx2] = xr; 4302 a[idx2 + 1] = xi; 4303 j1 += nm; 4304 k1 -= nm; 4305 idx1 = offa + j1; 4306 idx2 = offa + k1; 4307 xr = a[idx1]; 4308 xi = a[idx1 + 1]; 4309 yr = a[idx2]; 4310 yi = a[idx2 + 1]; 4311 a[idx1] = yr; 4312 a[idx1 + 1] = yi; 4313 a[idx2] = xr; 4314 a[idx2 + 1] = xi; 4315 j1 -= 2; 4316 k1 -= nh; 4317 idx1 = offa + j1; 4318 idx2 = offa + k1; 4319 xr = a[idx1]; 4320 xi = a[idx1 + 1]; 4321 yr = a[idx2]; 4322 yi = a[idx2 + 1]; 4323 a[idx1] = yr; 4324 a[idx1 + 1] = yi; 4325 a[idx2] = xr; 4326 a[idx2 + 1] = xi; 4327 j1 += nh + 2; 4328 k1 += nh + 2; 4329 idx1 = offa + j1; 4330 idx2 = offa + k1; 4331 xr = a[idx1]; 4332 xi = a[idx1 + 1]; 4333 yr = a[idx2]; 4334 yi = a[idx2 + 1]; 4335 a[idx1] = yr; 4336 a[idx1 + 1] = yi; 4337 a[idx2] = xr; 4338 a[idx2 + 1] = xi; 4339 j1 -= nh - nm; 4340 k1 += 2 * nm - 2; 4341 idx1 = offa + j1; 4342 idx2 = offa + k1; 4343 xr = a[idx1]; 4344 xi = a[idx1 + 1]; 4345 yr = a[idx2]; 4346 yi = a[idx2 + 1]; 4347 a[idx1] = yr; 4348 a[idx1 + 1] = yi; 4349 a[idx2] = xr; 4350 a[idx2 + 1] = xi; 4351 } 4352 } else { 4353 for (int k = 0; k < m; k++) { 4354 idx0 = 4 * k; 4355 for (int j = 0; j < k; j++) { 4356 j1 = 4 * j + ip[m + k]; 4357 k1 = idx0 + ip[m + j]; 4358 idx1 = offa + j1; 4359 idx2 = offa + k1; 4360 xr = a[idx1]; 4361 xi = a[idx1 + 1]; 4362 yr = a[idx2]; 4363 yi = a[idx2 + 1]; 4364 a[idx1] = yr; 4365 a[idx1 + 1] = yi; 4366 a[idx2] = xr; 4367 a[idx2 + 1] = xi; 4368 j1 += nm; 4369 k1 += nm; 4370 idx1 = offa + j1; 4371 idx2 = offa + k1; 4372 xr = a[idx1]; 4373 xi = a[idx1 + 1]; 4374 yr = a[idx2]; 4375 yi = a[idx2 + 1]; 4376 a[idx1] = yr; 4377 a[idx1 + 1] = yi; 4378 a[idx2] = xr; 4379 a[idx2 + 1] = xi; 4380 j1 += nh; 4381 k1 += 2; 4382 idx1 = offa + j1; 4383 idx2 = offa + k1; 4384 xr = a[idx1]; 4385 xi = a[idx1 + 1]; 4386 yr = a[idx2]; 4387 yi = a[idx2 + 1]; 4388 a[idx1] = yr; 4389 a[idx1 + 1] = yi; 4390 a[idx2] = xr; 4391 a[idx2 + 1] = xi; 4392 j1 -= nm; 4393 k1 -= nm; 4394 idx1 = offa + j1; 4395 idx2 = offa + k1; 4396 xr = a[idx1]; 4397 xi = a[idx1 + 1]; 4398 yr = a[idx2]; 4399 yi = a[idx2 + 1]; 4400 a[idx1] = yr; 4401 a[idx1 + 1] = yi; 4402 a[idx2] = xr; 4403 a[idx2 + 1] = xi; 4404 j1 += 2; 4405 k1 += nh; 4406 idx1 = offa + j1; 4407 idx2 = offa + k1; 4408 xr = a[idx1]; 4409 xi = a[idx1 + 1]; 4410 yr = a[idx2]; 4411 yi = a[idx2 + 1]; 4412 a[idx1] = yr; 4413 a[idx1 + 1] = yi; 4414 a[idx2] = xr; 4415 a[idx2 + 1] = xi; 4416 j1 += nm; 4417 k1 += nm; 4418 idx1 = offa + j1; 4419 idx2 = offa + k1; 4420 xr = a[idx1]; 4421 xi = a[idx1 + 1]; 4422 yr = a[idx2]; 4423 yi = a[idx2 + 1]; 4424 a[idx1] = yr; 4425 a[idx1 + 1] = yi; 4426 a[idx2] = xr; 4427 a[idx2 + 1] = xi; 4428 j1 -= nh; 4429 k1 -= 2; 4430 idx1 = offa + j1; 4431 idx2 = offa + k1; 4432 xr = a[idx1]; 4433 xi = a[idx1 + 1]; 4434 yr = a[idx2]; 4435 yi = a[idx2 + 1]; 4436 a[idx1] = yr; 4437 a[idx1 + 1] = yi; 4438 a[idx2] = xr; 4439 a[idx2 + 1] = xi; 4440 j1 -= nm; 4441 k1 -= nm; 4442 idx1 = offa + j1; 4443 idx2 = offa + k1; 4444 xr = a[idx1]; 4445 xi = a[idx1 + 1]; 4446 yr = a[idx2]; 4447 yi = a[idx2 + 1]; 4448 a[idx1] = yr; 4449 a[idx1 + 1] = yi; 4450 a[idx2] = xr; 4451 a[idx2 + 1] = xi; 4452 } 4453 k1 = idx0 + ip[m + k]; 4454 j1 = k1 + 2; 4455 k1 += nh; 4456 idx1 = offa + j1; 4457 idx2 = offa + k1; 4458 xr = a[idx1]; 4459 xi = a[idx1 + 1]; 4460 yr = a[idx2]; 4461 yi = a[idx2 + 1]; 4462 a[idx1] = yr; 4463 a[idx1 + 1] = yi; 4464 a[idx2] = xr; 4465 a[idx2 + 1] = xi; 4466 j1 += nm; 4467 k1 += nm; 4468 idx1 = offa + j1; 4469 idx2 = offa + k1; 4470 xr = a[idx1]; 4471 xi = a[idx1 + 1]; 4472 yr = a[idx2]; 4473 yi = a[idx2 + 1]; 4474 a[idx1] = yr; 4475 a[idx1 + 1] = yi; 4476 a[idx2] = xr; 4477 a[idx2 + 1] = xi; 4478 } 4479 } 4480 } 4481 4482 private void bitrv2conj(int n, int[] ip, float[] a, int offa) { 4483 int j1, k1, l, m, nh, nm; 4484 float xr, xi, yr, yi; 4485 int idx0, idx1, idx2; 4486 4487 m = 1; 4488 for (l = n >> 2; l > 8; l >>= 2) { 4489 m <<= 1; 4490 } 4491 nh = n >> 1; 4492 nm = 4 * m; 4493 if (l == 8) { 4494 for (int k = 0; k < m; k++) { 4495 idx0 = 4 * k; 4496 for (int j = 0; j < k; j++) { 4497 j1 = 4 * j + 2 * ip[m + k]; 4498 k1 = idx0 + 2 * ip[m + j]; 4499 idx1 = offa + j1; 4500 idx2 = offa + k1; 4501 xr = a[idx1]; 4502 xi = -a[idx1 + 1]; 4503 yr = a[idx2]; 4504 yi = -a[idx2 + 1]; 4505 a[idx1] = yr; 4506 a[idx1 + 1] = yi; 4507 a[idx2] = xr; 4508 a[idx2 + 1] = xi; 4509 j1 += nm; 4510 k1 += 2 * nm; 4511 idx1 = offa + j1; 4512 idx2 = offa + k1; 4513 xr = a[idx1]; 4514 xi = -a[idx1 + 1]; 4515 yr = a[idx2]; 4516 yi = -a[idx2 + 1]; 4517 a[idx1] = yr; 4518 a[idx1 + 1] = yi; 4519 a[idx2] = xr; 4520 a[idx2 + 1] = xi; 4521 j1 += nm; 4522 k1 -= nm; 4523 idx1 = offa + j1; 4524 idx2 = offa + k1; 4525 xr = a[idx1]; 4526 xi = -a[idx1 + 1]; 4527 yr = a[idx2]; 4528 yi = -a[idx2 + 1]; 4529 a[idx1] = yr; 4530 a[idx1 + 1] = yi; 4531 a[idx2] = xr; 4532 a[idx2 + 1] = xi; 4533 j1 += nm; 4534 k1 += 2 * nm; 4535 idx1 = offa + j1; 4536 idx2 = offa + k1; 4537 xr = a[idx1]; 4538 xi = -a[idx1 + 1]; 4539 yr = a[idx2]; 4540 yi = -a[idx2 + 1]; 4541 a[idx1] = yr; 4542 a[idx1 + 1] = yi; 4543 a[idx2] = xr; 4544 a[idx2 + 1] = xi; 4545 j1 += nh; 4546 k1 += 2; 4547 idx1 = offa + j1; 4548 idx2 = offa + k1; 4549 xr = a[idx1]; 4550 xi = -a[idx1 + 1]; 4551 yr = a[idx2]; 4552 yi = -a[idx2 + 1]; 4553 a[idx1] = yr; 4554 a[idx1 + 1] = yi; 4555 a[idx2] = xr; 4556 a[idx2 + 1] = xi; 4557 j1 -= nm; 4558 k1 -= 2 * nm; 4559 idx1 = offa + j1; 4560 idx2 = offa + k1; 4561 xr = a[idx1]; 4562 xi = -a[idx1 + 1]; 4563 yr = a[idx2]; 4564 yi = -a[idx2 + 1]; 4565 a[idx1] = yr; 4566 a[idx1 + 1] = yi; 4567 a[idx2] = xr; 4568 a[idx2 + 1] = xi; 4569 j1 -= nm; 4570 k1 += nm; 4571 idx1 = offa + j1; 4572 idx2 = offa + k1; 4573 xr = a[idx1]; 4574 xi = -a[idx1 + 1]; 4575 yr = a[idx2]; 4576 yi = -a[idx2 + 1]; 4577 a[idx1] = yr; 4578 a[idx1 + 1] = yi; 4579 a[idx2] = xr; 4580 a[idx2 + 1] = xi; 4581 j1 -= nm; 4582 k1 -= 2 * nm; 4583 idx1 = offa + j1; 4584 idx2 = offa + k1; 4585 xr = a[idx1]; 4586 xi = -a[idx1 + 1]; 4587 yr = a[idx2]; 4588 yi = -a[idx2 + 1]; 4589 a[idx1] = yr; 4590 a[idx1 + 1] = yi; 4591 a[idx2] = xr; 4592 a[idx2 + 1] = xi; 4593 j1 += 2; 4594 k1 += nh; 4595 idx1 = offa + j1; 4596 idx2 = offa + k1; 4597 xr = a[idx1]; 4598 xi = -a[idx1 + 1]; 4599 yr = a[idx2]; 4600 yi = -a[idx2 + 1]; 4601 a[idx1] = yr; 4602 a[idx1 + 1] = yi; 4603 a[idx2] = xr; 4604 a[idx2 + 1] = xi; 4605 j1 += nm; 4606 k1 += 2 * nm; 4607 idx1 = offa + j1; 4608 idx2 = offa + k1; 4609 xr = a[idx1]; 4610 xi = -a[idx1 + 1]; 4611 yr = a[idx2]; 4612 yi = -a[idx2 + 1]; 4613 a[idx1] = yr; 4614 a[idx1 + 1] = yi; 4615 a[idx2] = xr; 4616 a[idx2 + 1] = xi; 4617 j1 += nm; 4618 k1 -= nm; 4619 idx1 = offa + j1; 4620 idx2 = offa + k1; 4621 xr = a[idx1]; 4622 xi = -a[idx1 + 1]; 4623 yr = a[idx2]; 4624 yi = -a[idx2 + 1]; 4625 a[idx1] = yr; 4626 a[idx1 + 1] = yi; 4627 a[idx2] = xr; 4628 a[idx2 + 1] = xi; 4629 j1 += nm; 4630 k1 += 2 * nm; 4631 idx1 = offa + j1; 4632 idx2 = offa + k1; 4633 xr = a[idx1]; 4634 xi = -a[idx1 + 1]; 4635 yr = a[idx2]; 4636 yi = -a[idx2 + 1]; 4637 a[idx1] = yr; 4638 a[idx1 + 1] = yi; 4639 a[idx2] = xr; 4640 a[idx2 + 1] = xi; 4641 j1 -= nh; 4642 k1 -= 2; 4643 idx1 = offa + j1; 4644 idx2 = offa + k1; 4645 xr = a[idx1]; 4646 xi = -a[idx1 + 1]; 4647 yr = a[idx2]; 4648 yi = -a[idx2 + 1]; 4649 a[idx1] = yr; 4650 a[idx1 + 1] = yi; 4651 a[idx2] = xr; 4652 a[idx2 + 1] = xi; 4653 j1 -= nm; 4654 k1 -= 2 * nm; 4655 idx1 = offa + j1; 4656 idx2 = offa + k1; 4657 xr = a[idx1]; 4658 xi = -a[idx1 + 1]; 4659 yr = a[idx2]; 4660 yi = -a[idx2 + 1]; 4661 a[idx1] = yr; 4662 a[idx1 + 1] = yi; 4663 a[idx2] = xr; 4664 a[idx2 + 1] = xi; 4665 j1 -= nm; 4666 k1 += nm; 4667 idx1 = offa + j1; 4668 idx2 = offa + k1; 4669 xr = a[idx1]; 4670 xi = -a[idx1 + 1]; 4671 yr = a[idx2]; 4672 yi = -a[idx2 + 1]; 4673 a[idx1] = yr; 4674 a[idx1 + 1] = yi; 4675 a[idx2] = xr; 4676 a[idx2 + 1] = xi; 4677 j1 -= nm; 4678 k1 -= 2 * nm; 4679 idx1 = offa + j1; 4680 idx2 = offa + k1; 4681 xr = a[idx1]; 4682 xi = -a[idx1 + 1]; 4683 yr = a[idx2]; 4684 yi = -a[idx2 + 1]; 4685 a[idx1] = yr; 4686 a[idx1 + 1] = yi; 4687 a[idx2] = xr; 4688 a[idx2 + 1] = xi; 4689 } 4690 k1 = idx0 + 2 * ip[m + k]; 4691 j1 = k1 + 2; 4692 k1 += nh; 4693 idx1 = offa + j1; 4694 idx2 = offa + k1; 4695 a[idx1 - 1] = -a[idx1 - 1]; 4696 xr = a[idx1]; 4697 xi = -a[idx1 + 1]; 4698 yr = a[idx2]; 4699 yi = -a[idx2 + 1]; 4700 a[idx1] = yr; 4701 a[idx1 + 1] = yi; 4702 a[idx2] = xr; 4703 a[idx2 + 1] = xi; 4704 a[idx2 + 3] = -a[idx2 + 3]; 4705 j1 += nm; 4706 k1 += 2 * nm; 4707 idx1 = offa + j1; 4708 idx2 = offa + k1; 4709 xr = a[idx1]; 4710 xi = -a[idx1 + 1]; 4711 yr = a[idx2]; 4712 yi = -a[idx2 + 1]; 4713 a[idx1] = yr; 4714 a[idx1 + 1] = yi; 4715 a[idx2] = xr; 4716 a[idx2 + 1] = xi; 4717 j1 += nm; 4718 k1 -= nm; 4719 idx1 = offa + j1; 4720 idx2 = offa + k1; 4721 xr = a[idx1]; 4722 xi = -a[idx1 + 1]; 4723 yr = a[idx2]; 4724 yi = -a[idx2 + 1]; 4725 a[idx1] = yr; 4726 a[idx1 + 1] = yi; 4727 a[idx2] = xr; 4728 a[idx2 + 1] = xi; 4729 j1 -= 2; 4730 k1 -= nh; 4731 idx1 = offa + j1; 4732 idx2 = offa + k1; 4733 xr = a[idx1]; 4734 xi = -a[idx1 + 1]; 4735 yr = a[idx2]; 4736 yi = -a[idx2 + 1]; 4737 a[idx1] = yr; 4738 a[idx1 + 1] = yi; 4739 a[idx2] = xr; 4740 a[idx2 + 1] = xi; 4741 j1 += nh + 2; 4742 k1 += nh + 2; 4743 idx1 = offa + j1; 4744 idx2 = offa + k1; 4745 xr = a[idx1]; 4746 xi = -a[idx1 + 1]; 4747 yr = a[idx2]; 4748 yi = -a[idx2 + 1]; 4749 a[idx1] = yr; 4750 a[idx1 + 1] = yi; 4751 a[idx2] = xr; 4752 a[idx2 + 1] = xi; 4753 j1 -= nh - nm; 4754 k1 += 2 * nm - 2; 4755 idx1 = offa + j1; 4756 idx2 = offa + k1; 4757 a[idx1 - 1] = -a[idx1 - 1]; 4758 xr = a[idx1]; 4759 xi = -a[idx1 + 1]; 4760 yr = a[idx2]; 4761 yi = -a[idx2 + 1]; 4762 a[idx1] = yr; 4763 a[idx1 + 1] = yi; 4764 a[idx2] = xr; 4765 a[idx2 + 1] = xi; 4766 a[idx2 + 3] = -a[idx2 + 3]; 4767 } 4768 } else { 4769 for (int k = 0; k < m; k++) { 4770 idx0 = 4 * k; 4771 for (int j = 0; j < k; j++) { 4772 j1 = 4 * j + ip[m + k]; 4773 k1 = idx0 + ip[m + j]; 4774 idx1 = offa + j1; 4775 idx2 = offa + k1; 4776 xr = a[idx1]; 4777 xi = -a[idx1 + 1]; 4778 yr = a[idx2]; 4779 yi = -a[idx2 + 1]; 4780 a[idx1] = yr; 4781 a[idx1 + 1] = yi; 4782 a[idx2] = xr; 4783 a[idx2 + 1] = xi; 4784 j1 += nm; 4785 k1 += nm; 4786 idx1 = offa + j1; 4787 idx2 = offa + k1; 4788 xr = a[idx1]; 4789 xi = -a[idx1 + 1]; 4790 yr = a[idx2]; 4791 yi = -a[idx2 + 1]; 4792 a[idx1] = yr; 4793 a[idx1 + 1] = yi; 4794 a[idx2] = xr; 4795 a[idx2 + 1] = xi; 4796 j1 += nh; 4797 k1 += 2; 4798 idx1 = offa + j1; 4799 idx2 = offa + k1; 4800 xr = a[idx1]; 4801 xi = -a[idx1 + 1]; 4802 yr = a[idx2]; 4803 yi = -a[idx2 + 1]; 4804 a[idx1] = yr; 4805 a[idx1 + 1] = yi; 4806 a[idx2] = xr; 4807 a[idx2 + 1] = xi; 4808 j1 -= nm; 4809 k1 -= nm; 4810 idx1 = offa + j1; 4811 idx2 = offa + k1; 4812 xr = a[idx1]; 4813 xi = -a[idx1 + 1]; 4814 yr = a[idx2]; 4815 yi = -a[idx2 + 1]; 4816 a[idx1] = yr; 4817 a[idx1 + 1] = yi; 4818 a[idx2] = xr; 4819 a[idx2 + 1] = xi; 4820 j1 += 2; 4821 k1 += nh; 4822 idx1 = offa + j1; 4823 idx2 = offa + k1; 4824 xr = a[idx1]; 4825 xi = -a[idx1 + 1]; 4826 yr = a[idx2]; 4827 yi = -a[idx2 + 1]; 4828 a[idx1] = yr; 4829 a[idx1 + 1] = yi; 4830 a[idx2] = xr; 4831 a[idx2 + 1] = xi; 4832 j1 += nm; 4833 k1 += nm; 4834 idx1 = offa + j1; 4835 idx2 = offa + k1; 4836 xr = a[idx1]; 4837 xi = -a[idx1 + 1]; 4838 yr = a[idx2]; 4839 yi = -a[idx2 + 1]; 4840 a[idx1] = yr; 4841 a[idx1 + 1] = yi; 4842 a[idx2] = xr; 4843 a[idx2 + 1] = xi; 4844 j1 -= nh; 4845 k1 -= 2; 4846 idx1 = offa + j1; 4847 idx2 = offa + k1; 4848 xr = a[idx1]; 4849 xi = -a[idx1 + 1]; 4850 yr = a[idx2]; 4851 yi = -a[idx2 + 1]; 4852 a[idx1] = yr; 4853 a[idx1 + 1] = yi; 4854 a[idx2] = xr; 4855 a[idx2 + 1] = xi; 4856 j1 -= nm; 4857 k1 -= nm; 4858 idx1 = offa + j1; 4859 idx2 = offa + k1; 4860 xr = a[idx1]; 4861 xi = -a[idx1 + 1]; 4862 yr = a[idx2]; 4863 yi = -a[idx2 + 1]; 4864 a[idx1] = yr; 4865 a[idx1 + 1] = yi; 4866 a[idx2] = xr; 4867 a[idx2 + 1] = xi; 4868 } 4869 k1 = idx0 + ip[m + k]; 4870 j1 = k1 + 2; 4871 k1 += nh; 4872 idx1 = offa + j1; 4873 idx2 = offa + k1; 4874 a[idx1 - 1] = -a[idx1 - 1]; 4875 xr = a[idx1]; 4876 xi = -a[idx1 + 1]; 4877 yr = a[idx2]; 4878 yi = -a[idx2 + 1]; 4879 a[idx1] = yr; 4880 a[idx1 + 1] = yi; 4881 a[idx2] = xr; 4882 a[idx2 + 1] = xi; 4883 a[idx2 + 3] = -a[idx2 + 3]; 4884 j1 += nm; 4885 k1 += nm; 4886 idx1 = offa + j1; 4887 idx2 = offa + k1; 4888 a[idx1 - 1] = -a[idx1 - 1]; 4889 xr = a[idx1]; 4890 xi = -a[idx1 + 1]; 4891 yr = a[idx2]; 4892 yi = -a[idx2 + 1]; 4893 a[idx1] = yr; 4894 a[idx1 + 1] = yi; 4895 a[idx2] = xr; 4896 a[idx2 + 1] = xi; 4897 a[idx2 + 3] = -a[idx2 + 3]; 4898 } 4899 } 4900 } 4901 4902 private void bitrv216(float[] a, int offa) { 4903 float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; 4904 4905 x1r = a[offa + 2]; 4906 x1i = a[offa + 3]; 4907 x2r = a[offa + 4]; 4908 x2i = a[offa + 5]; 4909 x3r = a[offa + 6]; 4910 x3i = a[offa + 7]; 4911 x4r = a[offa + 8]; 4912 x4i = a[offa + 9]; 4913 x5r = a[offa + 10]; 4914 x5i = a[offa + 11]; 4915 x7r = a[offa + 14]; 4916 x7i = a[offa + 15]; 4917 x8r = a[offa + 16]; 4918 x8i = a[offa + 17]; 4919 x10r = a[offa + 20]; 4920 x10i = a[offa + 21]; 4921 x11r = a[offa + 22]; 4922 x11i = a[offa + 23]; 4923 x12r = a[offa + 24]; 4924 x12i = a[offa + 25]; 4925 x13r = a[offa + 26]; 4926 x13i = a[offa + 27]; 4927 x14r = a[offa + 28]; 4928 x14i = a[offa + 29]; 4929 a[offa + 2] = x8r; 4930 a[offa + 3] = x8i; 4931 a[offa + 4] = x4r; 4932 a[offa + 5] = x4i; 4933 a[offa + 6] = x12r; 4934 a[offa + 7] = x12i; 4935 a[offa + 8] = x2r; 4936 a[offa + 9] = x2i; 4937 a[offa + 10] = x10r; 4938 a[offa + 11] = x10i; 4939 a[offa + 14] = x14r; 4940 a[offa + 15] = x14i; 4941 a[offa + 16] = x1r; 4942 a[offa + 17] = x1i; 4943 a[offa + 20] = x5r; 4944 a[offa + 21] = x5i; 4945 a[offa + 22] = x13r; 4946 a[offa + 23] = x13i; 4947 a[offa + 24] = x3r; 4948 a[offa + 25] = x3i; 4949 a[offa + 26] = x11r; 4950 a[offa + 27] = x11i; 4951 a[offa + 28] = x7r; 4952 a[offa + 29] = x7i; 4953 } 4954 4955 private void bitrv216neg(float[] a, int offa) { 4956 float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i; 4957 4958 x1r = a[offa + 2]; 4959 x1i = a[offa + 3]; 4960 x2r = a[offa + 4]; 4961 x2i = a[offa + 5]; 4962 x3r = a[offa + 6]; 4963 x3i = a[offa + 7]; 4964 x4r = a[offa + 8]; 4965 x4i = a[offa + 9]; 4966 x5r = a[offa + 10]; 4967 x5i = a[offa + 11]; 4968 x6r = a[offa + 12]; 4969 x6i = a[offa + 13]; 4970 x7r = a[offa + 14]; 4971 x7i = a[offa + 15]; 4972 x8r = a[offa + 16]; 4973 x8i = a[offa + 17]; 4974 x9r = a[offa + 18]; 4975 x9i = a[offa + 19]; 4976 x10r = a[offa + 20]; 4977 x10i = a[offa + 21]; 4978 x11r = a[offa + 22]; 4979 x11i = a[offa + 23]; 4980 x12r = a[offa + 24]; 4981 x12i = a[offa + 25]; 4982 x13r = a[offa + 26]; 4983 x13i = a[offa + 27]; 4984 x14r = a[offa + 28]; 4985 x14i = a[offa + 29]; 4986 x15r = a[offa + 30]; 4987 x15i = a[offa + 31]; 4988 a[offa + 2] = x15r; 4989 a[offa + 3] = x15i; 4990 a[offa + 4] = x7r; 4991 a[offa + 5] = x7i; 4992 a[offa + 6] = x11r; 4993 a[offa + 7] = x11i; 4994 a[offa + 8] = x3r; 4995 a[offa + 9] = x3i; 4996 a[offa + 10] = x13r; 4997 a[offa + 11] = x13i; 4998 a[offa + 12] = x5r; 4999 a[offa + 13] = x5i; 5000 a[offa + 14] = x9r; 5001 a[offa + 15] = x9i; 5002 a[offa + 16] = x1r; 5003 a[offa + 17] = x1i; 5004 a[offa + 18] = x14r; 5005 a[offa + 19] = x14i; 5006 a[offa + 20] = x6r; 5007 a[offa + 21] = x6i; 5008 a[offa + 22] = x10r; 5009 a[offa + 23] = x10i; 5010 a[offa + 24] = x2r; 5011 a[offa + 25] = x2i; 5012 a[offa + 26] = x12r; 5013 a[offa + 27] = x12i; 5014 a[offa + 28] = x4r; 5015 a[offa + 29] = x4i; 5016 a[offa + 30] = x8r; 5017 a[offa + 31] = x8i; 5018 } 5019 5020 private void bitrv208(float[] a, int offa) { 5021 float x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; 5022 5023 x1r = a[offa + 2]; 5024 x1i = a[offa + 3]; 5025 x3r = a[offa + 6]; 5026 x3i = a[offa + 7]; 5027 x4r = a[offa + 8]; 5028 x4i = a[offa + 9]; 5029 x6r = a[offa + 12]; 5030 x6i = a[offa + 13]; 5031 a[offa + 2] = x4r; 5032 a[offa + 3] = x4i; 5033 a[offa + 6] = x6r; 5034 a[offa + 7] = x6i; 5035 a[offa + 8] = x1r; 5036 a[offa + 9] = x1i; 5037 a[offa + 12] = x3r; 5038 a[offa + 13] = x3i; 5039 } 5040 5041 private void bitrv208neg(float[] a, int offa) { 5042 float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i; 5043 5044 x1r = a[offa + 2]; 5045 x1i = a[offa + 3]; 5046 x2r = a[offa + 4]; 5047 x2i = a[offa + 5]; 5048 x3r = a[offa + 6]; 5049 x3i = a[offa + 7]; 5050 x4r = a[offa + 8]; 5051 x4i = a[offa + 9]; 5052 x5r = a[offa + 10]; 5053 x5i = a[offa + 11]; 5054 x6r = a[offa + 12]; 5055 x6i = a[offa + 13]; 5056 x7r = a[offa + 14]; 5057 x7i = a[offa + 15]; 5058 a[offa + 2] = x7r; 5059 a[offa + 3] = x7i; 5060 a[offa + 4] = x3r; 5061 a[offa + 5] = x3i; 5062 a[offa + 6] = x5r; 5063 a[offa + 7] = x5i; 5064 a[offa + 8] = x1r; 5065 a[offa + 9] = x1i; 5066 a[offa + 10] = x6r; 5067 a[offa + 11] = x6i; 5068 a[offa + 12] = x2r; 5069 a[offa + 13] = x2i; 5070 a[offa + 14] = x4r; 5071 a[offa + 15] = x4i; 5072 } 5073 5074 private void cftf1st(int n, float[] a, int offa, float[] w, int startw) { 5075 int j0, j1, j2, j3, k, m, mh; 5076 float wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; 5077 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; 5078 int idx0, idx1, idx2, idx3, idx4, idx5; 5079 mh = n >> 3; 5080 m = 2 * mh; 5081 j1 = m; 5082 j2 = j1 + m; 5083 j3 = j2 + m; 5084 idx1 = offa + j1; 5085 idx2 = offa + j2; 5086 idx3 = offa + j3; 5087 x0r = a[offa] + a[idx2]; 5088 x0i = a[offa + 1] + a[idx2 + 1]; 5089 x1r = a[offa] - a[idx2]; 5090 x1i = a[offa + 1] - a[idx2 + 1]; 5091 x2r = a[idx1] + a[idx3]; 5092 x2i = a[idx1 + 1] + a[idx3 + 1]; 5093 x3r = a[idx1] - a[idx3]; 5094 x3i = a[idx1 + 1] - a[idx3 + 1]; 5095 a[offa] = x0r + x2r; 5096 a[offa + 1] = x0i + x2i; 5097 a[idx1] = x0r - x2r; 5098 a[idx1 + 1] = x0i - x2i; 5099 a[idx2] = x1r - x3i; 5100 a[idx2 + 1] = x1i + x3r; 5101 a[idx3] = x1r + x3i; 5102 a[idx3 + 1] = x1i - x3r; 5103 wn4r = w[startw + 1]; 5104 csc1 = w[startw + 2]; 5105 csc3 = w[startw + 3]; 5106 wd1r = 1; 5107 wd1i = 0; 5108 wd3r = 1; 5109 wd3i = 0; 5110 k = 0; 5111 for (int j = 2; j < mh - 2; j += 4) { 5112 k += 4; 5113 idx4 = startw + k; 5114 wk1r = csc1 * (wd1r + w[idx4]); 5115 wk1i = csc1 * (wd1i + w[idx4 + 1]); 5116 wk3r = csc3 * (wd3r + w[idx4 + 2]); 5117 wk3i = csc3 * (wd3i + w[idx4 + 3]); 5118 wd1r = w[idx4]; 5119 wd1i = w[idx4 + 1]; 5120 wd3r = w[idx4 + 2]; 5121 wd3i = w[idx4 + 3]; 5122 j1 = j + m; 5123 j2 = j1 + m; 5124 j3 = j2 + m; 5125 idx1 = offa + j1; 5126 idx2 = offa + j2; 5127 idx3 = offa + j3; 5128 idx5 = offa + j; 5129 x0r = a[idx5] + a[idx2]; 5130 x0i = a[idx5 + 1] + a[idx2 + 1]; 5131 x1r = a[idx5] - a[idx2]; 5132 x1i = a[idx5 + 1] - a[idx2 + 1]; 5133 y0r = a[idx5 + 2] + a[idx2 + 2]; 5134 y0i = a[idx5 + 3] + a[idx2 + 3]; 5135 y1r = a[idx5 + 2] - a[idx2 + 2]; 5136 y1i = a[idx5 + 3] - a[idx2 + 3]; 5137 x2r = a[idx1] + a[idx3]; 5138 x2i = a[idx1 + 1] + a[idx3 + 1]; 5139 x3r = a[idx1] - a[idx3]; 5140 x3i = a[idx1 + 1] - a[idx3 + 1]; 5141 y2r = a[idx1 + 2] + a[idx3 + 2]; 5142 y2i = a[idx1 + 3] + a[idx3 + 3]; 5143 y3r = a[idx1 + 2] - a[idx3 + 2]; 5144 y3i = a[idx1 + 3] - a[idx3 + 3]; 5145 a[idx5] = x0r + x2r; 5146 a[idx5 + 1] = x0i + x2i; 5147 a[idx5 + 2] = y0r + y2r; 5148 a[idx5 + 3] = y0i + y2i; 5149 a[idx1] = x0r - x2r; 5150 a[idx1 + 1] = x0i - x2i; 5151 a[idx1 + 2] = y0r - y2r; 5152 a[idx1 + 3] = y0i - y2i; 5153 x0r = x1r - x3i; 5154 x0i = x1i + x3r; 5155 a[idx2] = wk1r * x0r - wk1i * x0i; 5156 a[idx2 + 1] = wk1r * x0i + wk1i * x0r; 5157 x0r = y1r - y3i; 5158 x0i = y1i + y3r; 5159 a[idx2 + 2] = wd1r * x0r - wd1i * x0i; 5160 a[idx2 + 3] = wd1r * x0i + wd1i * x0r; 5161 x0r = x1r + x3i; 5162 x0i = x1i - x3r; 5163 a[idx3] = wk3r * x0r + wk3i * x0i; 5164 a[idx3 + 1] = wk3r * x0i - wk3i * x0r; 5165 x0r = y1r + y3i; 5166 x0i = y1i - y3r; 5167 a[idx3 + 2] = wd3r * x0r + wd3i * x0i; 5168 a[idx3 + 3] = wd3r * x0i - wd3i * x0r; 5169 j0 = m - j; 5170 j1 = j0 + m; 5171 j2 = j1 + m; 5172 j3 = j2 + m; 5173 idx0 = offa + j0; 5174 idx1 = offa + j1; 5175 idx2 = offa + j2; 5176 idx3 = offa + j3; 5177 x0r = a[idx0] + a[idx2]; 5178 x0i = a[idx0 + 1] + a[idx2 + 1]; 5179 x1r = a[idx0] - a[idx2]; 5180 x1i = a[idx0 + 1] - a[idx2 + 1]; 5181 y0r = a[idx0 - 2] + a[idx2 - 2]; 5182 y0i = a[idx0 - 1] + a[idx2 - 1]; 5183 y1r = a[idx0 - 2] - a[idx2 - 2]; 5184 y1i = a[idx0 - 1] - a[idx2 - 1]; 5185 x2r = a[idx1] + a[idx3]; 5186 x2i = a[idx1 + 1] + a[idx3 + 1]; 5187 x3r = a[idx1] - a[idx3]; 5188 x3i = a[idx1 + 1] - a[idx3 + 1]; 5189 y2r = a[idx1 - 2] + a[idx3 - 2]; 5190 y2i = a[idx1 - 1] + a[idx3 - 1]; 5191 y3r = a[idx1 - 2] - a[idx3 - 2]; 5192 y3i = a[idx1 - 1] - a[idx3 - 1]; 5193 a[idx0] = x0r + x2r; 5194 a[idx0 + 1] = x0i + x2i; 5195 a[idx0 - 2] = y0r + y2r; 5196 a[idx0 - 1] = y0i + y2i; 5197 a[idx1] = x0r - x2r; 5198 a[idx1 + 1] = x0i - x2i; 5199 a[idx1 - 2] = y0r - y2r; 5200 a[idx1 - 1] = y0i - y2i; 5201 x0r = x1r - x3i; 5202 x0i = x1i + x3r; 5203 a[idx2] = wk1i * x0r - wk1r * x0i; 5204 a[idx2 + 1] = wk1i * x0i + wk1r * x0r; 5205 x0r = y1r - y3i; 5206 x0i = y1i + y3r; 5207 a[idx2 - 2] = wd1i * x0r - wd1r * x0i; 5208 a[idx2 - 1] = wd1i * x0i + wd1r * x0r; 5209 x0r = x1r + x3i; 5210 x0i = x1i - x3r; 5211 a[idx3] = wk3i * x0r + wk3r * x0i; 5212 a[idx3 + 1] = wk3i * x0i - wk3r * x0r; 5213 x0r = y1r + y3i; 5214 x0i = y1i - y3r; 5215 a[offa + j3 - 2] = wd3i * x0r + wd3r * x0i; 5216 a[offa + j3 - 1] = wd3i * x0i - wd3r * x0r; 5217 } 5218 wk1r = csc1 * (wd1r + wn4r); 5219 wk1i = csc1 * (wd1i + wn4r); 5220 wk3r = csc3 * (wd3r - wn4r); 5221 wk3i = csc3 * (wd3i - wn4r); 5222 j0 = mh; 5223 j1 = j0 + m; 5224 j2 = j1 + m; 5225 j3 = j2 + m; 5226 idx0 = offa + j0; 5227 idx1 = offa + j1; 5228 idx2 = offa + j2; 5229 idx3 = offa + j3; 5230 x0r = a[idx0 - 2] + a[idx2 - 2]; 5231 x0i = a[idx0 - 1] + a[idx2 - 1]; 5232 x1r = a[idx0 - 2] - a[idx2 - 2]; 5233 x1i = a[idx0 - 1] - a[idx2 - 1]; 5234 x2r = a[idx1 - 2] + a[idx3 - 2]; 5235 x2i = a[idx1 - 1] + a[idx3 - 1]; 5236 x3r = a[idx1 - 2] - a[idx3 - 2]; 5237 x3i = a[idx1 - 1] - a[idx3 - 1]; 5238 a[idx0 - 2] = x0r + x2r; 5239 a[idx0 - 1] = x0i + x2i; 5240 a[idx1 - 2] = x0r - x2r; 5241 a[idx1 - 1] = x0i - x2i; 5242 x0r = x1r - x3i; 5243 x0i = x1i + x3r; 5244 a[idx2 - 2] = wk1r * x0r - wk1i * x0i; 5245 a[idx2 - 1] = wk1r * x0i + wk1i * x0r; 5246 x0r = x1r + x3i; 5247 x0i = x1i - x3r; 5248 a[idx3 - 2] = wk3r * x0r + wk3i * x0i; 5249 a[idx3 - 1] = wk3r * x0i - wk3i * x0r; 5250 x0r = a[idx0] + a[idx2]; 5251 x0i = a[idx0 + 1] + a[idx2 + 1]; 5252 x1r = a[idx0] - a[idx2]; 5253 x1i = a[idx0 + 1] - a[idx2 + 1]; 5254 x2r = a[idx1] + a[idx3]; 5255 x2i = a[idx1 + 1] + a[idx3 + 1]; 5256 x3r = a[idx1] - a[idx3]; 5257 x3i = a[idx1 + 1] - a[idx3 + 1]; 5258 a[idx0] = x0r + x2r; 5259 a[idx0 + 1] = x0i + x2i; 5260 a[idx1] = x0r - x2r; 5261 a[idx1 + 1] = x0i - x2i; 5262 x0r = x1r - x3i; 5263 x0i = x1i + x3r; 5264 a[idx2] = wn4r * (x0r - x0i); 5265 a[idx2 + 1] = wn4r * (x0i + x0r); 5266 x0r = x1r + x3i; 5267 x0i = x1i - x3r; 5268 a[idx3] = -wn4r * (x0r + x0i); 5269 a[idx3 + 1] = -wn4r * (x0i - x0r); 5270 x0r = a[idx0 + 2] + a[idx2 + 2]; 5271 x0i = a[idx0 + 3] + a[idx2 + 3]; 5272 x1r = a[idx0 + 2] - a[idx2 + 2]; 5273 x1i = a[idx0 + 3] - a[idx2 + 3]; 5274 x2r = a[idx1 + 2] + a[idx3 + 2]; 5275 x2i = a[idx1 + 3] + a[idx3 + 3]; 5276 x3r = a[idx1 + 2] - a[idx3 + 2]; 5277 x3i = a[idx1 + 3] - a[idx3 + 3]; 5278 a[idx0 + 2] = x0r + x2r; 5279 a[idx0 + 3] = x0i + x2i; 5280 a[idx1 + 2] = x0r - x2r; 5281 a[idx1 + 3] = x0i - x2i; 5282 x0r = x1r - x3i; 5283 x0i = x1i + x3r; 5284 a[idx2 + 2] = wk1i * x0r - wk1r * x0i; 5285 a[idx2 + 3] = wk1i * x0i + wk1r * x0r; 5286 x0r = x1r + x3i; 5287 x0i = x1i - x3r; 5288 a[idx3 + 2] = wk3i * x0r + wk3r * x0i; 5289 a[idx3 + 3] = wk3i * x0i - wk3r * x0r; 5290 } 5291 5292 private void cftb1st(int n, float[] a, int offa, float[] w, int startw) { 5293 int j0, j1, j2, j3, k, m, mh; 5294 float wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; 5295 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; 5296 int idx0, idx1, idx2, idx3, idx4, idx5; 5297 mh = n >> 3; 5298 m = 2 * mh; 5299 j1 = m; 5300 j2 = j1 + m; 5301 j3 = j2 + m; 5302 idx1 = offa + j1; 5303 idx2 = offa + j2; 5304 idx3 = offa + j3; 5305 5306 x0r = a[offa] + a[idx2]; 5307 x0i = -a[offa + 1] - a[idx2 + 1]; 5308 x1r = a[offa] - a[idx2]; 5309 x1i = -a[offa + 1] + a[idx2 + 1]; 5310 x2r = a[idx1] + a[idx3]; 5311 x2i = a[idx1 + 1] + a[idx3 + 1]; 5312 x3r = a[idx1] - a[idx3]; 5313 x3i = a[idx1 + 1] - a[idx3 + 1]; 5314 a[offa] = x0r + x2r; 5315 a[offa + 1] = x0i - x2i; 5316 a[idx1] = x0r - x2r; 5317 a[idx1 + 1] = x0i + x2i; 5318 a[idx2] = x1r + x3i; 5319 a[idx2 + 1] = x1i + x3r; 5320 a[idx3] = x1r - x3i; 5321 a[idx3 + 1] = x1i - x3r; 5322 wn4r = w[startw + 1]; 5323 csc1 = w[startw + 2]; 5324 csc3 = w[startw + 3]; 5325 wd1r = 1; 5326 wd1i = 0; 5327 wd3r = 1; 5328 wd3i = 0; 5329 k = 0; 5330 for (int j = 2; j < mh - 2; j += 4) { 5331 k += 4; 5332 idx4 = startw + k; 5333 wk1r = csc1 * (wd1r + w[idx4]); 5334 wk1i = csc1 * (wd1i + w[idx4 + 1]); 5335 wk3r = csc3 * (wd3r + w[idx4 + 2]); 5336 wk3i = csc3 * (wd3i + w[idx4 + 3]); 5337 wd1r = w[idx4]; 5338 wd1i = w[idx4 + 1]; 5339 wd3r = w[idx4 + 2]; 5340 wd3i = w[idx4 + 3]; 5341 j1 = j + m; 5342 j2 = j1 + m; 5343 j3 = j2 + m; 5344 idx1 = offa + j1; 5345 idx2 = offa + j2; 5346 idx3 = offa + j3; 5347 idx5 = offa + j; 5348 x0r = a[idx5] + a[idx2]; 5349 x0i = -a[idx5 + 1] - a[idx2 + 1]; 5350 x1r = a[idx5] - a[offa + j2]; 5351 x1i = -a[idx5 + 1] + a[idx2 + 1]; 5352 y0r = a[idx5 + 2] + a[idx2 + 2]; 5353 y0i = -a[idx5 + 3] - a[idx2 + 3]; 5354 y1r = a[idx5 + 2] - a[idx2 + 2]; 5355 y1i = -a[idx5 + 3] + a[idx2 + 3]; 5356 x2r = a[idx1] + a[idx3]; 5357 x2i = a[idx1 + 1] + a[idx3 + 1]; 5358 x3r = a[idx1] - a[idx3]; 5359 x3i = a[idx1 + 1] - a[idx3 + 1]; 5360 y2r = a[idx1 + 2] + a[idx3 + 2]; 5361 y2i = a[idx1 + 3] + a[idx3 + 3]; 5362 y3r = a[idx1 + 2] - a[idx3 + 2]; 5363 y3i = a[idx1 + 3] - a[idx3 + 3]; 5364 a[idx5] = x0r + x2r; 5365 a[idx5 + 1] = x0i - x2i; 5366 a[idx5 + 2] = y0r + y2r; 5367 a[idx5 + 3] = y0i - y2i; 5368 a[idx1] = x0r - x2r; 5369 a[idx1 + 1] = x0i + x2i; 5370 a[idx1 + 2] = y0r - y2r; 5371 a[idx1 + 3] = y0i + y2i; 5372 x0r = x1r + x3i; 5373 x0i = x1i + x3r; 5374 a[idx2] = wk1r * x0r - wk1i * x0i; 5375 a[idx2 + 1] = wk1r * x0i + wk1i * x0r; 5376 x0r = y1r + y3i; 5377 x0i = y1i + y3r; 5378 a[idx2 + 2] = wd1r * x0r - wd1i * x0i; 5379 a[idx2 + 3] = wd1r * x0i + wd1i * x0r; 5380 x0r = x1r - x3i; 5381 x0i = x1i - x3r; 5382 a[idx3] = wk3r * x0r + wk3i * x0i; 5383 a[idx3 + 1] = wk3r * x0i - wk3i * x0r; 5384 x0r = y1r - y3i; 5385 x0i = y1i - y3r; 5386 a[idx3 + 2] = wd3r * x0r + wd3i * x0i; 5387 a[idx3 + 3] = wd3r * x0i - wd3i * x0r; 5388 j0 = m - j; 5389 j1 = j0 + m; 5390 j2 = j1 + m; 5391 j3 = j2 + m; 5392 idx0 = offa + j0; 5393 idx1 = offa + j1; 5394 idx2 = offa + j2; 5395 idx3 = offa + j3; 5396 x0r = a[idx0] + a[idx2]; 5397 x0i = -a[idx0 + 1] - a[idx2 + 1]; 5398 x1r = a[idx0] - a[idx2]; 5399 x1i = -a[idx0 + 1] + a[idx2 + 1]; 5400 y0r = a[idx0 - 2] + a[idx2 - 2]; 5401 y0i = -a[idx0 - 1] - a[idx2 - 1]; 5402 y1r = a[idx0 - 2] - a[idx2 - 2]; 5403 y1i = -a[idx0 - 1] + a[idx2 - 1]; 5404 x2r = a[idx1] + a[idx3]; 5405 x2i = a[idx1 + 1] + a[idx3 + 1]; 5406 x3r = a[idx1] - a[idx3]; 5407 x3i = a[idx1 + 1] - a[idx3 + 1]; 5408 y2r = a[idx1 - 2] + a[idx3 - 2]; 5409 y2i = a[idx1 - 1] + a[idx3 - 1]; 5410 y3r = a[idx1 - 2] - a[idx3 - 2]; 5411 y3i = a[idx1 - 1] - a[idx3 - 1]; 5412 a[idx0] = x0r + x2r; 5413 a[idx0 + 1] = x0i - x2i; 5414 a[idx0 - 2] = y0r + y2r; 5415 a[idx0 - 1] = y0i - y2i; 5416 a[idx1] = x0r - x2r; 5417 a[idx1 + 1] = x0i + x2i; 5418 a[idx1 - 2] = y0r - y2r; 5419 a[idx1 - 1] = y0i + y2i; 5420 x0r = x1r + x3i; 5421 x0i = x1i + x3r; 5422 a[idx2] = wk1i * x0r - wk1r * x0i; 5423 a[idx2 + 1] = wk1i * x0i + wk1r * x0r; 5424 x0r = y1r + y3i; 5425 x0i = y1i + y3r; 5426 a[idx2 - 2] = wd1i * x0r - wd1r * x0i; 5427 a[idx2 - 1] = wd1i * x0i + wd1r * x0r; 5428 x0r = x1r - x3i; 5429 x0i = x1i - x3r; 5430 a[idx3] = wk3i * x0r + wk3r * x0i; 5431 a[idx3 + 1] = wk3i * x0i - wk3r * x0r; 5432 x0r = y1r - y3i; 5433 x0i = y1i - y3r; 5434 a[idx3 - 2] = wd3i * x0r + wd3r * x0i; 5435 a[idx3 - 1] = wd3i * x0i - wd3r * x0r; 5436 } 5437 wk1r = csc1 * (wd1r + wn4r); 5438 wk1i = csc1 * (wd1i + wn4r); 5439 wk3r = csc3 * (wd3r - wn4r); 5440 wk3i = csc3 * (wd3i - wn4r); 5441 j0 = mh; 5442 j1 = j0 + m; 5443 j2 = j1 + m; 5444 j3 = j2 + m; 5445 idx0 = offa + j0; 5446 idx1 = offa + j1; 5447 idx2 = offa + j2; 5448 idx3 = offa + j3; 5449 x0r = a[idx0 - 2] + a[idx2 - 2]; 5450 x0i = -a[idx0 - 1] - a[idx2 - 1]; 5451 x1r = a[idx0 - 2] - a[idx2 - 2]; 5452 x1i = -a[idx0 - 1] + a[idx2 - 1]; 5453 x2r = a[idx1 - 2] + a[idx3 - 2]; 5454 x2i = a[idx1 - 1] + a[idx3 - 1]; 5455 x3r = a[idx1 - 2] - a[idx3 - 2]; 5456 x3i = a[idx1 - 1] - a[idx3 - 1]; 5457 a[idx0 - 2] = x0r + x2r; 5458 a[idx0 - 1] = x0i - x2i; 5459 a[idx1 - 2] = x0r - x2r; 5460 a[idx1 - 1] = x0i + x2i; 5461 x0r = x1r + x3i; 5462 x0i = x1i + x3r; 5463 a[idx2 - 2] = wk1r * x0r - wk1i * x0i; 5464 a[idx2 - 1] = wk1r * x0i + wk1i * x0r; 5465 x0r = x1r - x3i; 5466 x0i = x1i - x3r; 5467 a[idx3 - 2] = wk3r * x0r + wk3i * x0i; 5468 a[idx3 - 1] = wk3r * x0i - wk3i * x0r; 5469 x0r = a[idx0] + a[idx2]; 5470 x0i = -a[idx0 + 1] - a[idx2 + 1]; 5471 x1r = a[idx0] - a[idx2]; 5472 x1i = -a[idx0 + 1] + a[idx2 + 1]; 5473 x2r = a[idx1] + a[idx3]; 5474 x2i = a[idx1 + 1] + a[idx3 + 1]; 5475 x3r = a[idx1] - a[idx3]; 5476 x3i = a[idx1 + 1] - a[idx3 + 1]; 5477 a[idx0] = x0r + x2r; 5478 a[idx0 + 1] = x0i - x2i; 5479 a[idx1] = x0r - x2r; 5480 a[idx1 + 1] = x0i + x2i; 5481 x0r = x1r + x3i; 5482 x0i = x1i + x3r; 5483 a[idx2] = wn4r * (x0r - x0i); 5484 a[idx2 + 1] = wn4r * (x0i + x0r); 5485 x0r = x1r - x3i; 5486 x0i = x1i - x3r; 5487 a[idx3] = -wn4r * (x0r + x0i); 5488 a[idx3 + 1] = -wn4r * (x0i - x0r); 5489 x0r = a[idx0 + 2] + a[idx2 + 2]; 5490 x0i = -a[idx0 + 3] - a[idx2 + 3]; 5491 x1r = a[idx0 + 2] - a[idx2 + 2]; 5492 x1i = -a[idx0 + 3] + a[idx2 + 3]; 5493 x2r = a[idx1 + 2] + a[idx3 + 2]; 5494 x2i = a[idx1 + 3] + a[idx3 + 3]; 5495 x3r = a[idx1 + 2] - a[idx3 + 2]; 5496 x3i = a[idx1 + 3] - a[idx3 + 3]; 5497 a[idx0 + 2] = x0r + x2r; 5498 a[idx0 + 3] = x0i - x2i; 5499 a[idx1 + 2] = x0r - x2r; 5500 a[idx1 + 3] = x0i + x2i; 5501 x0r = x1r + x3i; 5502 x0i = x1i + x3r; 5503 a[idx2 + 2] = wk1i * x0r - wk1r * x0i; 5504 a[idx2 + 3] = wk1i * x0i + wk1r * x0r; 5505 x0r = x1r - x3i; 5506 x0i = x1i - x3r; 5507 a[idx3 + 2] = wk3i * x0r + wk3r * x0i; 5508 a[idx3 + 3] = wk3i * x0i - wk3r * x0r; 5509 } 5510 5511 private void cftrec4_th(final int n, final float[] a, final int offa, final int nw, final float[] w) { 5512 int i; 5513 int idiv4, m, nthreads; 5514 int idx = 0; 5515 nthreads = 2; 5516 idiv4 = 0; 5517 m = n >> 1; 5518 if (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads()) { 5519 nthreads = 4; 5520 idiv4 = 1; 5521 m >>= 1; 5522 } 5523 Future<?>[] futures = new Future[nthreads]; 5524 final int mf = m; 5525 for (i = 0; i < nthreads; i++) { 5526 final int firstIdx = offa + i * m; 5527 if (i != idiv4) { 5528 futures[idx++] = ConcurrencyUtils.submit(new Runnable() { 5529 public void run() { 5530 int isplt, j, k, m; 5531 int idx1 = firstIdx + mf; 5532 m = n; 5533 while (m > 512) { 5534 m >>= 2; 5535 cftmdl1(m, a, idx1 - m, w, nw - (m >> 1)); 5536 } 5537 cftleaf(m, 1, a, idx1 - m, nw, w); 5538 k = 0; 5539 int idx2 = firstIdx - m; 5540 for (j = mf - m; j > 0; j -= m) { 5541 k++; 5542 isplt = cfttree(m, j, k, a, firstIdx, nw, w); 5543 cftleaf(m, isplt, a, idx2 + j, nw, w); 5544 } 5545 } 5546 }); 5547 } else { 5548 futures[idx++] = ConcurrencyUtils.submit(new Runnable() { 5549 public void run() { 5550 int isplt, j, k, m; 5551 int idx1 = firstIdx + mf; 5552 k = 1; 5553 m = n; 5554 while (m > 512) { 5555 m >>= 2; 5556 k <<= 2; 5557 cftmdl2(m, a, idx1 - m, w, nw - m); 5558 } 5559 cftleaf(m, 0, a, idx1 - m, nw, w); 5560 k >>= 1; 5561 int idx2 = firstIdx - m; 5562 for (j = mf - m; j > 0; j -= m) { 5563 k++; 5564 isplt = cfttree(m, j, k, a, firstIdx, nw, w); 5565 cftleaf(m, isplt, a, idx2 + j, nw, w); 5566 } 5567 } 5568 }); 5569 } 5570 } 5571 ConcurrencyUtils.waitForCompletion(futures); 5572 } 5573 5574 private void cftrec4(int n, float[] a, int offa, int nw, float[] w) { 5575 int isplt, j, k, m; 5576 5577 m = n; 5578 int idx1 = offa + n; 5579 while (m > 512) { 5580 m >>= 2; 5581 cftmdl1(m, a, idx1 - m, w, nw - (m >> 1)); 5582 } 5583 cftleaf(m, 1, a, idx1 - m, nw, w); 5584 k = 0; 5585 int idx2 = offa - m; 5586 for (j = n - m; j > 0; j -= m) { 5587 k++; 5588 isplt = cfttree(m, j, k, a, offa, nw, w); 5589 cftleaf(m, isplt, a, idx2 + j, nw, w); 5590 } 5591 } 5592 5593 private int cfttree(int n, int j, int k, float[] a, int offa, int nw, float[] w) { 5594 int i, isplt, m; 5595 int idx1 = offa - n; 5596 if ((k & 3) != 0) { 5597 isplt = k & 1; 5598 if (isplt != 0) { 5599 cftmdl1(n, a, idx1 + j, w, nw - (n >> 1)); 5600 } else { 5601 cftmdl2(n, a, idx1 + j, w, nw - n); 5602 } 5603 } else { 5604 m = n; 5605 for (i = k; (i & 3) == 0; i >>= 2) { 5606 m <<= 2; 5607 } 5608 isplt = i & 1; 5609 int idx2 = offa + j; 5610 if (isplt != 0) { 5611 while (m > 128) { 5612 cftmdl1(m, a, idx2 - m, w, nw - (m >> 1)); 5613 m >>= 2; 5614 } 5615 } else { 5616 while (m > 128) { 5617 cftmdl2(m, a, idx2 - m, w, nw - m); 5618 m >>= 2; 5619 } 5620 } 5621 } 5622 return isplt; 5623 } 5624 5625 private void cftleaf(int n, int isplt, float[] a, int offa, int nw, float[] w) { 5626 if (n == 512) { 5627 cftmdl1(128, a, offa, w, nw - 64); 5628 cftf161(a, offa, w, nw - 8); 5629 cftf162(a, offa + 32, w, nw - 32); 5630 cftf161(a, offa + 64, w, nw - 8); 5631 cftf161(a, offa + 96, w, nw - 8); 5632 cftmdl2(128, a, offa + 128, w, nw - 128); 5633 cftf161(a, offa + 128, w, nw - 8); 5634 cftf162(a, offa + 160, w, nw - 32); 5635 cftf161(a, offa + 192, w, nw - 8); 5636 cftf162(a, offa + 224, w, nw - 32); 5637 cftmdl1(128, a, offa + 256, w, nw - 64); 5638 cftf161(a, offa + 256, w, nw - 8); 5639 cftf162(a, offa + 288, w, nw - 32); 5640 cftf161(a, offa + 320, w, nw - 8); 5641 cftf161(a, offa + 352, w, nw - 8); 5642 if (isplt != 0) { 5643 cftmdl1(128, a, offa + 384, w, nw - 64); 5644 cftf161(a, offa + 480, w, nw - 8); 5645 } else { 5646 cftmdl2(128, a, offa + 384, w, nw - 128); 5647 cftf162(a, offa + 480, w, nw - 32); 5648 } 5649 cftf161(a, offa + 384, w, nw - 8); 5650 cftf162(a, offa + 416, w, nw - 32); 5651 cftf161(a, offa + 448, w, nw - 8); 5652 } else { 5653 cftmdl1(64, a, offa, w, nw - 32); 5654 cftf081(a, offa, w, nw - 8); 5655 cftf082(a, offa + 16, w, nw - 8); 5656 cftf081(a, offa + 32, w, nw - 8); 5657 cftf081(a, offa + 48, w, nw - 8); 5658 cftmdl2(64, a, offa + 64, w, nw - 64); 5659 cftf081(a, offa + 64, w, nw - 8); 5660 cftf082(a, offa + 80, w, nw - 8); 5661 cftf081(a, offa + 96, w, nw - 8); 5662 cftf082(a, offa + 112, w, nw - 8); 5663 cftmdl1(64, a, offa + 128, w, nw - 32); 5664 cftf081(a, offa + 128, w, nw - 8); 5665 cftf082(a, offa + 144, w, nw - 8); 5666 cftf081(a, offa + 160, w, nw - 8); 5667 cftf081(a, offa + 176, w, nw - 8); 5668 if (isplt != 0) { 5669 cftmdl1(64, a, offa + 192, w, nw - 32); 5670 cftf081(a, offa + 240, w, nw - 8); 5671 } else { 5672 cftmdl2(64, a, offa + 192, w, nw - 64); 5673 cftf082(a, offa + 240, w, nw - 8); 5674 } 5675 cftf081(a, offa + 192, w, nw - 8); 5676 cftf082(a, offa + 208, w, nw - 8); 5677 cftf081(a, offa + 224, w, nw - 8); 5678 } 5679 } 5680 5681 private void cftmdl1(int n, float[] a, int offa, float[] w, int startw) { 5682 int j0, j1, j2, j3, k, m, mh; 5683 float wn4r, wk1r, wk1i, wk3r, wk3i; 5684 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; 5685 int idx0, idx1, idx2, idx3, idx4, idx5; 5686 5687 mh = n >> 3; 5688 m = 2 * mh; 5689 j1 = m; 5690 j2 = j1 + m; 5691 j3 = j2 + m; 5692 idx1 = offa + j1; 5693 idx2 = offa + j2; 5694 idx3 = offa + j3; 5695 x0r = a[offa] + a[idx2]; 5696 x0i = a[offa + 1] + a[idx2 + 1]; 5697 x1r = a[offa] - a[idx2]; 5698 x1i = a[offa + 1] - a[idx2 + 1]; 5699 x2r = a[idx1] + a[idx3]; 5700 x2i = a[idx1 + 1] + a[idx3 + 1]; 5701 x3r = a[idx1] - a[idx3]; 5702 x3i = a[idx1 + 1] - a[idx3 + 1]; 5703 a[offa] = x0r + x2r; 5704 a[offa + 1] = x0i + x2i; 5705 a[idx1] = x0r - x2r; 5706 a[idx1 + 1] = x0i - x2i; 5707 a[idx2] = x1r - x3i; 5708 a[idx2 + 1] = x1i + x3r; 5709 a[idx3] = x1r + x3i; 5710 a[idx3 + 1] = x1i - x3r; 5711 wn4r = w[startw + 1]; 5712 k = 0; 5713 for (int j = 2; j < mh; j += 2) { 5714 k += 4; 5715 idx4 = startw + k; 5716 wk1r = w[idx4]; 5717 wk1i = w[idx4 + 1]; 5718 wk3r = w[idx4 + 2]; 5719 wk3i = w[idx4 + 3]; 5720 j1 = j + m; 5721 j2 = j1 + m; 5722 j3 = j2 + m; 5723 idx1 = offa + j1; 5724 idx2 = offa + j2; 5725 idx3 = offa + j3; 5726 idx5 = offa + j; 5727 x0r = a[idx5] + a[idx2]; 5728 x0i = a[idx5 + 1] + a[idx2 + 1]; 5729 x1r = a[idx5] - a[idx2]; 5730 x1i = a[idx5 + 1] - a[idx2 + 1]; 5731 x2r = a[idx1] + a[idx3]; 5732 x2i = a[idx1 + 1] + a[idx3 + 1]; 5733 x3r = a[idx1] - a[idx3]; 5734 x3i = a[idx1 + 1] - a[idx3 + 1]; 5735 a[idx5] = x0r + x2r; 5736 a[idx5 + 1] = x0i + x2i; 5737 a[idx1] = x0r - x2r; 5738 a[idx1 + 1] = x0i - x2i; 5739 x0r = x1r - x3i; 5740 x0i = x1i + x3r; 5741 a[idx2] = wk1r * x0r - wk1i * x0i; 5742 a[idx2 + 1] = wk1r * x0i + wk1i * x0r; 5743 x0r = x1r + x3i; 5744 x0i = x1i - x3r; 5745 a[idx3] = wk3r * x0r + wk3i * x0i; 5746 a[idx3 + 1] = wk3r * x0i - wk3i * x0r; 5747 j0 = m - j; 5748 j1 = j0 + m; 5749 j2 = j1 + m; 5750 j3 = j2 + m; 5751 idx0 = offa + j0; 5752 idx1 = offa + j1; 5753 idx2 = offa + j2; 5754 idx3 = offa + j3; 5755 x0r = a[idx0] + a[idx2]; 5756 x0i = a[idx0 + 1] + a[idx2 + 1]; 5757 x1r = a[idx0] - a[idx2]; 5758 x1i = a[idx0 + 1] - a[idx2 + 1]; 5759 x2r = a[idx1] + a[idx3]; 5760 x2i = a[idx1 + 1] + a[idx3 + 1]; 5761 x3r = a[idx1] - a[idx3]; 5762 x3i = a[idx1 + 1] - a[idx3 + 1]; 5763 a[idx0] = x0r + x2r; 5764 a[idx0 + 1] = x0i + x2i; 5765 a[idx1] = x0r - x2r; 5766 a[idx1 + 1] = x0i - x2i; 5767 x0r = x1r - x3i; 5768 x0i = x1i + x3r; 5769 a[idx2] = wk1i * x0r - wk1r * x0i; 5770 a[idx2 + 1] = wk1i * x0i + wk1r * x0r; 5771 x0r = x1r + x3i; 5772 x0i = x1i - x3r; 5773 a[idx3] = wk3i * x0r + wk3r * x0i; 5774 a[idx3 + 1] = wk3i * x0i - wk3r * x0r; 5775 } 5776 j0 = mh; 5777 j1 = j0 + m; 5778 j2 = j1 + m; 5779 j3 = j2 + m; 5780 idx0 = offa + j0; 5781 idx1 = offa + j1; 5782 idx2 = offa + j2; 5783 idx3 = offa + j3; 5784 x0r = a[idx0] + a[idx2]; 5785 x0i = a[idx0 + 1] + a[idx2 + 1]; 5786 x1r = a[idx0] - a[idx2]; 5787 x1i = a[idx0 + 1] - a[idx2 + 1]; 5788 x2r = a[idx1] + a[idx3]; 5789 x2i = a[idx1 + 1] + a[idx3 + 1]; 5790 x3r = a[idx1] - a[idx3]; 5791 x3i = a[idx1 + 1] - a[idx3 + 1]; 5792 a[idx0] = x0r + x2r; 5793 a[idx0 + 1] = x0i + x2i; 5794 a[idx1] = x0r - x2r; 5795 a[idx1 + 1] = x0i - x2i; 5796 x0r = x1r - x3i; 5797 x0i = x1i + x3r; 5798 a[idx2] = wn4r * (x0r - x0i); 5799 a[idx2 + 1] = wn4r * (x0i + x0r); 5800 x0r = x1r + x3i; 5801 x0i = x1i - x3r; 5802 a[idx3] = -wn4r * (x0r + x0i); 5803 a[idx3 + 1] = -wn4r * (x0i - x0r); 5804 } 5805 5806 private void cftmdl2(int n, float[] a, int offa, float[] w, int startw) { 5807 int j0, j1, j2, j3, k, kr, m, mh; 5808 float wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; 5809 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; 5810 int idx0, idx1, idx2, idx3, idx4, idx5, idx6; 5811 5812 mh = n >> 3; 5813 m = 2 * mh; 5814 wn4r = w[startw + 1]; 5815 j1 = m; 5816 j2 = j1 + m; 5817 j3 = j2 + m; 5818 idx1 = offa + j1; 5819 idx2 = offa + j2; 5820 idx3 = offa + j3; 5821 x0r = a[offa] - a[idx2 + 1]; 5822 x0i = a[offa + 1] + a[idx2]; 5823 x1r = a[offa] + a[idx2 + 1]; 5824 x1i = a[offa + 1] - a[idx2]; 5825 x2r = a[idx1] - a[idx3 + 1]; 5826 x2i = a[idx1 + 1] + a[idx3]; 5827 x3r = a[idx1] + a[idx3 + 1]; 5828 x3i = a[idx1 + 1] - a[idx3]; 5829 y0r = wn4r * (x2r - x2i); 5830 y0i = wn4r * (x2i + x2r); 5831 a[offa] = x0r + y0r; 5832 a[offa + 1] = x0i + y0i; 5833 a[idx1] = x0r - y0r; 5834 a[idx1 + 1] = x0i - y0i; 5835 y0r = wn4r * (x3r - x3i); 5836 y0i = wn4r * (x3i + x3r); 5837 a[idx2] = x1r - y0i; 5838 a[idx2 + 1] = x1i + y0r; 5839 a[idx3] = x1r + y0i; 5840 a[idx3 + 1] = x1i - y0r; 5841 k = 0; 5842 kr = 2 * m; 5843 for (int j = 2; j < mh; j += 2) { 5844 k += 4; 5845 idx4 = startw + k; 5846 wk1r = w[idx4]; 5847 wk1i = w[idx4 + 1]; 5848 wk3r = w[idx4 + 2]; 5849 wk3i = w[idx4 + 3]; 5850 kr -= 4; 5851 idx5 = startw + kr; 5852 wd1i = w[idx5]; 5853 wd1r = w[idx5 + 1]; 5854 wd3i = w[idx5 + 2]; 5855 wd3r = w[idx5 + 3]; 5856 j1 = j + m; 5857 j2 = j1 + m; 5858 j3 = j2 + m; 5859 idx1 = offa + j1; 5860 idx2 = offa + j2; 5861 idx3 = offa + j3; 5862 idx6 = offa + j; 5863 x0r = a[idx6] - a[idx2 + 1]; 5864 x0i = a[idx6 + 1] + a[idx2]; 5865 x1r = a[idx6] + a[idx2 + 1]; 5866 x1i = a[idx6 + 1] - a[idx2]; 5867 x2r = a[idx1] - a[idx3 + 1]; 5868 x2i = a[idx1 + 1] + a[idx3]; 5869 x3r = a[idx1] + a[idx3 + 1]; 5870 x3i = a[idx1 + 1] - a[idx3]; 5871 y0r = wk1r * x0r - wk1i * x0i; 5872 y0i = wk1r * x0i + wk1i * x0r; 5873 y2r = wd1r * x2r - wd1i * x2i; 5874 y2i = wd1r * x2i + wd1i * x2r; 5875 a[idx6] = y0r + y2r; 5876 a[idx6 + 1] = y0i + y2i; 5877 a[idx1] = y0r - y2r; 5878 a[idx1 + 1] = y0i - y2i; 5879 y0r = wk3r * x1r + wk3i * x1i; 5880 y0i = wk3r * x1i - wk3i * x1r; 5881 y2r = wd3r * x3r + wd3i * x3i; 5882 y2i = wd3r * x3i - wd3i * x3r; 5883 a[idx2] = y0r + y2r; 5884 a[idx2 + 1] = y0i + y2i; 5885 a[idx3] = y0r - y2r; 5886 a[idx3 + 1] = y0i - y2i; 5887 j0 = m - j; 5888 j1 = j0 + m; 5889 j2 = j1 + m; 5890 j3 = j2 + m; 5891 idx0 = offa + j0; 5892 idx1 = offa + j1; 5893 idx2 = offa + j2; 5894 idx3 = offa + j3; 5895 x0r = a[idx0] - a[idx2 + 1]; 5896 x0i = a[idx0 + 1] + a[idx2]; 5897 x1r = a[idx0] + a[idx2 + 1]; 5898 x1i = a[idx0 + 1] - a[idx2]; 5899 x2r = a[idx1] - a[idx3 + 1]; 5900 x2i = a[idx1 + 1] + a[idx3]; 5901 x3r = a[idx1] + a[idx3 + 1]; 5902 x3i = a[idx1 + 1] - a[idx3]; 5903 y0r = wd1i * x0r - wd1r * x0i; 5904 y0i = wd1i * x0i + wd1r * x0r; 5905 y2r = wk1i * x2r - wk1r * x2i; 5906 y2i = wk1i * x2i + wk1r * x2r; 5907 a[idx0] = y0r + y2r; 5908 a[idx0 + 1] = y0i + y2i; 5909 a[idx1] = y0r - y2r; 5910 a[idx1 + 1] = y0i - y2i; 5911 y0r = wd3i * x1r + wd3r * x1i; 5912 y0i = wd3i * x1i - wd3r * x1r; 5913 y2r = wk3i * x3r + wk3r * x3i; 5914 y2i = wk3i * x3i - wk3r * x3r; 5915 a[idx2] = y0r + y2r; 5916 a[idx2 + 1] = y0i + y2i; 5917 a[idx3] = y0r - y2r; 5918 a[idx3 + 1] = y0i - y2i; 5919 } 5920 wk1r = w[startw + m]; 5921 wk1i = w[startw + m + 1]; 5922 j0 = mh; 5923 j1 = j0 + m; 5924 j2 = j1 + m; 5925 j3 = j2 + m; 5926 idx0 = offa + j0; 5927 idx1 = offa + j1; 5928 idx2 = offa + j2; 5929 idx3 = offa + j3; 5930 x0r = a[idx0] - a[idx2 + 1]; 5931 x0i = a[idx0 + 1] + a[idx2]; 5932 x1r = a[idx0] + a[idx2 + 1]; 5933 x1i = a[idx0 + 1] - a[idx2]; 5934 x2r = a[idx1] - a[idx3 + 1]; 5935 x2i = a[idx1 + 1] + a[idx3]; 5936 x3r = a[idx1] + a[idx3 + 1]; 5937 x3i = a[idx1 + 1] - a[idx3]; 5938 y0r = wk1r * x0r - wk1i * x0i; 5939 y0i = wk1r * x0i + wk1i * x0r; 5940 y2r = wk1i * x2r - wk1r * x2i; 5941 y2i = wk1i * x2i + wk1r * x2r; 5942 a[idx0] = y0r + y2r; 5943 a[idx0 + 1] = y0i + y2i; 5944 a[idx1] = y0r - y2r; 5945 a[idx1 + 1] = y0i - y2i; 5946 y0r = wk1i * x1r - wk1r * x1i; 5947 y0i = wk1i * x1i + wk1r * x1r; 5948 y2r = wk1r * x3r - wk1i * x3i; 5949 y2i = wk1r * x3i + wk1i * x3r; 5950 a[idx2] = y0r - y2r; 5951 a[idx2 + 1] = y0i - y2i; 5952 a[idx3] = y0r + y2r; 5953 a[idx3 + 1] = y0i + y2i; 5954 } 5955 5956 private void cftfx41(int n, float[] a, int offa, int nw, float[] w) { 5957 if (n == 128) { 5958 cftf161(a, offa, w, nw - 8); 5959 cftf162(a, offa + 32, w, nw - 32); 5960 cftf161(a, offa + 64, w, nw - 8); 5961 cftf161(a, offa + 96, w, nw - 8); 5962 } else { 5963 cftf081(a, offa, w, nw - 8); 5964 cftf082(a, offa + 16, w, nw - 8); 5965 cftf081(a, offa + 32, w, nw - 8); 5966 cftf081(a, offa + 48, w, nw - 8); 5967 } 5968 } 5969 5970 private void cftf161(float[] a, int offa, float[] w, int startw) { 5971 float wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; 5972 5973 wn4r = w[startw + 1]; 5974 wk1r = w[startw + 2]; 5975 wk1i = w[startw + 3]; 5976 5977 x0r = a[offa] + a[offa + 16]; 5978 x0i = a[offa + 1] + a[offa + 17]; 5979 x1r = a[offa] - a[offa + 16]; 5980 x1i = a[offa + 1] - a[offa + 17]; 5981 x2r = a[offa + 8] + a[offa + 24]; 5982 x2i = a[offa + 9] + a[offa + 25]; 5983 x3r = a[offa + 8] - a[offa + 24]; 5984 x3i = a[offa + 9] - a[offa + 25]; 5985 y0r = x0r + x2r; 5986 y0i = x0i + x2i; 5987 y4r = x0r - x2r; 5988 y4i = x0i - x2i; 5989 y8r = x1r - x3i; 5990 y8i = x1i + x3r; 5991 y12r = x1r + x3i; 5992 y12i = x1i - x3r; 5993 x0r = a[offa + 2] + a[offa + 18]; 5994 x0i = a[offa + 3] + a[offa + 19]; 5995 x1r = a[offa + 2] - a[offa + 18]; 5996 x1i = a[offa + 3] - a[offa + 19]; 5997 x2r = a[offa + 10] + a[offa + 26]; 5998 x2i = a[offa + 11] + a[offa + 27]; 5999 x3r = a[offa + 10] - a[offa + 26]; 6000 x3i = a[offa + 11] - a[offa + 27]; 6001 y1r = x0r + x2r; 6002 y1i = x0i + x2i; 6003 y5r = x0r - x2r; 6004 y5i = x0i - x2i; 6005 x0r = x1r - x3i; 6006 x0i = x1i + x3r; 6007 y9r = wk1r * x0r - wk1i * x0i; 6008 y9i = wk1r * x0i + wk1i * x0r; 6009 x0r = x1r + x3i; 6010 x0i = x1i - x3r; 6011 y13r = wk1i * x0r - wk1r * x0i; 6012 y13i = wk1i * x0i + wk1r * x0r; 6013 x0r = a[offa + 4] + a[offa + 20]; 6014 x0i = a[offa + 5] + a[offa + 21]; 6015 x1r = a[offa + 4] - a[offa + 20]; 6016 x1i = a[offa + 5] - a[offa + 21]; 6017 x2r = a[offa + 12] + a[offa + 28]; 6018 x2i = a[offa + 13] + a[offa + 29]; 6019 x3r = a[offa + 12] - a[offa + 28]; 6020 x3i = a[offa + 13] - a[offa + 29]; 6021 y2r = x0r + x2r; 6022 y2i = x0i + x2i; 6023 y6r = x0r - x2r; 6024 y6i = x0i - x2i; 6025 x0r = x1r - x3i; 6026 x0i = x1i + x3r; 6027 y10r = wn4r * (x0r - x0i); 6028 y10i = wn4r * (x0i + x0r); 6029 x0r = x1r + x3i; 6030 x0i = x1i - x3r; 6031 y14r = wn4r * (x0r + x0i); 6032 y14i = wn4r * (x0i - x0r); 6033 x0r = a[offa + 6] + a[offa + 22]; 6034 x0i = a[offa + 7] + a[offa + 23]; 6035 x1r = a[offa + 6] - a[offa + 22]; 6036 x1i = a[offa + 7] - a[offa + 23]; 6037 x2r = a[offa + 14] + a[offa + 30]; 6038 x2i = a[offa + 15] + a[offa + 31]; 6039 x3r = a[offa + 14] - a[offa + 30]; 6040 x3i = a[offa + 15] - a[offa + 31]; 6041 y3r = x0r + x2r; 6042 y3i = x0i + x2i; 6043 y7r = x0r - x2r; 6044 y7i = x0i - x2i; 6045 x0r = x1r - x3i; 6046 x0i = x1i + x3r; 6047 y11r = wk1i * x0r - wk1r * x0i; 6048 y11i = wk1i * x0i + wk1r * x0r; 6049 x0r = x1r + x3i; 6050 x0i = x1i - x3r; 6051 y15r = wk1r * x0r - wk1i * x0i; 6052 y15i = wk1r * x0i + wk1i * x0r; 6053 x0r = y12r - y14r; 6054 x0i = y12i - y14i; 6055 x1r = y12r + y14r; 6056 x1i = y12i + y14i; 6057 x2r = y13r - y15r; 6058 x2i = y13i - y15i; 6059 x3r = y13r + y15r; 6060 x3i = y13i + y15i; 6061 a[offa + 24] = x0r + x2r; 6062 a[offa + 25] = x0i + x2i; 6063 a[offa + 26] = x0r - x2r; 6064 a[offa + 27] = x0i - x2i; 6065 a[offa + 28] = x1r - x3i; 6066 a[offa + 29] = x1i + x3r; 6067 a[offa + 30] = x1r + x3i; 6068 a[offa + 31] = x1i - x3r; 6069 x0r = y8r + y10r; 6070 x0i = y8i + y10i; 6071 x1r = y8r - y10r; 6072 x1i = y8i - y10i; 6073 x2r = y9r + y11r; 6074 x2i = y9i + y11i; 6075 x3r = y9r - y11r; 6076 x3i = y9i - y11i; 6077 a[offa + 16] = x0r + x2r; 6078 a[offa + 17] = x0i + x2i; 6079 a[offa + 18] = x0r - x2r; 6080 a[offa + 19] = x0i - x2i; 6081 a[offa + 20] = x1r - x3i; 6082 a[offa + 21] = x1i + x3r; 6083 a[offa + 22] = x1r + x3i; 6084 a[offa + 23] = x1i - x3r; 6085 x0r = y5r - y7i; 6086 x0i = y5i + y7r; 6087 x2r = wn4r * (x0r - x0i); 6088 x2i = wn4r * (x0i + x0r); 6089 x0r = y5r + y7i; 6090 x0i = y5i - y7r; 6091 x3r = wn4r * (x0r - x0i); 6092 x3i = wn4r * (x0i + x0r); 6093 x0r = y4r - y6i; 6094 x0i = y4i + y6r; 6095 x1r = y4r + y6i; 6096 x1i = y4i - y6r; 6097 a[offa + 8] = x0r + x2r; 6098 a[offa + 9] = x0i + x2i; 6099 a[offa + 10] = x0r - x2r; 6100 a[offa + 11] = x0i - x2i; 6101 a[offa + 12] = x1r - x3i; 6102 a[offa + 13] = x1i + x3r; 6103 a[offa + 14] = x1r + x3i; 6104 a[offa + 15] = x1i - x3r; 6105 x0r = y0r + y2r; 6106 x0i = y0i + y2i; 6107 x1r = y0r - y2r; 6108 x1i = y0i - y2i; 6109 x2r = y1r + y3r; 6110 x2i = y1i + y3i; 6111 x3r = y1r - y3r; 6112 x3i = y1i - y3i; 6113 a[offa] = x0r + x2r; 6114 a[offa + 1] = x0i + x2i; 6115 a[offa + 2] = x0r - x2r; 6116 a[offa + 3] = x0i - x2i; 6117 a[offa + 4] = x1r - x3i; 6118 a[offa + 5] = x1i + x3r; 6119 a[offa + 6] = x1r + x3i; 6120 a[offa + 7] = x1i - x3r; 6121 } 6122 6123 private void cftf162(float[] a, int offa, float[] w, int startw) { 6124 float wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; 6125 6126 wn4r = w[startw + 1]; 6127 wk1r = w[startw + 4]; 6128 wk1i = w[startw + 5]; 6129 wk3r = w[startw + 6]; 6130 wk3i = -w[startw + 7]; 6131 wk2r = w[startw + 8]; 6132 wk2i = w[startw + 9]; 6133 x1r = a[offa] - a[offa + 17]; 6134 x1i = a[offa + 1] + a[offa + 16]; 6135 x0r = a[offa + 8] - a[offa + 25]; 6136 x0i = a[offa + 9] + a[offa + 24]; 6137 x2r = wn4r * (x0r - x0i); 6138 x2i = wn4r * (x0i + x0r); 6139 y0r = x1r + x2r; 6140 y0i = x1i + x2i; 6141 y4r = x1r - x2r; 6142 y4i = x1i - x2i; 6143 x1r = a[offa] + a[offa + 17]; 6144 x1i = a[offa + 1] - a[offa + 16]; 6145 x0r = a[offa + 8] + a[offa + 25]; 6146 x0i = a[offa + 9] - a[offa + 24]; 6147 x2r = wn4r * (x0r - x0i); 6148 x2i = wn4r * (x0i + x0r); 6149 y8r = x1r - x2i; 6150 y8i = x1i + x2r; 6151 y12r = x1r + x2i; 6152 y12i = x1i - x2r; 6153 x0r = a[offa + 2] - a[offa + 19]; 6154 x0i = a[offa + 3] + a[offa + 18]; 6155 x1r = wk1r * x0r - wk1i * x0i; 6156 x1i = wk1r * x0i + wk1i * x0r; 6157 x0r = a[offa + 10] - a[offa + 27]; 6158 x0i = a[offa + 11] + a[offa + 26]; 6159 x2r = wk3i * x0r - wk3r * x0i; 6160 x2i = wk3i * x0i + wk3r * x0r; 6161 y1r = x1r + x2r; 6162 y1i = x1i + x2i; 6163 y5r = x1r - x2r; 6164 y5i = x1i - x2i; 6165 x0r = a[offa + 2] + a[offa + 19]; 6166 x0i = a[offa + 3] - a[offa + 18]; 6167 x1r = wk3r * x0r - wk3i * x0i; 6168 x1i = wk3r * x0i + wk3i * x0r; 6169 x0r = a[offa + 10] + a[offa + 27]; 6170 x0i = a[offa + 11] - a[offa + 26]; 6171 x2r = wk1r * x0r + wk1i * x0i; 6172 x2i = wk1r * x0i - wk1i * x0r; 6173 y9r = x1r - x2r; 6174 y9i = x1i - x2i; 6175 y13r = x1r + x2r; 6176 y13i = x1i + x2i; 6177 x0r = a[offa + 4] - a[offa + 21]; 6178 x0i = a[offa + 5] + a[offa + 20]; 6179 x1r = wk2r * x0r - wk2i * x0i; 6180 x1i = wk2r * x0i + wk2i * x0r; 6181 x0r = a[offa + 12] - a[offa + 29]; 6182 x0i = a[offa + 13] + a[offa + 28]; 6183 x2r = wk2i * x0r - wk2r * x0i; 6184 x2i = wk2i * x0i + wk2r * x0r; 6185 y2r = x1r + x2r; 6186 y2i = x1i + x2i; 6187 y6r = x1r - x2r; 6188 y6i = x1i - x2i; 6189 x0r = a[offa + 4] + a[offa + 21]; 6190 x0i = a[offa + 5] - a[offa + 20]; 6191 x1r = wk2i * x0r - wk2r * x0i; 6192 x1i = wk2i * x0i + wk2r * x0r; 6193 x0r = a[offa + 12] + a[offa + 29]; 6194 x0i = a[offa + 13] - a[offa + 28]; 6195 x2r = wk2r * x0r - wk2i * x0i; 6196 x2i = wk2r * x0i + wk2i * x0r; 6197 y10r = x1r - x2r; 6198 y10i = x1i - x2i; 6199 y14r = x1r + x2r; 6200 y14i = x1i + x2i; 6201 x0r = a[offa + 6] - a[offa + 23]; 6202 x0i = a[offa + 7] + a[offa + 22]; 6203 x1r = wk3r * x0r - wk3i * x0i; 6204 x1i = wk3r * x0i + wk3i * x0r; 6205 x0r = a[offa + 14] - a[offa + 31]; 6206 x0i = a[offa + 15] + a[offa + 30]; 6207 x2r = wk1i * x0r - wk1r * x0i; 6208 x2i = wk1i * x0i + wk1r * x0r; 6209 y3r = x1r + x2r; 6210 y3i = x1i + x2i; 6211 y7r = x1r - x2r; 6212 y7i = x1i - x2i; 6213 x0r = a[offa + 6] + a[offa + 23]; 6214 x0i = a[offa + 7] - a[offa + 22]; 6215 x1r = wk1i * x0r + wk1r * x0i; 6216 x1i = wk1i * x0i - wk1r * x0r; 6217 x0r = a[offa + 14] + a[offa + 31]; 6218 x0i = a[offa + 15] - a[offa + 30]; 6219 x2r = wk3i * x0r - wk3r * x0i; 6220 x2i = wk3i * x0i + wk3r * x0r; 6221 y11r = x1r + x2r; 6222 y11i = x1i + x2i; 6223 y15r = x1r - x2r; 6224 y15i = x1i - x2i; 6225 x1r = y0r + y2r; 6226 x1i = y0i + y2i; 6227 x2r = y1r + y3r; 6228 x2i = y1i + y3i; 6229 a[offa] = x1r + x2r; 6230 a[offa + 1] = x1i + x2i; 6231 a[offa + 2] = x1r - x2r; 6232 a[offa + 3] = x1i - x2i; 6233 x1r = y0r - y2r; 6234 x1i = y0i - y2i; 6235 x2r = y1r - y3r; 6236 x2i = y1i - y3i; 6237 a[offa + 4] = x1r - x2i; 6238 a[offa + 5] = x1i + x2r; 6239 a[offa + 6] = x1r + x2i; 6240 a[offa + 7] = x1i - x2r; 6241 x1r = y4r - y6i; 6242 x1i = y4i + y6r; 6243 x0r = y5r - y7i; 6244 x0i = y5i + y7r; 6245 x2r = wn4r * (x0r - x0i); 6246 x2i = wn4r * (x0i + x0r); 6247 a[offa + 8] = x1r + x2r; 6248 a[offa + 9] = x1i + x2i; 6249 a[offa + 10] = x1r - x2r; 6250 a[offa + 11] = x1i - x2i; 6251 x1r = y4r + y6i; 6252 x1i = y4i - y6r; 6253 x0r = y5r + y7i; 6254 x0i = y5i - y7r; 6255 x2r = wn4r * (x0r - x0i); 6256 x2i = wn4r * (x0i + x0r); 6257 a[offa + 12] = x1r - x2i; 6258 a[offa + 13] = x1i + x2r; 6259 a[offa + 14] = x1r + x2i; 6260 a[offa + 15] = x1i - x2r; 6261 x1r = y8r + y10r; 6262 x1i = y8i + y10i; 6263 x2r = y9r - y11r; 6264 x2i = y9i - y11i; 6265 a[offa + 16] = x1r + x2r; 6266 a[offa + 17] = x1i + x2i; 6267 a[offa + 18] = x1r - x2r; 6268 a[offa + 19] = x1i - x2i; 6269 x1r = y8r - y10r; 6270 x1i = y8i - y10i; 6271 x2r = y9r + y11r; 6272 x2i = y9i + y11i; 6273 a[offa + 20] = x1r - x2i; 6274 a[offa + 21] = x1i + x2r; 6275 a[offa + 22] = x1r + x2i; 6276 a[offa + 23] = x1i - x2r; 6277 x1r = y12r - y14i; 6278 x1i = y12i + y14r; 6279 x0r = y13r + y15i; 6280 x0i = y13i - y15r; 6281 x2r = wn4r * (x0r - x0i); 6282 x2i = wn4r * (x0i + x0r); 6283 a[offa + 24] = x1r + x2r; 6284 a[offa + 25] = x1i + x2i; 6285 a[offa + 26] = x1r - x2r; 6286 a[offa + 27] = x1i - x2i; 6287 x1r = y12r + y14i; 6288 x1i = y12i - y14r; 6289 x0r = y13r - y15i; 6290 x0i = y13i + y15r; 6291 x2r = wn4r * (x0r - x0i); 6292 x2i = wn4r * (x0i + x0r); 6293 a[offa + 28] = x1r - x2i; 6294 a[offa + 29] = x1i + x2r; 6295 a[offa + 30] = x1r + x2i; 6296 a[offa + 31] = x1i - x2r; 6297 } 6298 6299 private void cftf081(float[] a, int offa, float[] w, int startw) { 6300 float wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; 6301 6302 wn4r = w[startw + 1]; 6303 x0r = a[offa] + a[offa + 8]; 6304 x0i = a[offa + 1] + a[offa + 9]; 6305 x1r = a[offa] - a[offa + 8]; 6306 x1i = a[offa + 1] - a[offa + 9]; 6307 x2r = a[offa + 4] + a[offa + 12]; 6308 x2i = a[offa + 5] + a[offa + 13]; 6309 x3r = a[offa + 4] - a[offa + 12]; 6310 x3i = a[offa + 5] - a[offa + 13]; 6311 y0r = x0r + x2r; 6312 y0i = x0i + x2i; 6313 y2r = x0r - x2r; 6314 y2i = x0i - x2i; 6315 y1r = x1r - x3i; 6316 y1i = x1i + x3r; 6317 y3r = x1r + x3i; 6318 y3i = x1i - x3r; 6319 x0r = a[offa + 2] + a[offa + 10]; 6320 x0i = a[offa + 3] + a[offa + 11]; 6321 x1r = a[offa + 2] - a[offa + 10]; 6322 x1i = a[offa + 3] - a[offa + 11]; 6323 x2r = a[offa + 6] + a[offa + 14]; 6324 x2i = a[offa + 7] + a[offa + 15]; 6325 x3r = a[offa + 6] - a[offa + 14]; 6326 x3i = a[offa + 7] - a[offa + 15]; 6327 y4r = x0r + x2r; 6328 y4i = x0i + x2i; 6329 y6r = x0r - x2r; 6330 y6i = x0i - x2i; 6331 x0r = x1r - x3i; 6332 x0i = x1i + x3r; 6333 x2r = x1r + x3i; 6334 x2i = x1i - x3r; 6335 y5r = wn4r * (x0r - x0i); 6336 y5i = wn4r * (x0r + x0i); 6337 y7r = wn4r * (x2r - x2i); 6338 y7i = wn4r * (x2r + x2i); 6339 a[offa + 8] = y1r + y5r; 6340 a[offa + 9] = y1i + y5i; 6341 a[offa + 10] = y1r - y5r; 6342 a[offa + 11] = y1i - y5i; 6343 a[offa + 12] = y3r - y7i; 6344 a[offa + 13] = y3i + y7r; 6345 a[offa + 14] = y3r + y7i; 6346 a[offa + 15] = y3i - y7r; 6347 a[offa] = y0r + y4r; 6348 a[offa + 1] = y0i + y4i; 6349 a[offa + 2] = y0r - y4r; 6350 a[offa + 3] = y0i - y4i; 6351 a[offa + 4] = y2r - y6i; 6352 a[offa + 5] = y2i + y6r; 6353 a[offa + 6] = y2r + y6i; 6354 a[offa + 7] = y2i - y6r; 6355 } 6356 6357 private void cftf082(float[] a, int offa, float[] w, int startw) { 6358 float wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; 6359 6360 wn4r = w[startw + 1]; 6361 wk1r = w[startw + 2]; 6362 wk1i = w[startw + 3]; 6363 y0r = a[offa] - a[offa + 9]; 6364 y0i = a[offa + 1] + a[offa + 8]; 6365 y1r = a[offa] + a[offa + 9]; 6366 y1i = a[offa + 1] - a[offa + 8]; 6367 x0r = a[offa + 4] - a[offa + 13]; 6368 x0i = a[offa + 5] + a[offa + 12]; 6369 y2r = wn4r * (x0r - x0i); 6370 y2i = wn4r * (x0i + x0r); 6371 x0r = a[offa + 4] + a[offa + 13]; 6372 x0i = a[offa + 5] - a[offa + 12]; 6373 y3r = wn4r * (x0r - x0i); 6374 y3i = wn4r * (x0i + x0r); 6375 x0r = a[offa + 2] - a[offa + 11]; 6376 x0i = a[offa + 3] + a[offa + 10]; 6377 y4r = wk1r * x0r - wk1i * x0i; 6378 y4i = wk1r * x0i + wk1i * x0r; 6379 x0r = a[offa + 2] + a[offa + 11]; 6380 x0i = a[offa + 3] - a[offa + 10]; 6381 y5r = wk1i * x0r - wk1r * x0i; 6382 y5i = wk1i * x0i + wk1r * x0r; 6383 x0r = a[offa + 6] - a[offa + 15]; 6384 x0i = a[offa + 7] + a[offa + 14]; 6385 y6r = wk1i * x0r - wk1r * x0i; 6386 y6i = wk1i * x0i + wk1r * x0r; 6387 x0r = a[offa + 6] + a[offa + 15]; 6388 x0i = a[offa + 7] - a[offa + 14]; 6389 y7r = wk1r * x0r - wk1i * x0i; 6390 y7i = wk1r * x0i + wk1i * x0r; 6391 x0r = y0r + y2r; 6392 x0i = y0i + y2i; 6393 x1r = y4r + y6r; 6394 x1i = y4i + y6i; 6395 a[offa] = x0r + x1r; 6396 a[offa + 1] = x0i + x1i; 6397 a[offa + 2] = x0r - x1r; 6398 a[offa + 3] = x0i - x1i; 6399 x0r = y0r - y2r; 6400 x0i = y0i - y2i; 6401 x1r = y4r - y6r; 6402 x1i = y4i - y6i; 6403 a[offa + 4] = x0r - x1i; 6404 a[offa + 5] = x0i + x1r; 6405 a[offa + 6] = x0r + x1i; 6406 a[offa + 7] = x0i - x1r; 6407 x0r = y1r - y3i; 6408 x0i = y1i + y3r; 6409 x1r = y5r - y7r; 6410 x1i = y5i - y7i; 6411 a[offa + 8] = x0r + x1r; 6412 a[offa + 9] = x0i + x1i; 6413 a[offa + 10] = x0r - x1r; 6414 a[offa + 11] = x0i - x1i; 6415 x0r = y1r + y3i; 6416 x0i = y1i - y3r; 6417 x1r = y5r + y7r; 6418 x1i = y5i + y7i; 6419 a[offa + 12] = x0r - x1i; 6420 a[offa + 13] = x0i + x1r; 6421 a[offa + 14] = x0r + x1i; 6422 a[offa + 15] = x0i - x1r; 6423 } 6424 6425 private void cftf040(float[] a, int offa) { 6426 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; 6427 6428 x0r = a[offa] + a[offa + 4]; 6429 x0i = a[offa + 1] + a[offa + 5]; 6430 x1r = a[offa] - a[offa + 4]; 6431 x1i = a[offa + 1] - a[offa + 5]; 6432 x2r = a[offa + 2] + a[offa + 6]; 6433 x2i = a[offa + 3] + a[offa + 7]; 6434 x3r = a[offa + 2] - a[offa + 6]; 6435 x3i = a[offa + 3] - a[offa + 7]; 6436 a[offa] = x0r + x2r; 6437 a[offa + 1] = x0i + x2i; 6438 a[offa + 2] = x1r - x3i; 6439 a[offa + 3] = x1i + x3r; 6440 a[offa + 4] = x0r - x2r; 6441 a[offa + 5] = x0i - x2i; 6442 a[offa + 6] = x1r + x3i; 6443 a[offa + 7] = x1i - x3r; 6444 } 6445 6446 private void cftb040(float[] a, int offa) { 6447 float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; 6448 6449 x0r = a[offa] + a[offa + 4]; 6450 x0i = a[offa + 1] + a[offa + 5]; 6451 x1r = a[offa] - a[offa + 4]; 6452 x1i = a[offa + 1] - a[offa + 5]; 6453 x2r = a[offa + 2] + a[offa + 6]; 6454 x2i = a[offa + 3] + a[offa + 7]; 6455 x3r = a[offa + 2] - a[offa + 6]; 6456 x3i = a[offa + 3] - a[offa + 7]; 6457 a[offa] = x0r + x2r; 6458 a[offa + 1] = x0i + x2i; 6459 a[offa + 2] = x1r + x3i; 6460 a[offa + 3] = x1i - x3r; 6461 a[offa + 4] = x0r - x2r; 6462 a[offa + 5] = x0i - x2i; 6463 a[offa + 6] = x1r - x3i; 6464 a[offa + 7] = x1i + x3r; 6465 } 6466 6467 private void cftx020(float[] a, int offa) { 6468 float x0r, x0i; 6469 x0r = a[offa] - a[offa + 2]; 6470 x0i = -a[offa + 1] + a[offa + 3]; 6471 a[offa] += a[offa + 2]; 6472 a[offa + 1] += a[offa + 3]; 6473 a[offa + 2] = x0r; 6474 a[offa + 3] = x0i; 6475 } 6476 6477 private void cftxb020(float[] a, int offa) { 6478 float x0r, x0i; 6479 6480 x0r = a[offa] - a[offa + 2]; 6481 x0i = a[offa + 1] - a[offa + 3]; 6482 a[offa] += a[offa + 2]; 6483 a[offa + 1] += a[offa + 3]; 6484 a[offa + 2] = x0r; 6485 a[offa + 3] = x0i; 6486 } 6487 6488 private void cftxc020(float[] a, int offa) { 6489 float x0r, x0i; 6490 x0r = a[offa] - a[offa + 2]; 6491 x0i = a[offa + 1] + a[offa + 3]; 6492 a[offa] += a[offa + 2]; 6493 a[offa + 1] -= a[offa + 3]; 6494 a[offa + 2] = x0r; 6495 a[offa + 3] = x0i; 6496 } 6497 6498 private void rftfsub(int n, float[] a, int offa, int nc, float[] c, int startc) { 6499 int k, kk, ks, m; 6500 float wkr, wki, xr, xi, yr, yi; 6501 int idx1, idx2; 6502 6503 m = n >> 1; 6504 ks = 2 * nc / m; 6505 kk = 0; 6506 for (int j = 2; j < m; j += 2) { 6507 k = n - j; 6508 kk += ks; 6509 wkr = (float)(0.5 - c[startc + nc - kk]); 6510 wki = c[startc + kk]; 6511 idx1 = offa + j; 6512 idx2 = offa + k; 6513 xr = a[idx1] - a[idx2]; 6514 xi = a[idx1 + 1] + a[idx2 + 1]; 6515 yr = wkr * xr - wki * xi; 6516 yi = wkr * xi + wki * xr; 6517 a[idx1] -= yr; 6518 a[idx1 + 1] = yi - a[idx1 + 1]; 6519 a[idx2] += yr; 6520 a[idx2 + 1] = yi - a[idx2 + 1]; 6521 } 6522 a[offa + m + 1] = -a[offa + m + 1]; 6523 } 6524 6525 private void rftbsub(int n, float[] a, int offa, int nc, float[] c, int startc) { 6526 int k, kk, ks, m; 6527 float wkr, wki, xr, xi, yr, yi; 6528 int idx1, idx2; 6529 6530 m = n >> 1; 6531 ks = 2 * nc / m; 6532 kk = 0; 6533 for (int j = 2; j < m; j += 2) { 6534 k = n - j; 6535 kk += ks; 6536 wkr = (float)(0.5 - c[startc + nc - kk]); 6537 wki = c[startc + kk]; 6538 idx1 = offa + j; 6539 idx2 = offa + k; 6540 xr = a[idx1] - a[idx2]; 6541 xi = a[idx1 + 1] + a[idx2 + 1]; 6542 yr = wkr * xr - wki * xi; 6543 yi = wkr * xi + wki * xr; 6544 a[idx1] -= yr; 6545 a[idx1 + 1] -= yi; 6546 a[idx2] += yr; 6547 a[idx2 + 1] -= yi; 6548 } 6549 } 6550 6551 private void scale(final float m, final float[] a, int offa, boolean complex) { 6552 final float norm = (float)(1.0 / m); 6553 int n2; 6554 if (complex) { 6555 n2 = 2 * n; 6556 } else { 6557 n2 = n; 6558 } 6559 int nthreads = ConcurrencyUtils.getNumberOfThreads(); 6560 if ((nthreads > 1) && (n2 >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) { 6561 final int k = n2 / nthreads; 6562 Future<?>[] futures = new Future[nthreads]; 6563 for (int i = 0; i < nthreads; i++) { 6564 final int firstIdx = offa + i * k; 6565 final int lastIdx = (i == (nthreads - 1)) ? offa + n2 : firstIdx + k; 6566 futures[i] = ConcurrencyUtils.submit(new Runnable() { 6567 6568 public void run() { 6569 for (int i = firstIdx; i < lastIdx; i++) { 6570 a[i] *= norm; 6571 } 6572 } 6573 }); 6574 } 6575 ConcurrencyUtils.waitForCompletion(futures); 6576 } else { 6577 for (int i = offa; i < offa + n2; i++) { 6578 a[i] *= norm; 6579 } 6580 6581 } 6582 } 6583}