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