├── .gitignore ├── .settings └── org.eclipse.jdt.core.prefs ├── AndroidManifest.xml ├── README.md ├── libs └── android-support-v4.jar ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── values-v11 │ └── styles.xml ├── values-v14 │ └── styles.xml └── values │ ├── strings.xml │ └── styles.xml └── src └── vavi ├── sound └── pcm │ └── resampling │ └── ssrc │ └── SSRC.java └── util ├── I0Bessel.java └── SplitRadixFft.java /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | .DS_Store 18 | 19 | # Eclipse project files 20 | .classpath 21 | .project 22 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 3 | org.eclipse.jdt.core.compiler.compliance=1.6 4 | org.eclipse.jdt.core.compiler.source=1.6 5 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | android-pcm-resample 2 | ==================== 3 | 4 | Android resample library written in Java ported from JSSRC 5 | -------------------------------------------------------------------------------- /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simingweng/android-pcm-resample/8d80103d8af51d8979f3c40207bd9181c9dab840/libs/android-support-v4.jar -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | android.library=true 16 | -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simingweng/android-pcm-resample/8d80103d8af51d8979f3c40207bd9181c9dab840/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simingweng/android-pcm-resample/8d80103d8af51d8979f3c40207bd9181c9dab840/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simingweng/android-pcm-resample/8d80103d8af51d8979f3c40207bd9181c9dab840/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | AndroidJSSRC 4 | 5 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /src/vavi/sound/pcm/resampling/ssrc/SSRC.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This program(except FFT and Bessel function part) is distributed under 3 | * LGPL. See LGPL.txt for details. But, if you make a new program with derived 4 | * code from this program,I strongly wish that my name and derived code are 5 | * indicated explicitly. 6 | */ 7 | 8 | package vavi.sound.pcm.resampling.ssrc; 9 | 10 | import java.io.*; 11 | import java.nio.ByteBuffer; 12 | import java.nio.ByteOrder; 13 | import java.nio.channels.FileChannel; 14 | import java.util.Random; 15 | 16 | import vavi.util.I0Bessel; 17 | import vavi.util.SplitRadixFft; 18 | 19 | 20 | /** 21 | * Shibatch Sampling Rate Converter. 22 | * 23 | * @author Naoki Shibata 24 | * @author Naohide Sano (nsano) 25 | * @author Maksim Khadkevich (a couple of minor changes) 26 | * @version 0.00 060127 nsano port to java version
27 | */ 28 | public class SSRC { 29 | 30 | /** */ 31 | private ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN; 32 | 33 | /** */ 34 | private SplitRadixFft fft = new SplitRadixFft(); 35 | 36 | /** */ 37 | private static final String VERSION = "1.30"; 38 | 39 | /** */ 40 | private double AA = 170; 41 | 42 | /** */ 43 | private double DF = 100; 44 | 45 | /** */ 46 | private int FFTFIRLEN = 65536; 47 | 48 | /** */ 49 | // private static final int M = 15; 50 | 51 | /** */ 52 | private static final int RANDBUFLEN = 65536; 53 | 54 | /** */ 55 | private int RINT(double x) { 56 | return ((x) >= 0 ? ((int) ((x) + 0.5)) : ((int) ((x) - 0.5))); 57 | } 58 | 59 | /** */ 60 | private static final int scoeffreq[] = { 61 | 0, 48000, 44100, 37800, 32000, 22050, 48000, 44100 62 | }; 63 | 64 | /** */ 65 | private static final int scoeflen[] = { 66 | 1, 16, 20, 16, 16, 15, 16, 15 67 | }; 68 | 69 | /** */ 70 | private static final int samp[] = { 71 | 8, 18, 27, 8, 8, 8, 10, 9 72 | }; 73 | 74 | /** */ 75 | private static final double[][] shapercoefs = { 76 | {-1}, // triangular dither 77 | 78 | {-2.8720729351043701172, 5.0413231849670410156, -6.2442994117736816406, 5.8483986854553222656, 79 | -3.7067542076110839844, 1.0495119094848632812, 1.1830236911773681641, -2.1126792430877685547, 80 | 1.9094531536102294922, -0.99913084506988525391, 0.17090806365013122559, 0.32615602016448974609, 81 | -0.39127644896507263184, 0.26876461505889892578, -0.097676105797290802002, 0.023473845794796943665, 82 | }, // 48k, N=16, amp=18 83 | 84 | {-2.6773197650909423828, 4.8308925628662109375, -6.570110321044921875, 7.4572014808654785156, 85 | -6.7263274192810058594, 4.8481650352478027344, -2.0412089824676513672, -0.7006359100341796875, 86 | 2.9537565708160400391, -4.0800385475158691406, 4.1845216751098632812, -3.3311812877655029297, 87 | 2.1179926395416259766, -0.879302978515625, 0.031759146600961685181, 0.42382788658142089844, 88 | -0.47882103919982910156, 0.35490813851356506348, -0.17496839165687561035, 0.060908168554306030273, 89 | }, // 44.1k, N=20, amp=27 90 | 91 | {-1.6335992813110351562, 2.2615492343902587891, -2.4077029228210449219, 2.6341717243194580078, 92 | -2.1440362930297851562, 1.8153258562088012695, -1.0816224813461303711, 0.70302653312683105469, 93 | -0.15991993248462677002, -0.041549518704414367676, 0.29416576027870178223, -0.2518316805362701416, 94 | 0.27766478061676025391, -0.15785403549671173096, 0.10165894031524658203, -0.016833892092108726501, 95 | }, // 37.8k, N=16 96 | 97 | {-0.82901298999786376953, 0.98922657966613769531, -0.59825712442398071289, 1.0028809309005737305, 98 | -0.59938216209411621094, 0.79502451419830322266, -0.42723315954208374023, 0.54492527246475219727, 99 | -0.30792605876922607422, 0.36871799826622009277, -0.18792048096656799316, 0.2261127084493637085, 100 | -0.10573341697454452515, 0.11435490846633911133, -0.038800679147243499756, 0.040842197835445404053, 101 | }, // 32k, N=16 102 | 103 | {-0.065229974687099456787, 0.54981261491775512695, 0.40278548002243041992, 0.31783768534660339355, 104 | 0.28201797604560852051, 0.16985194385051727295, 0.15433363616466522217, 0.12507140636444091797, 105 | 0.08903945237398147583, 0.064410120248794555664, 0.047146003693342208862, 0.032805237919092178345, 106 | 0.028495194390416145325, 0.011695005930960178375, 0.011831838637590408325, 107 | }, // 22.05k, N=15 108 | 109 | {-2.3925774097442626953, 3.4350297451019287109, -3.1853709220886230469, 1.8117271661758422852, 110 | 0.20124770700931549072, -1.4759907722473144531, 1.7210904359817504883, -0.97746700048446655273, 111 | 0.13790138065814971924, 0.38185903429985046387, -0.27421241998672485352, -0.066584214568138122559, 112 | 0.35223302245140075684, -0.37672343850135803223, 0.23964276909828186035, -0.068674825131893157959, 113 | }, // 48k, N=16, amp=10 114 | 115 | {-2.0833916664123535156, 3.0418450832366943359, -3.2047898769378662109, 2.7571926116943359375, 116 | -1.4978630542755126953, 0.3427594602108001709, 0.71733748912811279297, -1.0737057924270629883, 117 | 1.0225815773010253906, -0.56649994850158691406, 0.20968692004680633545, 0.065378531813621520996, 118 | -0.10322438180446624756, 0.067442022264003753662, 0.00495197344571352005, 119 | }, // 44.1k, N=15, amp=9 120 | }; 121 | 122 | /** */ 123 | private double[][] shapebuf; 124 | 125 | /** */ 126 | private int shaper_type, shaper_len, shaper_clipmin, shaper_clipmax; 127 | 128 | /** */ 129 | private double[] randbuf; 130 | 131 | /** */ 132 | private int randptr; 133 | 134 | /** */ 135 | private boolean quiet = false; 136 | 137 | /** */ 138 | private int lastshowed2; 139 | 140 | /** */ 141 | private long starttime, lastshowed; 142 | 143 | /** */ 144 | private static final int POOLSIZE = 97; 145 | 146 | /** */ 147 | public int init_shaper(int freq, int nch, int min, int max, int dtype, int pdf, double noiseamp) { 148 | int i; 149 | int[] pool = new int[POOLSIZE]; 150 | 151 | for (i = 1; i < 6; i++) { 152 | if (freq == scoeffreq[i]) { 153 | break; 154 | } 155 | } 156 | if ((dtype == 3 || dtype == 4) && i == 6) { 157 | System.err.printf("Warning: ATH based noise shaping for destination frequency %dHz is not available, using triangular dither\n", freq); 158 | } 159 | if (dtype == 2 || i == 6) { 160 | i = 0; 161 | } 162 | if (dtype == 4 && (i == 1 || i == 2)) { 163 | i += 5; 164 | } 165 | 166 | shaper_type = i; 167 | 168 | shapebuf = new double[nch][]; 169 | shaper_len = scoeflen[shaper_type]; 170 | 171 | for (i = 0; i < nch; i++) { 172 | shapebuf[i] = new double[shaper_len]; 173 | } 174 | 175 | shaper_clipmin = min; 176 | shaper_clipmax = max; 177 | 178 | randbuf = new double[RANDBUFLEN]; 179 | 180 | Random random = new Random(System.currentTimeMillis()); 181 | for (i = 0; i < POOLSIZE; i++) { 182 | pool[i] = random.nextInt(); 183 | } 184 | 185 | switch (pdf) { 186 | case 0: // rectangular 187 | for (i = 0; i < RANDBUFLEN; i++) { 188 | int r, p; 189 | 190 | p = random.nextInt() % POOLSIZE; 191 | r = pool[p]; 192 | pool[p] = random.nextInt(); 193 | randbuf[i] = noiseamp * (((double) r) / Integer.MAX_VALUE - 0.5); 194 | } 195 | break; 196 | 197 | case 1: // triangular 198 | for (i = 0; i < RANDBUFLEN; i++) { 199 | int r1, r2, p; 200 | 201 | p = random.nextInt() % POOLSIZE; 202 | r1 = pool[p]; 203 | pool[p] = random.nextInt(); 204 | p = random.nextInt() % POOLSIZE; 205 | r2 = pool[p]; 206 | pool[p] = random.nextInt(); 207 | randbuf[i] = noiseamp * ((((double) r1) / Integer.MAX_VALUE) - (((double) r2) / Integer.MAX_VALUE)); 208 | } 209 | break; 210 | 211 | case 2: // gaussian 212 | { 213 | int sw = 0; 214 | double t = 0, u = 0; 215 | 216 | for (i = 0; i < RANDBUFLEN; i++) { 217 | double r; 218 | int p; 219 | 220 | if (sw == 0) { 221 | sw = 1; 222 | 223 | p = random.nextInt() % POOLSIZE; 224 | r = ((double) pool[p]) / Integer.MAX_VALUE; 225 | pool[p] = random.nextInt(); 226 | if (r == 1.0) { 227 | r = 0.0; 228 | } 229 | 230 | t = Math.sqrt(-2 * Math.log(1 - r)); 231 | 232 | p = random.nextInt() % POOLSIZE; 233 | r = ((double) pool[p]) / Integer.MAX_VALUE; 234 | pool[p] = random.nextInt(); 235 | 236 | u = 2 * Math.PI * r; 237 | 238 | randbuf[i] = noiseamp * t * Math.cos(u); 239 | } else { 240 | sw = 0; 241 | 242 | randbuf[i] = noiseamp * t * Math.sin(u); 243 | } 244 | } 245 | } 246 | break; 247 | } 248 | 249 | randptr = 0; 250 | 251 | if (dtype == 0 || dtype == 1) { 252 | return 1; 253 | } 254 | return samp[shaper_type]; 255 | } 256 | 257 | /** */ 258 | public int do_shaping(double s, double[] peak, int dtype, int ch) { 259 | double u, h; 260 | int i; 261 | 262 | if (dtype == 1) { 263 | s += randbuf[randptr++ & (RANDBUFLEN - 1)]; 264 | 265 | if (s < shaper_clipmin) { 266 | double d = s / shaper_clipmin; 267 | peak[0] = peak[0] < d ? d : peak[0]; 268 | s = shaper_clipmin; 269 | } 270 | if (s > shaper_clipmax) { 271 | double d = s / shaper_clipmax; 272 | peak[0] = peak[0] < d ? d : peak[0]; 273 | s = shaper_clipmax; 274 | } 275 | 276 | return RINT(s); 277 | } 278 | 279 | h = 0; 280 | for (i = 0; i < shaper_len; i++) { 281 | h += shapercoefs[shaper_type][i] * shapebuf[ch][i]; 282 | } 283 | s += h; 284 | u = s; 285 | s += randbuf[randptr++ & (RANDBUFLEN - 1)]; 286 | 287 | for (i = shaper_len - 2; i >= 0; i--) { 288 | shapebuf[ch][i + 1] = shapebuf[ch][i]; 289 | } 290 | 291 | if (s < shaper_clipmin) { 292 | double d = s / shaper_clipmin; 293 | peak[0] = peak[0] < d ? d : peak[0]; 294 | s = shaper_clipmin; 295 | shapebuf[ch][0] = s - u; 296 | 297 | if (shapebuf[ch][0] > 1) { 298 | shapebuf[ch][0] = 1; 299 | } 300 | if (shapebuf[ch][0] < -1) { 301 | shapebuf[ch][0] = -1; 302 | } 303 | } else if (s > shaper_clipmax) { 304 | double d = s / shaper_clipmax; 305 | peak[0] = peak[0] < d ? d : peak[0]; 306 | s = shaper_clipmax; 307 | shapebuf[ch][0] = s - u; 308 | 309 | if (shapebuf[ch][0] > 1) { 310 | shapebuf[ch][0] = 1; 311 | } 312 | if (shapebuf[ch][0] < -1) { 313 | shapebuf[ch][0] = -1; 314 | } 315 | } else { 316 | s = RINT(s); 317 | shapebuf[ch][0] = s - u; 318 | } 319 | 320 | return (int) s; 321 | } 322 | 323 | /** */ 324 | private void quit_shaper(int nch) { 325 | } 326 | 327 | /** */ 328 | private double alpha(double a) { 329 | if (a <= 21) { 330 | return 0; 331 | } 332 | if (a <= 50) { 333 | return 0.5842 * Math.pow(a - 21, 0.4) + 0.07886 * (a - 21); 334 | } 335 | return 0.1102 * (a - 8.7); 336 | } 337 | 338 | /** */ 339 | private double win(double n, int len, double alp, double iza) { 340 | return I0Bessel.value(alp * Math.sqrt(1 - 4 * n * n / (((double) len - 1) * ((double) len - 1)))) / iza; 341 | } 342 | 343 | /** */ 344 | private double sinc(double x) { 345 | return x == 0 ? 1 : Math.sin(x) / x; 346 | } 347 | 348 | /** */ 349 | private double hn_lpf(int n, double lpf, double fs) { 350 | double t = 1 / fs; 351 | double omega = 2 * Math.PI * lpf; 352 | return 2 * lpf * t * sinc(n * omega * t); 353 | } 354 | 355 | /** */ 356 | private void usage() { 357 | System.err.printf("http://shibatch.sourceforge.net/\n\n"); 358 | System.err.printf("usage: ssrc [] \n"); 359 | System.err.printf("options : --rate output sample rate\n"); 360 | System.err.printf(" --att attenuate signal\n"); 361 | System.err.printf(" --bits output quantization bit length\n"); 362 | System.err.printf(" --tmpfile specify temporal file\n"); 363 | System.err.printf(" --twopass two pass processing to avoid clipping\n"); 364 | System.err.printf(" --normalize normalize the wave file\n"); 365 | System.err.printf(" --quiet nothing displayed except error\n"); 366 | System.err.printf(" --dither [] dithering\n"); 367 | System.err.printf(" 0 : no dither\n"); 368 | System.err.printf(" 1 : no noise shaping\n"); 369 | System.err.printf(" 2 : triangular spectral shape\n"); 370 | System.err.printf(" 3 : ATH based noise shaping\n"); 371 | System.err.printf(" 4 : less dither amplitude than type 3\n"); 372 | System.err.printf(" --pdf [] select p.d.f. of noise\n"); 373 | System.err.printf(" 0 : rectangular\n"); 374 | System.err.printf(" 1 : triangular\n"); 375 | System.err.printf(" 2 : Gaussian\n"); 376 | System.err.printf(" --profile specify profile\n"); 377 | System.err.printf(" standard : the default quality\n"); 378 | System.err.printf(" fast : fast, not so bad quality\n"); 379 | } 380 | 381 | /** */ 382 | private void fmterr(int x) { 383 | throw new IllegalStateException("unknown error " + x); 384 | } 385 | 386 | /** */ 387 | private void setstarttime() { 388 | starttime = System.currentTimeMillis(); 389 | lastshowed = 0; 390 | lastshowed2 = -1; 391 | } 392 | 393 | /** */ 394 | private void showprogress(double p) { 395 | int eta, pc; 396 | long t; 397 | if (quiet) { 398 | return; 399 | } 400 | 401 | t = System.currentTimeMillis() - starttime; 402 | if (p == 0) { 403 | eta = 0; 404 | } else { 405 | eta = (int) (t * (1 - p) / p); 406 | } 407 | 408 | pc = (int) (p * 100); 409 | 410 | if (pc != lastshowed2 || t != lastshowed) { 411 | System.err.printf(" %3d%% processed", pc); 412 | lastshowed2 = pc; 413 | } 414 | if (t != lastshowed) { 415 | System.err.printf(", ETA =%4dmsec", eta); 416 | lastshowed = t; 417 | } 418 | System.err.printf("\r"); 419 | System.err.flush(); 420 | } 421 | 422 | /** */ 423 | private int gcd(int x, int y) { 424 | int t; 425 | 426 | while (y != 0) { 427 | t = x % y; 428 | x = y; 429 | y = t; 430 | } 431 | return x; 432 | } 433 | 434 | /** 435 | * @param fpi 436 | * @param fpo 437 | * @param nch 438 | * @param bps 439 | * @param dbps sizeof(double)? 440 | * @param sfrq 441 | * @param dfrq 442 | * @param gain 443 | * @param chanklen 444 | * @param twopass 445 | * @param dither 446 | * @return 447 | * @throws IOException 448 | */ 449 | public double upsample(InputStream fpi, OutputStream fpo, int nch, int bps, int dbps, int sfrq, int dfrq, double gain, int chanklen, boolean twopass, int dither) throws IOException { 450 | int frqgcd, osf = 0, fs1, fs2; 451 | double[][] stage1; 452 | double[] stage2; 453 | int n1, n1x, n1y, n2, n2b; 454 | int filter2len; 455 | int[] f1order, f1inc; 456 | int[] fft_ip = null; 457 | double[] fft_w = null; 458 | ByteBuffer rawinbuf, rawoutbuf; 459 | double[] inbuf, outbuf; 460 | double[][] buf1, buf2; 461 | double[] peak = new double[]{0}; 462 | int spcount = 0; 463 | int i, j; 464 | 465 | // System.err.println("upsample"); 466 | 467 | filter2len = FFTFIRLEN; // stage 2 filter length 468 | 469 | // Make stage 1 filter 470 | 471 | { 472 | double aa = AA; // stop band attenuation(dB) 473 | double lpf, d, df, alp, iza; 474 | // double delta; 475 | double guard = 2; 476 | 477 | frqgcd = gcd(sfrq, dfrq); 478 | 479 | fs1 = sfrq / frqgcd * dfrq; 480 | 481 | if (fs1 / dfrq == 1) { 482 | osf = 1; 483 | } else if (fs1 / dfrq % 2 == 0) { 484 | osf = 2; 485 | } else if (fs1 / dfrq % 3 == 0) { 486 | osf = 3; 487 | } else { 488 | throw new IllegalArgumentException( 489 | String.format("Resampling from %dHz to %dHz is not supported.\n" + 490 | "%d/gcd(%d,%d)=%d must be divided by 2 or 3.\n", 491 | sfrq, dfrq, sfrq, sfrq, dfrq, fs1 / dfrq)); 492 | } 493 | 494 | df = (dfrq * osf / 2 - sfrq / 2) * 2 / guard; 495 | lpf = sfrq / 2 + (dfrq * osf / 2 - sfrq / 2) / guard; 496 | 497 | // delta = Math.pow(10, -aa / 20); 498 | if (aa <= 21) { 499 | d = 0.9222; 500 | } else { 501 | d = (aa - 7.95) / 14.36; 502 | } 503 | 504 | n1 = (int) (fs1 / df * d + 1); 505 | if (n1 % 2 == 0) { 506 | n1++; 507 | } 508 | 509 | alp = alpha(aa); 510 | iza = I0Bessel.value(alp); 511 | // System.err.printf("iza = %g\n",iza); 512 | 513 | n1y = fs1 / sfrq; 514 | n1x = n1 / n1y + 1; 515 | 516 | f1order = new int[n1y * osf]; 517 | for (i = 0; i < n1y * osf; i++) { 518 | f1order[i] = fs1 / sfrq - (i * (fs1 / (dfrq * osf))) % (fs1 / sfrq); 519 | if (f1order[i] == fs1 / sfrq) { 520 | f1order[i] = 0; 521 | } 522 | } 523 | 524 | f1inc = new int[n1y * osf]; 525 | for (i = 0; i < n1y * osf; i++) { 526 | f1inc[i] = f1order[i] < fs1 / (dfrq * osf) ? nch : 0; 527 | if (f1order[i] == fs1 / sfrq) { 528 | f1order[i] = 0; 529 | } 530 | } 531 | 532 | stage1 = new double[n1y][n1x]; 533 | 534 | for (i = -(n1 / 2); i <= n1 / 2; i++) { 535 | stage1[(i + n1 / 2) % n1y][(i + n1 / 2) / n1y] = win(i, n1, alp, iza) * hn_lpf(i, lpf, fs1) * fs1 / sfrq; 536 | } 537 | } 538 | 539 | // Make stage 2 filter 540 | 541 | { 542 | double aa = AA; // stop band attenuation(dB) 543 | double lpf, d, df, alp, iza; 544 | // double delta; 545 | int ipsize, wsize; 546 | 547 | // delta = Math.pow(10, -aa / 20); 548 | if (aa <= 21) { 549 | d = 0.9222; 550 | } else { 551 | d = (aa - 7.95) / 14.36; 552 | } 553 | 554 | fs2 = dfrq * osf; 555 | 556 | for (i = 1; ; i = i * 2) { 557 | n2 = filter2len * i; 558 | if (n2 % 2 == 0) { 559 | n2--; 560 | } 561 | df = (fs2 * d) / (n2 - 1); 562 | lpf = sfrq / 2; 563 | if (df < DF) { 564 | break; 565 | } 566 | } 567 | 568 | alp = alpha(aa); 569 | 570 | iza = I0Bessel.value(alp); 571 | 572 | for (n2b = 1; n2b < n2; n2b *= 2) { 573 | } 574 | n2b *= 2; 575 | 576 | stage2 = new double[n2b]; 577 | 578 | for (i = -(n2 / 2); i <= n2 / 2; i++) { 579 | stage2[i + n2 / 2] = win(i, n2, alp, iza) * hn_lpf(i, lpf, fs2) / n2b * 2; 580 | } 581 | 582 | ipsize = (int) (2 + Math.sqrt(n2b)); 583 | fft_ip = new int[ipsize]; 584 | fft_ip[0] = 0; 585 | wsize = n2b / 2; 586 | fft_w = new double[wsize]; 587 | 588 | fft.rdft(n2b, 1, stage2, fft_ip, fft_w); 589 | } 590 | 591 | // Apply filters 592 | 593 | setstarttime(); 594 | 595 | { 596 | int n2b2 = n2b / 2; 597 | // inbuffs1Tv??? 598 | int rp; 599 | // disposesfrqTv? 600 | int ds; 601 | // ?t@Cinbuf?lvZ stage2 filternTv? 602 | int nsmplwrt1; 603 | // ?t@Cinbuf?lvZ stage2 filternTv? 604 | int nsmplwrt2 = 0; 605 | // stage1 filter?oTv?n1y*osf] 606 | int s1p; 607 | boolean init; 608 | boolean ending; 609 | int sumread, sumwrite; 610 | int osc; 611 | int ip, ip_backup; 612 | int s1p_backup, osc_backup; 613 | int ch, p; 614 | int inbuflen; 615 | int delay = 0; 616 | 617 | buf1 = new double[nch][n2b2 / osf + 1]; 618 | 619 | buf2 = new double[nch][n2b]; 620 | 621 | rawinbuf = ByteBuffer.allocate(nch * (n2b2 + n1x) * bps); // ,bps 622 | rawoutbuf = ByteBuffer.allocate(nch * (n2b2 / osf + 1) * dbps); // ,dbps 623 | 624 | inbuf = new double[nch * (n2b2 + n1x)]; 625 | outbuf = new double[nch * (n2b2 / osf + 1)]; 626 | 627 | s1p = 0; 628 | rp = 0; 629 | ds = 0; 630 | osc = 0; 631 | 632 | init = true; 633 | ending = false; 634 | inbuflen = n1 / 2 / (fs1 / sfrq) + 1; 635 | delay = (int) ((double) n2 / 2 / (fs2 / dfrq)); 636 | 637 | sumread = sumwrite = 0; 638 | 639 | while (true) { 640 | int nsmplread, toberead, toberead2; 641 | 642 | toberead2 = toberead = (int) (Math.floor((double) n2b2 * sfrq / (dfrq * osf)) + 1 + n1x - inbuflen); 643 | if (toberead + sumread > chanklen) { 644 | toberead = chanklen - sumread; 645 | } 646 | 647 | rawinbuf.position(0); 648 | rawinbuf.limit(Math.min(rawinbuf.limit(), bps * nch * toberead)); 649 | // rawinbuf.limit(bps * nch * toberead); 650 | 651 | byte[] tempData = new byte[rawinbuf.limit()]; 652 | nsmplread = fpi.read(tempData); 653 | if (nsmplread < 0) { 654 | nsmplread = 0; 655 | } 656 | 657 | if (nsmplread < rawinbuf.limit()) { 658 | chanklen = sumread + nsmplread / bps * nch; 659 | } 660 | 661 | rawinbuf.limit(nsmplread); 662 | rawinbuf = ByteBuffer.wrap(tempData); 663 | rawinbuf.position(nsmplread); 664 | 665 | rawinbuf.flip(); 666 | nsmplread /= bps * nch; 667 | 668 | switch (bps) { 669 | case 1: 670 | for (i = 0; i < nsmplread * nch; i++) 671 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7f) * ((double) rawinbuf.get(i) - 128); 672 | break; 673 | 674 | case 2: 675 | for (i = 0; i < nsmplread * nch; i++) { 676 | int v = rawinbuf.order(byteOrder).asShortBuffer().get(i); 677 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7fff) * v; 678 | } 679 | break; 680 | 681 | case 3: 682 | for (i = 0; i < nsmplread * nch; i++) { 683 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7fffff) * 684 | ((rawinbuf.get(i * 3) << 0) | 685 | (rawinbuf.get(i * 3 + 1) << 8) | 686 | (rawinbuf.get(i * 3 + 2) << 16)); 687 | } 688 | break; 689 | 690 | case 4: 691 | for (i = 0; i < nsmplread * nch; i++) { 692 | int v = rawinbuf.order(byteOrder).asIntBuffer().get(i); 693 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7fffffff) * v; 694 | } 695 | break; 696 | } 697 | 698 | for (; i < nch * toberead2; i++) { 699 | inbuf[nch * inbuflen + i] = 0; 700 | } 701 | 702 | inbuflen += toberead2; 703 | 704 | sumread += nsmplread; 705 | 706 | ending = sumread >= chanklen; 707 | // ending = fpi.available() == 0 || sumread >= chanklen; 708 | 709 | // nsmplwrt1 = ((rp - 1) * sfrq / fs1 + inbuflen - n1x) * dfrq * osf / sfrq; 710 | // if (nsmplwrt1 > n2b2) { nsmplwrt1 = n2b2; } 711 | nsmplwrt1 = n2b2; 712 | 713 | // apply stage 1 filter 714 | 715 | ip = ((sfrq * (rp - 1) + fs1) / fs1) * nch; // inbuf 716 | 717 | s1p_backup = s1p; 718 | ip_backup = ip; 719 | osc_backup = osc; 720 | 721 | for (ch = 0; ch < nch; ch++) { 722 | int op = ch; // outbuf 723 | // int fdo = fs1 / (dfrq * osf); 724 | int no = n1y * osf; 725 | 726 | s1p = s1p_backup; 727 | ip = ip_backup + ch; 728 | 729 | switch (n1x) { 730 | case 7: 731 | for (p = 0; p < nsmplwrt1; p++) { 732 | int s1o = f1order[s1p]; 733 | 734 | buf2[ch][p] = 735 | stage1[s1o][0] * inbuf[ip + 0 * nch] + 736 | stage1[s1o][1] * inbuf[ip + 1 * nch] + 737 | stage1[s1o][2] * inbuf[ip + 2 * nch] + 738 | stage1[s1o][3] * inbuf[ip + 3 * nch] + 739 | stage1[s1o][4] * inbuf[ip + 4 * nch] + 740 | stage1[s1o][5] * inbuf[ip + 5 * nch] + 741 | stage1[s1o][6] * inbuf[ip + 6 * nch]; 742 | 743 | ip += f1inc[s1p]; 744 | 745 | s1p++; 746 | if (s1p == no) { 747 | s1p = 0; 748 | } 749 | } 750 | break; 751 | 752 | case 9: 753 | for (p = 0; p < nsmplwrt1; p++) { 754 | int s1o = f1order[s1p]; 755 | 756 | buf2[ch][p] = 757 | stage1[s1o][0] * inbuf[ip + 0 * nch] + 758 | stage1[s1o][1] * inbuf[ip + 1 * nch] + 759 | stage1[s1o][2] * inbuf[ip + 2 * nch] + 760 | stage1[s1o][3] * inbuf[ip + 3 * nch] + 761 | stage1[s1o][4] * inbuf[ip + 4 * nch] + 762 | stage1[s1o][5] * inbuf[ip + 5 * nch] + 763 | stage1[s1o][6] * inbuf[ip + 6 * nch] + 764 | stage1[s1o][7] * inbuf[ip + 7 * nch] + 765 | stage1[s1o][8] * inbuf[ip + 8 * nch]; 766 | 767 | ip += f1inc[s1p]; 768 | 769 | s1p++; 770 | if (s1p == no) { 771 | s1p = 0; 772 | } 773 | } 774 | break; 775 | 776 | default: 777 | for (p = 0; p < nsmplwrt1; p++) { 778 | double tmp = 0; 779 | int ip2 = ip; 780 | 781 | int s1o = f1order[s1p]; 782 | 783 | for (i = 0; i < n1x; i++) { 784 | tmp += stage1[s1o][i] * inbuf[ip2]; 785 | ip2 += nch; 786 | } 787 | buf2[ch][p] = tmp; 788 | 789 | ip += f1inc[s1p]; 790 | 791 | s1p++; 792 | if (s1p == no) { 793 | s1p = 0; 794 | } 795 | } 796 | break; 797 | } 798 | 799 | osc = osc_backup; 800 | 801 | // apply stage 2 filter 802 | 803 | for (p = nsmplwrt1; p < n2b; p++) { 804 | buf2[ch][p] = 0; 805 | } 806 | 807 | //for(i=0;i 0 ? outbuf[i] : -outbuf[i]; 848 | peak[0] = peak[0] < f ? f : peak[0]; 849 | rawoutbuf.asDoubleBuffer().put(i, outbuf[i]); 850 | } 851 | } else { 852 | switch (dbps) { 853 | case 1: { 854 | double gain2 = gain * 0x7f; 855 | ch = 0; 856 | 857 | for (i = 0; i < nsmplwrt2 * nch; i++) { 858 | int s; 859 | 860 | if (dither != 0) { 861 | s = do_shaping(outbuf[i] * gain2, peak, dither, ch); 862 | } else { 863 | s = RINT(outbuf[i] * gain2); 864 | 865 | if (s < -0x80) { 866 | double d = (double) s / -0x80; 867 | peak[0] = peak[0] < d ? d : peak[0]; 868 | s = -0x80; 869 | } 870 | if (0x7f < s) { 871 | double d = (double) s / 0x7f; 872 | peak[0] = peak[0] < d ? d : peak[0]; 873 | s = 0x7f; 874 | } 875 | } 876 | 877 | rawoutbuf.put(i, (byte) (s + 0x80)); 878 | 879 | ch++; 880 | if (ch == nch) { 881 | ch = 0; 882 | } 883 | } 884 | } 885 | break; 886 | 887 | case 2: { 888 | double gain2 = gain * 0x7fff; 889 | ch = 0; 890 | 891 | for (i = 0; i < nsmplwrt2 * nch; i++) { 892 | int s; 893 | 894 | if (dither != 0) { 895 | s = do_shaping(outbuf[i] * gain2, peak, dither, ch); 896 | } else { 897 | s = RINT(outbuf[i] * gain2); 898 | 899 | if (s < -0x8000) { 900 | double d = (double) s / -0x8000; 901 | peak[0] = peak[0] < d ? d : peak[0]; 902 | s = -0x8000; 903 | } 904 | if (0x7fff < s) { 905 | double d = (double) s / 0x7fff; 906 | peak[0] = peak[0] < d ? d : peak[0]; 907 | s = 0x7fff; 908 | } 909 | } 910 | 911 | rawoutbuf.order(byteOrder).asShortBuffer().put(i, (short) s); 912 | 913 | ch++; 914 | if (ch == nch) { 915 | ch = 0; 916 | } 917 | } 918 | } 919 | break; 920 | 921 | case 3: { 922 | double gain2 = gain * 0x7fffff; 923 | ch = 0; 924 | 925 | for (i = 0; i < nsmplwrt2 * nch; i++) { 926 | int s; 927 | 928 | if (dither != 0) { 929 | s = do_shaping(outbuf[i] * gain2, peak, dither, ch); 930 | } else { 931 | s = RINT(outbuf[i] * gain2); 932 | 933 | if (s < -0x800000) { 934 | double d = (double) s / -0x800000; 935 | peak[0] = peak[0] < d ? d : peak[0]; 936 | s = -0x800000; 937 | } 938 | if (0x7fffff < s) { 939 | double d = (double) s / 0x7fffff; 940 | peak[0] = peak[0] < d ? d : peak[0]; 941 | s = 0x7fffff; 942 | } 943 | } 944 | 945 | rawoutbuf.put(i * 3, (byte) (s & 255)); 946 | s >>= 8; 947 | rawoutbuf.put(i * 3 + 1, (byte) (s & 255)); 948 | s >>= 8; 949 | rawoutbuf.put(i * 3 + 2, (byte) (s & 255)); 950 | 951 | ch++; 952 | if (ch == nch) { 953 | ch = 0; 954 | } 955 | } 956 | } 957 | break; 958 | 959 | } 960 | } 961 | 962 | if (!init) { 963 | if (ending) { 964 | if ((double) sumread * dfrq / sfrq + 2 > sumwrite + nsmplwrt2) { 965 | rawoutbuf.position(0); 966 | rawoutbuf.limit(dbps * nch * nsmplwrt2); 967 | writeBuffers(fpo, rawoutbuf); 968 | sumwrite += nsmplwrt2; 969 | } else { 970 | rawoutbuf.position(0); 971 | int limitData = (int) (dbps * nch * (Math.floor((double) sumread * dfrq / sfrq) + 2 - sumwrite)); 972 | if (limitData > 0) { 973 | rawoutbuf.limit(limitData); 974 | writeBuffers(fpo, rawoutbuf); 975 | } 976 | break; 977 | } 978 | } else { 979 | rawoutbuf.position(0); 980 | rawoutbuf.limit(dbps * nch * nsmplwrt2); 981 | writeBuffers(fpo, rawoutbuf); 982 | sumwrite += nsmplwrt2; 983 | } 984 | } else { 985 | 986 | if (nsmplwrt2 < delay) { 987 | delay -= nsmplwrt2; 988 | } else { 989 | if (ending) { 990 | if ((double) sumread * dfrq / sfrq + 2 > sumwrite + nsmplwrt2 - delay) { 991 | rawoutbuf.position(dbps * nch * delay); 992 | rawoutbuf.limit(dbps * nch * (nsmplwrt2 - delay)); 993 | writeBuffers(fpo, rawoutbuf); 994 | sumwrite += nsmplwrt2 - delay; 995 | } else { 996 | rawoutbuf.position(dbps * nch * delay); 997 | rawoutbuf.limit((int) (dbps * nch * (Math.floor((double) sumread * dfrq / sfrq) + 2 + sumwrite + nsmplwrt2 - delay))); 998 | writeBuffers(fpo, rawoutbuf); 999 | break; 1000 | } 1001 | } else { 1002 | rawoutbuf.position(dbps * nch * delay); 1003 | rawoutbuf.limit(dbps * nch * (nsmplwrt2)); 1004 | writeBuffers(fpo, rawoutbuf); 1005 | sumwrite += nsmplwrt2 - delay; 1006 | init = false; 1007 | } 1008 | } 1009 | } 1010 | 1011 | { 1012 | ds = (rp - 1) / (fs1 / sfrq); 1013 | 1014 | assert (inbuflen >= ds); 1015 | 1016 | System.arraycopy(inbuf, nch * ds, inbuf, 0, nch * (inbuflen - ds)); // memmove TODO overlap 1017 | inbuflen -= ds; 1018 | rp -= ds * (fs1 / sfrq); 1019 | } 1020 | 1021 | if ((spcount++ & 7) == 7) { 1022 | showprogress((double) sumread / chanklen); 1023 | } 1024 | } 1025 | } 1026 | 1027 | showprogress(1); 1028 | 1029 | return peak[0]; 1030 | } 1031 | 1032 | /** */ 1033 | public double downsample(InputStream fpi, OutputStream fpo, int nch, int bps, int dbps, int sfrq, int dfrq, double gain, int chanklen, boolean twopass, int dither) throws IOException { 1034 | int frqgcd, osf = 0, fs1, fs2; 1035 | double[] stage1; 1036 | double[][] stage2; 1037 | int n2, n2x, n2y, n1, n1b; 1038 | int filter1len; 1039 | int[] f2order, f2inc; 1040 | int[] fft_ip = null; 1041 | double[] fft_w = null; 1042 | ByteBuffer rawinbuf, rawoutbuf; 1043 | double[] inbuf, outbuf; 1044 | double[][] buf1, buf2; 1045 | int i, j; 1046 | int spcount = 0; 1047 | double[] peak = new double[]{0}; 1048 | 1049 | // System.err.println("downsample"); 1050 | 1051 | filter1len = FFTFIRLEN; // stage 1 filter length 1052 | 1053 | // Make stage 1 filter 1054 | 1055 | { 1056 | double aa = AA; // stop band attenuation(dB) 1057 | double lpf, d, df, alp, iza; 1058 | // double delta; 1059 | int ipsize, wsize; 1060 | 1061 | frqgcd = gcd(sfrq, dfrq); 1062 | 1063 | if (dfrq / frqgcd == 1) { 1064 | osf = 1; 1065 | } else if (dfrq / frqgcd % 2 == 0) { 1066 | osf = 2; 1067 | } else if (dfrq / frqgcd % 3 == 0) { 1068 | osf = 3; 1069 | } else { 1070 | throw new IllegalArgumentException( 1071 | String.format("Resampling from %dHz to %dHz is not supported.\n" + 1072 | "%d/gcd(%d,%d)=%d must be divided by 2 or 3.", 1073 | sfrq, dfrq, dfrq, sfrq, dfrq, dfrq / frqgcd)); 1074 | } 1075 | 1076 | fs1 = sfrq * osf; 1077 | 1078 | // delta = Math.pow(10, -aa / 20); 1079 | if (aa <= 21) { 1080 | d = 0.9222; 1081 | } else { 1082 | d = (aa - 7.95) / 14.36; 1083 | } 1084 | 1085 | n1 = filter1len; 1086 | for (i = 1; ; i = i * 2) { 1087 | n1 = filter1len * i; 1088 | if (n1 % 2 == 0) { 1089 | n1--; 1090 | } 1091 | df = (fs1 * d) / (n1 - 1); 1092 | lpf = (dfrq - df) / 2; 1093 | if (df < DF) { 1094 | break; 1095 | } 1096 | } 1097 | 1098 | alp = alpha(aa); 1099 | 1100 | iza = I0Bessel.value(alp); 1101 | //System.err.printf("iza %f, alp: %f\n", iza, alp); // OK 1102 | 1103 | for (n1b = 1; n1b < n1; n1b *= 2) { 1104 | } 1105 | n1b *= 2; 1106 | 1107 | stage1 = new double[n1b]; 1108 | 1109 | for (i = -(n1 / 2); i <= n1 / 2; i++) { 1110 | stage1[i + n1 / 2] = win(i, n1, alp, iza) * hn_lpf(i, lpf, fs1) * fs1 / sfrq / n1b * 2; 1111 | //System.err.printf("1: %06d: %e\n", i + n1 / 2, stage1[i + n1 / 2]); // OK 1112 | } 1113 | 1114 | ipsize = (int) (2 + Math.sqrt(n1b)); 1115 | fft_ip = new int[ipsize]; 1116 | fft_ip[0] = 0; 1117 | wsize = n1b / 2; 1118 | fft_w = new double[wsize]; 1119 | 1120 | fft.rdft(n1b, 1, stage1, fft_ip, fft_w); 1121 | //for (i = -(n1 / 2); i <= n1 / 2; i++) { 1122 | // System.err.printf("1': %06d: %e\n", i + n1 / 2, stage1[i + n1 / 2]); 1123 | //} 1124 | //for (i = 0; i < ipsize; i++) { 1125 | // System.err.printf("ip: %06d: %d\n", i, fft_ip[i]); // OK 1126 | //} 1127 | //for (i = 0; i < wsize; i++) { 1128 | // System.err.printf("w: %06d: %e\n", i, fft_w[i]); // OK 1129 | //} 1130 | } 1131 | 1132 | // Make stage 2 filter 1133 | 1134 | if (osf == 1) { 1135 | fs2 = sfrq / frqgcd * dfrq; 1136 | n2 = 1; 1137 | n2y = n2x = 1; 1138 | f2order = new int[n2y]; 1139 | f2order[0] = 0; 1140 | f2inc = new int[n2y]; 1141 | f2inc[0] = sfrq / dfrq; 1142 | stage2 = new double[n2y][n2x]; 1143 | stage2[0][0] = 1; 1144 | } else { 1145 | double aa = AA; // stop band attenuation(dB) 1146 | double lpf, d, df, alp, iza; 1147 | // double delta; 1148 | double guard = 2; 1149 | 1150 | fs2 = sfrq / frqgcd * dfrq; 1151 | 1152 | df = (fs1 / 2 - sfrq / 2) * 2 / guard; 1153 | lpf = sfrq / 2 + (fs1 / 2 - sfrq / 2) / guard; 1154 | 1155 | // delta = Math.pow(10, -aa / 20); 1156 | if (aa <= 21) { 1157 | d = 0.9222; 1158 | } else { 1159 | d = (aa - 7.95) / 14.36; 1160 | } 1161 | 1162 | n2 = (int) (fs2 / df * d + 1); 1163 | if (n2 % 2 == 0) { 1164 | n2++; 1165 | } 1166 | 1167 | alp = alpha(aa); 1168 | iza = I0Bessel.value(alp); 1169 | //System.err.printf("iza %f, alp: %f\n", iza, alp); // OK 1170 | 1171 | n2y = fs2 / fs1; // 0Tvfs2Tv?H 1172 | n2x = n2 / n2y + 1; 1173 | 1174 | f2order = new int[n2y]; 1175 | for (i = 0; i < n2y; i++) { 1176 | f2order[i] = fs2 / fs1 - (i * (fs2 / dfrq)) % (fs2 / fs1); 1177 | if (f2order[i] == fs2 / fs1) { 1178 | f2order[i] = 0; 1179 | } 1180 | } 1181 | 1182 | f2inc = new int[n2y]; 1183 | for (i = 0; i < n2y; i++) { 1184 | f2inc[i] = (fs2 / dfrq - f2order[i]) / (fs2 / fs1) + 1; 1185 | if (f2order[i + 1 == n2y ? 0 : i + 1] == 0) { 1186 | f2inc[i]--; 1187 | } 1188 | } 1189 | 1190 | stage2 = new double[n2y][n2x]; 1191 | 1192 | //System.err.printf("n2y: %d, n2: %d\n", n2y, n2); 1193 | for (i = -(n2 / 2); i <= n2 / 2; i++) { 1194 | stage2[(i + n2 / 2) % n2y][(i + n2 / 2) / n2y] = win(i, n2, alp, iza) * hn_lpf(i, lpf, fs2) * fs2 / fs1; 1195 | //System.err.printf(" stage2[%02d][%02d]: %f\n", (i + n2 / 2) % n2y, (i + n2 / 2) / n2y, win(i, n2, alp, iza) * hn_lpf(i, lpf, fs2) * fs2 / fs1); // OK 1196 | } 1197 | } 1198 | 1199 | // Apply filters 1200 | 1201 | setstarttime(); 1202 | 1203 | { 1204 | int n1b2 = n1b / 2; 1205 | int rp; // inbuffs1Tv??? 1206 | int rps; // rp(fs1/sfrq=osf)] 1207 | int rp2; // buf2fs2Tv??? 1208 | int ds; // disposesfrqTv? 1209 | // ?t@Cinbuf?lvZ stage2 filternTv? 1210 | // int nsmplwrt1; 1211 | // ?t@Cinbuf?lvZ stage2 filternTv? 1212 | int nsmplwrt2 = 0; 1213 | int s2p; // stage1 filter?oTv?n1y*osf] 1214 | boolean init, ending; 1215 | // int osc; 1216 | int bp; // rp2vZ?Dbuf2Tvu 1217 | int rps_backup, s2p_backup; 1218 | int k, ch, p; 1219 | int inbuflen = 0; 1220 | int sumread, sumwrite; 1221 | int delay = 0; 1222 | int op; 1223 | 1224 | // |....B....|....C....| buf1 n1b2+n1b2 1225 | // |.A.|....D....| buf2 n2x+n1b2 1226 | // 1227 | // inbufBosf{TvORs?[ 1228 | // CNA 1229 | // BCstage 1 filter 1230 | // DB 1231 | // ADstage 2 filter 1232 | // DA 1233 | // CDRs?[ 1234 | 1235 | buf1 = new double[nch][n1b]; //rawoutbuf = calloc(nch*(n2b2/osf+1),dbps); 1236 | 1237 | buf2 = new double[nch][n2x + 1 + n1b2]; 1238 | 1239 | rawinbuf = ByteBuffer.allocate((nch * (n1b2 / osf + osf + 1)) * bps); 1240 | //System.err.println((double) n1b2 * sfrq / dfrq + 1); 1241 | rawoutbuf = ByteBuffer.allocate((int) (((double) n1b2 * dfrq / sfrq + 1) * (dbps * nch))); 1242 | inbuf = new double[nch * (n1b2 / osf + osf + 1)]; 1243 | outbuf = new double[(int) (nch * ((double) n1b2 * dfrq / sfrq + 1))]; 1244 | 1245 | op = 0; // outbuf 1246 | 1247 | s2p = 0; 1248 | rp = 0; 1249 | rps = 0; 1250 | ds = 0; 1251 | // osc = 0; 1252 | rp2 = 0; 1253 | 1254 | init = true; 1255 | ending = false; 1256 | delay = (int) ((double) n1 / 2 / ((double) fs1 / dfrq) + (double) n2 / 2 / ((double) fs2 / dfrq)); 1257 | sumread = sumwrite = 0; 1258 | 1259 | while (true) { 1260 | int nsmplread; 1261 | int toberead; 1262 | rps = 0; //TODO settings this parameter to zero fixed a lot of problems 1263 | toberead = (n1b2 - rps - 1) / osf + 1; 1264 | if (toberead + sumread > chanklen) { 1265 | toberead = chanklen - sumread; 1266 | } 1267 | 1268 | rawinbuf.position(0); 1269 | rawinbuf.limit(bps * nch * toberead); 1270 | 1271 | byte[] tempData = new byte[rawinbuf.limit()]; 1272 | nsmplread = fpi.read(tempData); 1273 | if (nsmplread < 0) { 1274 | nsmplread = 0; 1275 | } 1276 | 1277 | //TODO sometimes happens, investigate around it 1278 | if (nsmplread < rawinbuf.limit()) { 1279 | chanklen = sumread + nsmplread / bps * nch; 1280 | } 1281 | 1282 | rawinbuf.limit(nsmplread); 1283 | rawinbuf = ByteBuffer.wrap(tempData); 1284 | rawinbuf.position(nsmplread); 1285 | 1286 | rawinbuf.flip(); 1287 | nsmplread /= bps * nch; 1288 | 1289 | switch (bps) { 1290 | case 1: 1291 | for (i = 0; i < nsmplread * nch; i++) { 1292 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7f) * ((rawinbuf.get(i) & 0xff) - 128); 1293 | } 1294 | break; 1295 | 1296 | case 2: 1297 | for (i = 0; i < nsmplread * nch; i++) { 1298 | int v = rawinbuf.order(byteOrder).asShortBuffer().get(i); 1299 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7fff) * v; 1300 | // System.err.printf("I: %f\n", inbuf[nch * inbuflen + i]); 1301 | } 1302 | break; 1303 | 1304 | case 3: 1305 | for (i = 0; i < nsmplread * nch; i++) { 1306 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7fffff) * 1307 | (((rawinbuf.get(i * 3) & 0xff) << 0) | 1308 | ((rawinbuf.get(i * 3 + 1) & 0xff) << 8) | 1309 | ((rawinbuf.get(i * 3 + 2) & 0xff) << 16)); 1310 | } 1311 | break; 1312 | 1313 | case 4: 1314 | for (i = 0; i < nsmplread * nch; i++) { 1315 | int v = rawinbuf.order(byteOrder).getInt(i); 1316 | inbuf[nch * inbuflen + i] = (1 / (double) 0x7fffffff) * v; 1317 | } 1318 | break; 1319 | } 1320 | 1321 | for (; i < nch * toberead; i++) { 1322 | inbuf[i] = 0; 1323 | } 1324 | 1325 | sumread += nsmplread; 1326 | 1327 | // ending = sumread >= chanklen; 1328 | ending = fpi.available() < 0 || sumread >= chanklen; 1329 | 1330 | 1331 | rps_backup = rps; 1332 | s2p_backup = s2p; 1333 | 1334 | for (ch = 0; ch < nch; ch++) { 1335 | rps = rps_backup; 1336 | 1337 | for (k = 0; k < rps; k++) { 1338 | buf1[ch][k] = 0; 1339 | } 1340 | 1341 | for (i = rps, j = 0; i < n1b2; i += osf, j++) { 1342 | assert (j < ((n1b2 - rps - 1) / osf + 1)); 1343 | 1344 | buf1[ch][i] = inbuf[j * nch + ch]; 1345 | 1346 | for (k = i + 1; k < i + osf; k++) { 1347 | buf1[ch][k] = 0; 1348 | } 1349 | } 1350 | 1351 | assert (j == ((n1b2 - rps - 1) / osf + 1)); 1352 | 1353 | for (k = n1b2; k < n1b; k++) { 1354 | buf1[ch][k] = 0; 1355 | } 1356 | 1357 | rps = i - n1b2; 1358 | rp += j; 1359 | 1360 | fft.rdft(n1b, 1, buf1[ch], fft_ip, fft_w); 1361 | 1362 | buf1[ch][0] = stage1[0] * buf1[ch][0]; 1363 | buf1[ch][1] = stage1[1] * buf1[ch][1]; 1364 | 1365 | for (i = 1; i < n1b2; i++) { 1366 | double re, im; 1367 | 1368 | re = stage1[i * 2] * buf1[ch][i * 2] - stage1[i * 2 + 1] * buf1[ch][i * 2 + 1]; 1369 | im = stage1[i * 2 + 1] * buf1[ch][i * 2] + stage1[i * 2] * buf1[ch][i * 2 + 1]; 1370 | 1371 | buf1[ch][i * 2] = re; 1372 | buf1[ch][i * 2 + 1] = im; 1373 | } 1374 | 1375 | fft.rdft(n1b, -1, buf1[ch], fft_ip, fft_w); 1376 | 1377 | for (i = 0; i < n1b2; i++) { 1378 | buf2[ch][n2x + 1 + i] += buf1[ch][i]; 1379 | } 1380 | 1381 | { 1382 | int t1 = rp2 / (fs2 / fs1); 1383 | if (rp2 % (fs2 / fs1) != 0) { 1384 | t1++; 1385 | } 1386 | 1387 | bp = buf2[0].length * ch + t1; // &(buf2[ch][t1]); 1388 | } 1389 | 1390 | s2p = s2p_backup; 1391 | 1392 | for (p = 0; bp - (buf2[0].length * ch) < n1b2 + 1; p++) { // buf2[ch] 1393 | double tmp = 0; 1394 | int bp2; 1395 | int s2o; 1396 | 1397 | bp2 = bp; 1398 | s2o = f2order[s2p]; 1399 | bp += f2inc[s2p]; 1400 | s2p++; 1401 | 1402 | if (s2p == n2y) { 1403 | s2p = 0; 1404 | } 1405 | 1406 | assert ((bp2 - (buf2[0].length * ch)) * (fs2 / fs1) - (rp2 + p * (fs2 / dfrq)) == s2o); // &(buf2[ch][0]) 1407 | for (i = 0; i < n2x; i++) { 1408 | //System.err.printf("%d (%d, %d)\n", i, bp2 / buf2[0].length, bp2 % buf2[0].length); 1409 | tmp += stage2[s2o][i] * buf2[bp2 / buf2[0].length][bp2 % buf2[0].length]; // *bp2++ 1410 | bp2++; 1411 | } 1412 | 1413 | outbuf[op + p * nch + ch] = tmp; 1414 | //System.err.printf("O: %06d: %f\n", op + p * nch + ch, tmp); 1415 | } 1416 | 1417 | nsmplwrt2 = p; 1418 | } 1419 | 1420 | rp2 += nsmplwrt2 * (fs2 / dfrq); 1421 | 1422 | rawoutbuf.clear(); 1423 | if (twopass) { 1424 | for (i = 0; i < nsmplwrt2 * nch; i++) { 1425 | double f = outbuf[i] > 0 ? outbuf[i] : -outbuf[i]; 1426 | peak[0] = peak[0] < f ? f : peak[0]; 1427 | //System.err.println("p: " + rawoutbuf.position() + ", l: " + rawoutbuf.limit()); 1428 | rawoutbuf.asDoubleBuffer().put(i, outbuf[i]); 1429 | //if (i < 100) { 1430 | // System.err.printf("1: %06d: %f\n", i, outbuf[i]); 1431 | //} 1432 | //System.err.print(StringUtil.getDump(rawoutbuf, i, 8)); 1433 | } 1434 | } else { 1435 | switch (dbps) { 1436 | case 1: { 1437 | double gain2 = gain * 0x7f; 1438 | ch = 0; 1439 | 1440 | for (i = 0; i < nsmplwrt2 * nch; i++) { 1441 | int s; 1442 | 1443 | if (dither != 0) { 1444 | s = do_shaping(outbuf[i] * gain2, peak, dither, ch); 1445 | } else { 1446 | s = RINT(outbuf[i] * gain2); 1447 | 1448 | if (s < -0x80) { 1449 | double d = (double) s / -0x80; 1450 | peak[0] = peak[0] < d ? d : peak[0]; 1451 | s = -0x80; 1452 | } 1453 | if (0x7f < s) { 1454 | double d = (double) s / 0x7f; 1455 | peak[0] = peak[0] < d ? d : peak[0]; 1456 | s = 0x7f; 1457 | } 1458 | } 1459 | 1460 | rawoutbuf.put(i, (byte) (s + 0x80)); 1461 | 1462 | ch++; 1463 | if (ch == nch) { 1464 | ch = 0; 1465 | } 1466 | } 1467 | } 1468 | break; 1469 | 1470 | case 2: { 1471 | double gain2 = gain * 0x7fff; 1472 | ch = 0; 1473 | 1474 | for (i = 0; i < nsmplwrt2 * nch; i++) { 1475 | int s; 1476 | 1477 | if (dither != 0) { 1478 | s = do_shaping(outbuf[i] * gain2, peak, dither, ch); 1479 | } else { 1480 | s = RINT(outbuf[i] * gain2); 1481 | 1482 | if (s < -0x8000) { 1483 | double d = (double) s / -0x8000; 1484 | peak[0] = peak[0] < d ? d : peak[0]; 1485 | s = -0x8000; 1486 | } 1487 | if (0x7fff < s) { 1488 | double d = (double) s / 0x7fff; 1489 | peak[0] = peak[0] < d ? d : peak[0]; 1490 | s = 0x7fff; 1491 | } 1492 | } 1493 | 1494 | rawoutbuf.order(byteOrder).asShortBuffer().put(i, (short) s); 1495 | 1496 | ch++; 1497 | if (ch == nch) { 1498 | ch = 0; 1499 | } 1500 | } 1501 | } 1502 | break; 1503 | 1504 | case 3: { 1505 | double gain2 = gain * 0x7fffff; 1506 | ch = 0; 1507 | 1508 | for (i = 0; i < nsmplwrt2 * nch; i++) { 1509 | int s; 1510 | 1511 | if (dither != 0) { 1512 | s = do_shaping(outbuf[i] * gain2, peak, dither, ch); 1513 | } else { 1514 | s = RINT(outbuf[i] * gain2); 1515 | 1516 | if (s < -0x800000) { 1517 | double d = (double) s / -0x800000; 1518 | peak[0] = peak[0] < d ? d : peak[0]; 1519 | s = -0x800000; 1520 | } 1521 | if (0x7fffff < s) { 1522 | double d = (double) s / 0x7fffff; 1523 | peak[0] = peak[0] < d ? d : peak[0]; 1524 | s = 0x7fffff; 1525 | } 1526 | } 1527 | 1528 | rawoutbuf.put(i * 3, (byte) (s & 255)); 1529 | s >>= 8; 1530 | rawoutbuf.put(i * 3 + 1, (byte) (s & 255)); 1531 | s >>= 8; 1532 | rawoutbuf.put(i * 3 + 2, (byte) (s & 255)); 1533 | 1534 | ch++; 1535 | if (ch == nch) { 1536 | ch = 0; 1537 | } 1538 | } 1539 | } 1540 | break; 1541 | 1542 | } 1543 | } 1544 | 1545 | if (!init) { 1546 | if (ending) { 1547 | if ((double) sumread * dfrq / sfrq + 2 > sumwrite + nsmplwrt2) { 1548 | rawoutbuf.position(0); 1549 | rawoutbuf.limit(dbps * nch * nsmplwrt2); 1550 | writeBuffers(fpo, rawoutbuf); 1551 | sumwrite += nsmplwrt2; 1552 | } else { 1553 | rawoutbuf.position(0); 1554 | int limitData = (int) (dbps * nch * (Math.floor((double) sumread * dfrq / sfrq) + 2 - sumwrite)); 1555 | if (limitData > 0) { 1556 | rawoutbuf.limit(limitData); 1557 | writeBuffers(fpo, rawoutbuf); 1558 | } 1559 | break; 1560 | } 1561 | } else { 1562 | rawoutbuf.position(0); 1563 | rawoutbuf.limit(dbps * nch * nsmplwrt2); 1564 | writeBuffers(fpo, rawoutbuf); 1565 | sumwrite += nsmplwrt2; 1566 | } 1567 | } else { 1568 | if (nsmplwrt2 < delay) { 1569 | delay -= nsmplwrt2; 1570 | } else { 1571 | if (ending) { 1572 | if ((double) sumread * dfrq / sfrq + 2 > sumwrite + nsmplwrt2 - delay) { 1573 | rawoutbuf.position(dbps * nch * delay); 1574 | rawoutbuf.limit(dbps * nch * (nsmplwrt2 - delay)); 1575 | writeBuffers(fpo, rawoutbuf); 1576 | sumwrite += nsmplwrt2 - delay; 1577 | } else { 1578 | rawoutbuf.position(dbps * nch * delay); 1579 | rawoutbuf.limit((int) (dbps * nch * (Math.floor((double) sumread * dfrq / sfrq) + 2 + sumwrite + nsmplwrt2 - delay))); //TODO fails with short signals (think that fixed this) 1580 | writeBuffers(fpo, rawoutbuf); 1581 | break; 1582 | } 1583 | } else { 1584 | rawoutbuf.position(dbps * nch * delay); 1585 | rawoutbuf.limit(dbps * nch * (nsmplwrt2)); 1586 | writeBuffers(fpo, rawoutbuf); 1587 | sumwrite += nsmplwrt2 - delay; 1588 | init = false; 1589 | } 1590 | } 1591 | } 1592 | 1593 | { 1594 | ds = (rp2 - 1) / (fs2 / fs1); 1595 | 1596 | if (ds > n1b2) { 1597 | ds = n1b2; 1598 | } 1599 | 1600 | for (ch = 0; ch < nch; ch++) { 1601 | System.arraycopy(buf2[ch], ds, buf2[ch], 0, n2x + 1 + n1b2 - ds); // memmove TODO overlap 1602 | } 1603 | 1604 | rp2 -= ds * (fs2 / fs1); 1605 | } 1606 | 1607 | for (ch = 0; ch < nch; ch++) { 1608 | System.arraycopy(buf1[ch], n1b2, buf2[ch], n2x + 1, n1b2); 1609 | } 1610 | 1611 | if ((spcount++ & 7) == 7) { 1612 | showprogress((double) sumread / chanklen); 1613 | } 1614 | } 1615 | } 1616 | 1617 | showprogress(1); 1618 | 1619 | return peak[0]; 1620 | } 1621 | 1622 | /** */ 1623 | public double no_src(InputStream fpi, OutputStream fpo, int nch, int bps, int dbps, double gain, int chanklen, boolean twopass, int dither) throws IOException { 1624 | double[] peak = new double[]{ 1625 | 0 1626 | }; 1627 | int ch = 0, sumread = 0; 1628 | 1629 | setstarttime(); 1630 | 1631 | ByteBuffer leos = null; 1632 | if (twopass) { 1633 | leos = ByteBuffer.allocate(8); 1634 | } 1635 | 1636 | ByteBuffer buf = ByteBuffer.allocate(4); 1637 | while (sumread < chanklen * nch) { 1638 | double f = 0; 1639 | int s; 1640 | 1641 | switch (bps) { 1642 | case 1: 1643 | buf.position(0); 1644 | buf.limit(1); 1645 | 1646 | byte[] tempData = new byte[buf.limit()]; 1647 | fpi.read(tempData); 1648 | buf = ByteBuffer.wrap(tempData); 1649 | buf.position(buf.limit()); 1650 | 1651 | 1652 | buf.flip(); 1653 | f = (1 / (double) 0x7f) * (buf.get(0) - 128); 1654 | break; 1655 | case 2: 1656 | buf.position(0); 1657 | buf.limit(2); 1658 | 1659 | tempData = new byte[buf.limit()]; 1660 | fpi.read(tempData); 1661 | buf = ByteBuffer.wrap(tempData); 1662 | buf.position(buf.limit()); 1663 | 1664 | buf.flip(); 1665 | s = buf.order(byteOrder).asShortBuffer().get(0); 1666 | f = (1 / (double) 0x7fff) * s; 1667 | break; 1668 | case 3: 1669 | buf.position(0); 1670 | buf.limit(3); 1671 | 1672 | tempData = new byte[buf.limit()]; 1673 | fpi.read(tempData); 1674 | buf = ByteBuffer.wrap(tempData); 1675 | buf.position(buf.limit()); 1676 | 1677 | buf.flip(); 1678 | f = (1 / (double) 0x7fffff) * 1679 | (((buf.get(0) & 0xff) << 0) | 1680 | ((buf.get(1) & 0xff) << 8) | 1681 | ((buf.get(2) & 0xff) << 16)); 1682 | break; 1683 | case 4: 1684 | buf.position(0); 1685 | buf.limit(4); 1686 | 1687 | tempData = new byte[buf.limit()]; 1688 | fpi.read(tempData); 1689 | buf = ByteBuffer.wrap(tempData); 1690 | buf.position(buf.limit()); 1691 | 1692 | buf.flip(); 1693 | s = buf.order(byteOrder).asIntBuffer().get(0); 1694 | f = (1 / (double) 0x7fffffff) * s; 1695 | break; 1696 | } 1697 | ; 1698 | 1699 | if (fpi.available() == 0) { 1700 | // if (fpi.position() == fpi.size()) { 1701 | break; 1702 | } 1703 | f *= gain; 1704 | 1705 | if (!twopass) { 1706 | switch (dbps) { 1707 | case 1: 1708 | f *= 0x7f; 1709 | s = dither != 0 ? do_shaping(f, peak, dither, ch) : RINT(f); 1710 | buf.position(0); 1711 | buf.limit(1); 1712 | buf.put(0, (byte) (s + 128)); 1713 | buf.flip(); 1714 | writeBuffers(fpo, buf); 1715 | break; 1716 | case 2: 1717 | f *= 0x7fff; 1718 | s = dither != 0 ? do_shaping(f, peak, dither, ch) : RINT(f); 1719 | buf.position(0); 1720 | buf.limit(2); 1721 | buf.asShortBuffer().put(0, (short) s); 1722 | buf.flip(); 1723 | writeBuffers(fpo, buf); 1724 | break; 1725 | case 3: 1726 | f *= 0x7fffff; 1727 | s = dither != 0 ? do_shaping(f, peak, dither, ch) : RINT(f); 1728 | buf.position(0); 1729 | buf.limit(3); 1730 | buf.put(0, (byte) (s & 255)); 1731 | s >>= 8; 1732 | buf.put(1, (byte) (s & 255)); 1733 | s >>= 8; 1734 | buf.put(2, (byte) (s & 255)); 1735 | buf.flip(); 1736 | writeBuffers(fpo, buf); 1737 | break; 1738 | } 1739 | } else { 1740 | double p = f > 0 ? f : -f; 1741 | peak[0] = peak[0] < p ? p : peak[0]; 1742 | leos.position(0); 1743 | leos.putDouble(f); 1744 | leos.flip(); 1745 | writeBuffers(fpo, leos); 1746 | } 1747 | 1748 | ch++; 1749 | if (ch == nch) { 1750 | ch = 0; 1751 | } 1752 | sumread++; 1753 | 1754 | if ((sumread & 0x3ffff) == 0) { 1755 | showprogress((double) sumread / (chanklen * nch)); 1756 | } 1757 | } 1758 | 1759 | showprogress(1); 1760 | 1761 | return peak[0]; 1762 | } 1763 | 1764 | /** */ 1765 | public static void main(String[] args) throws Exception { 1766 | new SSRC(args); 1767 | } 1768 | 1769 | /** */ 1770 | private static final double presets[] = { 1771 | 0.7, 0.9, 0.18 1772 | }; 1773 | 1774 | public SSRC(){} 1775 | 1776 | /** */ 1777 | SSRC(String[] argv) throws IOException { 1778 | String sfn, dfn, tmpfn = null; 1779 | FileInputStream fpi = null; 1780 | File fo = null; 1781 | FileOutputStream fpo = null; 1782 | File ft = null; 1783 | FileOutputStream fpto = null; 1784 | boolean twopass, normalize; 1785 | int dither, pdf, samp = 0; 1786 | int nch, bps; 1787 | int length; 1788 | int sfrq, dfrq, dbps; 1789 | double att, noiseamp; 1790 | double[] peak = new double[]{0}; 1791 | int i; 1792 | 1793 | // parse command line options 1794 | 1795 | dfrq = -1; 1796 | att = 0; 1797 | dbps = -1; 1798 | twopass = false; 1799 | normalize = false; 1800 | dither = 0; 1801 | pdf = 0; 1802 | noiseamp = 0.18; 1803 | 1804 | for (i = 0; i < argv.length; i++) { 1805 | if (argv[i].charAt(0) != '-') { 1806 | break; 1807 | } 1808 | 1809 | if (argv[i].equals("--rate")) { 1810 | dfrq = Integer.parseInt(argv[++i]); 1811 | //System.err.printf("dfrq: %d\n", dfrq); 1812 | continue; 1813 | } 1814 | 1815 | if (argv[i].equals("--att")) { 1816 | att = Float.parseFloat(argv[++i]); 1817 | continue; 1818 | } 1819 | 1820 | if (argv[i].equals("--bits")) { 1821 | dbps = Integer.parseInt(argv[++i]); 1822 | if (dbps != 8 && dbps != 16 && dbps != 24) { 1823 | throw new IllegalArgumentException("Error: Only 8bit, 16bit and 24bit PCM are supported."); 1824 | } 1825 | dbps /= 8; 1826 | continue; 1827 | } 1828 | 1829 | if (argv[i].equals("--twopass")) { 1830 | twopass = true; 1831 | continue; 1832 | } 1833 | 1834 | if (argv[i].equals("--normalize")) { 1835 | twopass = true; 1836 | normalize = true; 1837 | continue; 1838 | } 1839 | 1840 | if (argv[i].equals("--dither")) { 1841 | try { 1842 | dither = Integer.parseInt(argv[i + 1]); 1843 | if (dither < 0 || dither > 4) { 1844 | throw new IllegalArgumentException("unrecognized dither type : " + argv[i + 1]); 1845 | } 1846 | i++; 1847 | } catch (NumberFormatException e) { 1848 | dither = -1; 1849 | } 1850 | continue; 1851 | } 1852 | 1853 | if (argv[i].equals("--pdf")) { 1854 | try { 1855 | pdf = Integer.parseInt(argv[i + 1]); 1856 | if (pdf < 0 || pdf > 2) { 1857 | throw new IllegalArgumentException("unrecognized p.d.f. type : " + argv[i + 1]); 1858 | } 1859 | i++; 1860 | } catch (NumberFormatException e) { 1861 | throw new IllegalArgumentException("unrecognized p.d.f. type : " + argv[i + 1]); 1862 | } 1863 | 1864 | try { 1865 | noiseamp = Double.parseDouble(argv[i + 1]); 1866 | i++; 1867 | } catch (NumberFormatException e) { 1868 | noiseamp = presets[pdf]; 1869 | } 1870 | 1871 | continue; 1872 | } 1873 | 1874 | if (argv[i].equals("--quiet")) { 1875 | quiet = true; 1876 | continue; 1877 | } 1878 | 1879 | if (argv[i].equals("--tmpfile")) { 1880 | tmpfn = argv[++i]; 1881 | continue; 1882 | } 1883 | 1884 | if (argv[i].equals("--profile")) { 1885 | if (argv[i + 1].equals("fast")) { 1886 | AA = 96; 1887 | DF = 8000; 1888 | FFTFIRLEN = 1024; 1889 | } else if (argv[i + 1].equals("standard")) { 1890 | /* nothing to do */ 1891 | } else { 1892 | throw new IllegalArgumentException("unrecognized profile : " + argv[i + 1]); 1893 | } 1894 | i++; 1895 | continue; 1896 | } 1897 | 1898 | throw new IllegalArgumentException("unrecognized option : " + argv[i]); 1899 | } 1900 | 1901 | if (!quiet) { 1902 | System.err.printf("Shibatch sampling rate converter version " + VERSION + "(high precision/nio)\n\n"); 1903 | } 1904 | 1905 | if (argv.length - i != 2) { 1906 | usage(); 1907 | throw new IllegalStateException("too few arguments"); 1908 | } 1909 | 1910 | sfn = argv[i]; 1911 | dfn = argv[i + 1]; 1912 | 1913 | try { 1914 | fpi = new FileInputStream(sfn); 1915 | } catch (IOException e) { 1916 | throw new IllegalArgumentException("cannot open input file."); 1917 | } 1918 | 1919 | // read wav header 1920 | 1921 | { 1922 | @SuppressWarnings("unused") 1923 | short word; 1924 | @SuppressWarnings("unused") 1925 | int dword; 1926 | 1927 | ByteBuffer bb = ByteBuffer.allocate(256).order(ByteOrder.LITTLE_ENDIAN); 1928 | bb.limit(36); 1929 | fpi.getChannel().read(bb); 1930 | bb.flip(); 1931 | System.err.println("p: " + bb.position() + ", l: " + bb.limit()); 1932 | if (bb.get() != 'R') fmterr(1); 1933 | if (bb.get() != 'I') fmterr(1); 1934 | if (bb.get() != 'F') fmterr(1); 1935 | if (bb.get() != 'F') fmterr(1); 1936 | 1937 | dword = bb.getInt(); 1938 | 1939 | if (bb.get() != 'W') fmterr(2); 1940 | if (bb.get() != 'A') fmterr(2); 1941 | if (bb.get() != 'V') fmterr(2); 1942 | if (bb.get() != 'E') fmterr(2); 1943 | if (bb.get() != 'f') fmterr(2); 1944 | if (bb.get() != 'm') fmterr(2); 1945 | if (bb.get() != 't') fmterr(2); 1946 | if (bb.get() != ' ') fmterr(2); 1947 | 1948 | int sizeOfFmt = bb.getInt(); 1949 | 1950 | if (bb.getShort() != 1) { 1951 | throw new IllegalStateException("Error: Only PCM is supported."); 1952 | } 1953 | nch = bb.getShort(); 1954 | sfrq = bb.getInt(); 1955 | bps = bb.getInt(); 1956 | if (bps % sfrq * nch != 0) { 1957 | fmterr(4); 1958 | } 1959 | 1960 | word = bb.getShort(); 1961 | word = bb.getShort(); 1962 | 1963 | bps /= sfrq * nch; 1964 | 1965 | if (sizeOfFmt > 16) { 1966 | bb.position(0); 1967 | bb.limit(2); 1968 | fpi.read(getDataFromByteBuffer(bb)); 1969 | bb.flip(); 1970 | int sizeofExtended = bb.getShort(); 1971 | fpi.getChannel().position(fpi.getChannel().position() + sizeofExtended); 1972 | } 1973 | 1974 | while (true) { 1975 | bb.position(0); 1976 | bb.limit(8); 1977 | fpi.getChannel().read(bb); 1978 | bb.flip(); 1979 | int c0 = bb.get(); 1980 | int c1 = bb.get(); 1981 | int c2 = bb.get(); 1982 | int c3 = bb.get(); 1983 | length = bb.getInt(); 1984 | System.err.printf("chunk: %c%c%c%c\n", c0, c1, c2, c3); 1985 | if (c0 == 'd' && c1 == 'a' && c2 == 't' && c3 == 'a') { 1986 | break; 1987 | } 1988 | if (fpi.getChannel().position() == fpi.getChannel().size()) { 1989 | break; 1990 | } 1991 | fpi.getChannel().position(fpi.getChannel().position() + length); 1992 | } 1993 | if (fpi.getChannel().position() == fpi.getChannel().size()) { 1994 | throw new IllegalStateException("Couldn't find data chank"); 1995 | } 1996 | } 1997 | 1998 | if (bps != 1 && bps != 2 && bps != 3 && bps != 4) { 1999 | throw new IllegalStateException("Error : Only 8bit, 16bit, 24bit and 32bit PCM are supported."); 2000 | } 2001 | 2002 | if (dbps == -1) { 2003 | if (bps != 1) { 2004 | dbps = bps; 2005 | } else { 2006 | dbps = 2; 2007 | } 2008 | if (dbps == 4) { 2009 | dbps = 3; 2010 | } 2011 | } 2012 | 2013 | if (dfrq == -1) { 2014 | dfrq = sfrq; 2015 | } 2016 | 2017 | if (dither == -1) { 2018 | if (dbps < bps) { 2019 | if (dbps == 1) { 2020 | dither = 4; 2021 | } else { 2022 | dither = 3; 2023 | } 2024 | } else { 2025 | dither = 1; 2026 | } 2027 | } 2028 | 2029 | if (!quiet) { 2030 | final String[] dtype = { 2031 | "none", "no noise shaping", "triangular spectral shape", "ATH based noise shaping", "ATH based noise shaping(less amplitude)" 2032 | }; 2033 | final String[] ptype = { 2034 | "rectangular", "triangular", "gaussian" 2035 | }; 2036 | System.err.printf("frequency : %d -> %d\n", sfrq, dfrq); 2037 | System.err.printf("attenuation : %gdB\n", att); 2038 | System.err.printf("bits per sample : %d -> %d\n", bps * 8, dbps * 8); 2039 | System.err.printf("nchannels : %d\n", nch); 2040 | System.err.printf("length : %d bytes, %g secs\n", length, (double) length / bps / nch / sfrq); 2041 | if (dither == 0) { 2042 | System.err.printf("dither type : none\n"); 2043 | } else { 2044 | System.err.printf("dither type : %s, %s p.d.f, amp = %g\n", dtype[dither], ptype[pdf], noiseamp); 2045 | } 2046 | System.err.printf("\n"); 2047 | } 2048 | 2049 | if (twopass) { 2050 | } 2051 | 2052 | try { 2053 | fo = new File(dfn); 2054 | fpo = new FileOutputStream(fo); 2055 | } catch (IOException e) { 2056 | throw new IllegalArgumentException("cannot open output file."); 2057 | } 2058 | 2059 | // generate wav header 2060 | 2061 | { 2062 | short word; 2063 | int dword; 2064 | 2065 | ByteBuffer leos = ByteBuffer.allocate(44).order(ByteOrder.LITTLE_ENDIAN); 2066 | 2067 | leos.put("RIFF".getBytes()); 2068 | dword = 0; 2069 | leos.putInt(dword); 2070 | 2071 | leos.put("WAVEfmt ".getBytes()); 2072 | dword = 16; 2073 | leos.putInt(dword); 2074 | word = 1; 2075 | leos.putShort(word); // inAudioFormat category, PCM 2076 | word = (short) nch; 2077 | leos.putShort(word); // channels 2078 | dword = dfrq; 2079 | leos.putInt(dword); // sampling rate 2080 | dword = dfrq * nch * dbps; 2081 | leos.putInt(dword); // bytes per sec 2082 | word = (short) (dbps * nch); 2083 | leos.putShort(word); // block alignment 2084 | word = (short) (dbps * 8); 2085 | leos.putShort(word); // bits per sample 2086 | 2087 | leos.put("data".getBytes()); 2088 | dword = 0; 2089 | leos.putInt(dword); 2090 | 2091 | leos.flip(); 2092 | writeBuffers(fpo, leos); 2093 | } 2094 | 2095 | if (dither != 0) { 2096 | int min = 0, max = 0; 2097 | if (dbps == 1) { 2098 | min = -0x80; 2099 | max = 0x7f; 2100 | } 2101 | if (dbps == 2) { 2102 | min = -0x8000; 2103 | max = 0x7fff; 2104 | } 2105 | if (dbps == 3) { 2106 | min = -0x800000; 2107 | max = 0x7fffff; 2108 | } 2109 | if (dbps == 4) { 2110 | min = -0x80000000; 2111 | max = 0x7fffffff; 2112 | } 2113 | 2114 | samp = init_shaper(dfrq, nch, min, max, dither, pdf, noiseamp); 2115 | } 2116 | 2117 | if (twopass) { 2118 | double gain = 0; 2119 | int ch = 0; 2120 | int fptlen, sumread; 2121 | 2122 | if (!quiet) { 2123 | System.err.printf("Pass 1\n"); 2124 | } 2125 | 2126 | try { 2127 | if (tmpfn != null) { 2128 | ft = new File(tmpfn); 2129 | } else { 2130 | ft = File.createTempFile("ssrc_", ".tmp"); 2131 | } 2132 | fpto = new FileOutputStream(ft); 2133 | } catch (IOException e) { 2134 | throw new IllegalStateException("cannot open temporary file."); 2135 | } 2136 | 2137 | //System.err.printf("nch: %d, bps: %d, size: %d, sfrq: %d, dfrq: %d, ???: %d, ???: %d, twopass: %b, dither: %d\n", nch, bps, 8, sfrq, dfrq, 1, length / bps / nch, twopass, dither); 2138 | if (normalize) { 2139 | if (sfrq < dfrq) { 2140 | peak[0] = upsample(fpi, fpto, nch, bps, 8, sfrq, dfrq, 1, length / bps / nch, twopass, dither); 2141 | } else if (sfrq > dfrq) { 2142 | peak[0] = downsample(fpi, fpto, nch, bps, 8, sfrq, dfrq, 1, length / bps / nch, twopass, dither); 2143 | } else { 2144 | peak[0] = no_src(fpi, fpto, nch, bps, 8, 1, length / bps / nch, twopass, dither); 2145 | } 2146 | } else { 2147 | if (sfrq < dfrq) { 2148 | peak[0] = upsample(fpi, fpto, nch, bps, 8, sfrq, dfrq, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2149 | } else if (sfrq > dfrq) { 2150 | peak[0] = downsample(fpi, fpto, nch, bps, 8, sfrq, dfrq, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2151 | } else { 2152 | peak[0] = no_src(fpi, fpto, nch, bps, 8, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2153 | } 2154 | } 2155 | 2156 | fpto.close(); 2157 | 2158 | if (!quiet) { 2159 | System.err.printf("\npeak : %gdB\n", 20 * Math.log10(peak[0])); 2160 | } 2161 | 2162 | if (!normalize) { 2163 | if (peak[0] < Math.pow(10, -att / 20)) { 2164 | peak[0] = 1; 2165 | } else { 2166 | peak[0] *= Math.pow(10, att / 20); 2167 | } 2168 | } else { 2169 | peak[0] *= Math.pow(10, att / 20); 2170 | } 2171 | 2172 | if (!quiet) { 2173 | System.err.printf("\nPass 2\n"); 2174 | } 2175 | 2176 | if (dither != 0) { 2177 | switch (dbps) { 2178 | case 1: 2179 | gain = (normalize || peak[0] >= (0x7f - samp) / (double) 0x7f) ? 1 / peak[0] * (0x7f - samp) : 1 / peak[0] * 0x7f; 2180 | break; 2181 | case 2: 2182 | gain = (normalize || peak[0] >= (0x7fff - samp) / (double) 0x7fff) ? 1 / peak[0] * (0x7fff - samp) : 1 / peak[0] * 0x7fff; 2183 | break; 2184 | case 3: 2185 | gain = (normalize || peak[0] >= (0x7fffff - samp) / (double) 0x7fffff) ? 1 / peak[0] * (0x7fffff - samp) : 1 / peak[0] * 0x7fffff; 2186 | break; 2187 | } 2188 | } else { 2189 | switch (dbps) { 2190 | case 1: 2191 | gain = 1 / peak[0] * 0x7f; 2192 | break; 2193 | case 2: 2194 | gain = 1 / peak[0] * 0x7fff; 2195 | break; 2196 | case 3: 2197 | gain = 1 / peak[0] * 0x7fffff; 2198 | break; 2199 | } 2200 | } 2201 | randptr = 0; 2202 | 2203 | setstarttime(); 2204 | 2205 | fptlen = (int) (ft.length() / 8); 2206 | //System.err.println("tmp: " + fpt.getFilePointer()); 2207 | 2208 | FileChannel fpti = new FileInputStream(ft).getChannel(); 2209 | ByteBuffer leis = ByteBuffer.allocate(8); 2210 | for (sumread = 0; sumread < fptlen; ) { 2211 | double f; 2212 | int s; 2213 | 2214 | leis.clear(); 2215 | fpti.read(leis); 2216 | leis.flip(); 2217 | f = leis.getDouble(); 2218 | //if (sumread < 100) { 2219 | // System.err.printf("2: %06d: %f\n", sumread, f); 2220 | //} 2221 | f *= gain; 2222 | sumread++; 2223 | 2224 | switch (dbps) { 2225 | case 1: { 2226 | s = dither != 0 ? do_shaping(f, peak, dither, ch) : RINT(f); 2227 | 2228 | ByteBuffer buf = ByteBuffer.allocate(1); 2229 | buf.put((byte) (s + 128)); 2230 | buf.flip(); 2231 | 2232 | writeBuffers(fpo, buf); 2233 | } 2234 | break; 2235 | case 2: { 2236 | s = dither != 0 ? do_shaping(f, peak, dither, ch) : RINT(f); 2237 | 2238 | ByteBuffer buf = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN); 2239 | buf.putShort((short) s); 2240 | buf.flip(); 2241 | 2242 | writeBuffers(fpo, buf); 2243 | } 2244 | break; 2245 | case 3: { 2246 | s = dither != 0 ? do_shaping(f, peak, dither, ch) : RINT(f); 2247 | 2248 | ByteBuffer buf = ByteBuffer.allocate(3); 2249 | buf.put((byte) (s & 255)); 2250 | s >>= 8; 2251 | buf.put((byte) (s & 255)); 2252 | s >>= 8; 2253 | buf.put((byte) (s & 255)); 2254 | buf.flip(); 2255 | 2256 | writeBuffers(fpo, buf); 2257 | } 2258 | break; 2259 | } 2260 | 2261 | ch++; 2262 | if (ch == nch) { 2263 | ch = 0; 2264 | } 2265 | 2266 | if ((sumread & 0x3ffff) == 0) { 2267 | showprogress((double) sumread / fptlen); 2268 | } 2269 | } 2270 | showprogress(1); 2271 | if (!quiet) { 2272 | System.err.printf("\n"); 2273 | } 2274 | fpti.close(); 2275 | if (ft != null) { 2276 | //System.err.println("ft: " + ft); 2277 | if (ft.delete() == false) { 2278 | System.err.printf("Failed to remove %s\n", ft); 2279 | } 2280 | } 2281 | } else { 2282 | if (sfrq < dfrq) { 2283 | peak[0] = upsample(fpi, fpo, nch, bps, dbps, sfrq, dfrq, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2284 | } else if (sfrq > dfrq) { 2285 | peak[0] = downsample(fpi, fpo, nch, bps, dbps, sfrq, dfrq, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2286 | } else { 2287 | peak[0] = no_src(fpi, fpo, nch, bps, dbps, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2288 | } 2289 | if (!quiet) { 2290 | System.err.printf("\n"); 2291 | } 2292 | } 2293 | 2294 | if (dither != 0) { 2295 | quit_shaper(nch); 2296 | } 2297 | 2298 | if (!twopass && peak[0] > 1) { 2299 | if (!quiet) { 2300 | System.err.printf("clipping detected : %gdB\n", 20 * Math.log10(peak[0])); 2301 | } 2302 | } 2303 | 2304 | { 2305 | int dword; 2306 | int len; 2307 | 2308 | fpo.close(); 2309 | 2310 | fo = new File(dfn); 2311 | 2312 | len = (int) fo.length(); 2313 | FileChannel fpo1 = new RandomAccessFile(fo, "rw").getChannel(); 2314 | ByteBuffer leos = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); 2315 | 2316 | dword = len - 8; 2317 | leos.position(0); 2318 | leos.limit(4); 2319 | leos.putInt(dword); 2320 | leos.flip(); 2321 | fpo1.write(leos, 4); 2322 | 2323 | dword = len - 44; 2324 | leos.position(0); 2325 | leos.limit(4); 2326 | leos.putInt(dword); 2327 | leos.flip(); 2328 | fpo1.write(leos, 40); 2329 | 2330 | fpo1.close(); 2331 | } 2332 | } 2333 | 2334 | 2335 | /** */ 2336 | public SSRC(InputStream fpi, OutputStream fpo, int sfrq, int dfrq, int bps, int dbps, int nch, int length, double att, int dither, boolean quiet_) throws IOException { 2337 | String tmpfn = null; 2338 | boolean twopass, normalize; 2339 | int pdf, samp = 0; 2340 | double noiseamp; 2341 | double[] peak = new double[]{0}; 2342 | int i; 2343 | 2344 | // parse command line options 2345 | 2346 | twopass = false; 2347 | normalize = false; 2348 | 2349 | pdf = 0; 2350 | noiseamp = 0.18; 2351 | 2352 | 2353 | if (dither < 0 || dither > 4) { 2354 | throw new IllegalArgumentException("unrecognized dither type : " + dither); 2355 | } 2356 | this.quiet = quiet_; 2357 | 2358 | 2359 | if (!quiet) { 2360 | System.err.printf("Shibatch sampling rate converter version " + VERSION + "(high precision/nio)\n\n"); 2361 | } 2362 | 2363 | if (bps != 1 && bps != 2 && bps != 3 && bps != 4) { 2364 | throw new IllegalStateException("Error : Only 8bit, 16bit, 24bit and 32bit PCM are supported."); 2365 | } 2366 | 2367 | if (dbps == -1) { 2368 | if (bps != 1) { 2369 | dbps = bps; 2370 | } else { 2371 | dbps = 2; 2372 | } 2373 | if (dbps == 4) { 2374 | dbps = 3; 2375 | } 2376 | } 2377 | 2378 | if (dfrq == -1) { 2379 | dfrq = sfrq; 2380 | } 2381 | 2382 | if (dither == -1) { 2383 | if (dbps < bps) { 2384 | if (dbps == 1) { 2385 | dither = 4; 2386 | } else { 2387 | dither = 3; 2388 | } 2389 | } else { 2390 | dither = 1; 2391 | } 2392 | } 2393 | 2394 | if (!quiet) { 2395 | final String[] dtype = { 2396 | "none", "no noise shaping", "triangular spectral shape", "ATH based noise shaping", "ATH based noise shaping(less amplitude)" 2397 | }; 2398 | final String[] ptype = { 2399 | "rectangular", "triangular", "gaussian" 2400 | }; 2401 | System.err.printf("frequency : %d -> %d\n", sfrq, dfrq); 2402 | System.err.printf("attenuation : %gdB\n", att); 2403 | System.err.printf("bits per sample : %d -> %d\n", bps * 8, dbps * 8); 2404 | System.err.printf("nchannels : %d\n", nch); 2405 | System.err.printf("length : %d bytes, %g secs\n", length, (double) length / bps / nch / sfrq); 2406 | if (dither == 0) { 2407 | System.err.printf("dither type : none\n"); 2408 | } else { 2409 | System.err.printf("dither type : %s, %s p.d.f, amp = %g\n", dtype[dither], ptype[pdf], noiseamp); 2410 | } 2411 | System.err.printf("\n"); 2412 | } 2413 | 2414 | 2415 | if (dither != 0) { 2416 | int min = 0, max = 0; 2417 | if (dbps == 1) { 2418 | min = -0x80; 2419 | max = 0x7f; 2420 | } 2421 | if (dbps == 2) { 2422 | min = -0x8000; 2423 | max = 0x7fff; 2424 | } 2425 | if (dbps == 3) { 2426 | min = -0x800000; 2427 | max = 0x7fffff; 2428 | } 2429 | if (dbps == 4) { 2430 | min = -0x80000000; 2431 | max = 0x7fffffff; 2432 | } 2433 | 2434 | samp = init_shaper(dfrq, nch, min, max, dither, pdf, noiseamp); 2435 | } 2436 | 2437 | if (sfrq < dfrq) { 2438 | peak[0] = upsample(fpi, fpo, nch, bps, dbps, sfrq, dfrq, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2439 | } else if (sfrq > dfrq) { 2440 | peak[0] = downsample(fpi, fpo, nch, bps, dbps, sfrq, dfrq, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2441 | } else { 2442 | peak[0] = no_src(fpi, fpo, nch, bps, dbps, Math.pow(10, -att / 20), length / bps / nch, twopass, dither); 2443 | } 2444 | if (!quiet) { 2445 | System.err.printf("\n"); 2446 | } 2447 | 2448 | if (dither != 0) { 2449 | quit_shaper(nch); 2450 | } 2451 | 2452 | if (!twopass && peak[0] > 1) { 2453 | if (!quiet) { 2454 | System.err.printf("clipping detected : %gdB\n", 20 * Math.log10(peak[0])); 2455 | } 2456 | } 2457 | 2458 | } 2459 | 2460 | 2461 | protected byte[] getDataFromByteBuffer(ByteBuffer rawoutbuf) { 2462 | byte[] tempDataWrt = new byte[rawoutbuf.limit() - rawoutbuf.position()]; 2463 | rawoutbuf.get(tempDataWrt, 0, tempDataWrt.length); 2464 | 2465 | return tempDataWrt; 2466 | } 2467 | 2468 | 2469 | protected void writeBuffers(OutputStream fpo, ByteBuffer rawoutbuf) { 2470 | try { 2471 | fpo.write(getDataFromByteBuffer(rawoutbuf)); 2472 | } catch (IOException e) { 2473 | // Some problems (Read end dead) 2474 | } 2475 | } 2476 | 2477 | 2478 | } 2479 | 2480 | /* */ 2481 | -------------------------------------------------------------------------------- /src/vavi/util/I0Bessel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 1996 Takuya OOURA (email: ooura@mmm.t.u-tokyo.ac.jp). 3 | * You may use, copy, modify this code for any purpose and 4 | * without fee. You may distribute this ORIGINAL package. 5 | */ 6 | package vavi.util; 7 | 8 | 9 | /** 10 | * Bessel I_0(). 11 | * 12 | * @author Takuya OOURA 13 | * @author Naohide Sano (nsano) 14 | * @version 0.00 060127 nsano port to java version
15 | */ 16 | public class I0Bessel { 17 | /** */ 18 | private static final double[] a = { 19 | 8.5246820682016865877e-11, 2.5966600546497407288e-9, 20 | 7.9689994568640180274e-8, 1.9906710409667748239e-6, 21 | 4.0312469446528002532e-5, 6.4499871606224265421e-4, 22 | 0.0079012345761930579108, 0.071111111109207045212, 23 | 0.444444444444724909, 1.7777777777777532045, 24 | 4.0000000000000011182, 3.99999999999999998, 25 | 1.0000000000000000001, 26 | 1.1520919130377195927e-10, 2.2287613013610985225e-9, 27 | 8.1903951930694585113e-8, 1.9821560631611544984e-6, 28 | 4.0335461940910133184e-5, 6.4495330974432203401e-4, 29 | 0.0079013012611467520626, 0.071111038160875566622, 30 | 0.44444450319062699316, 1.7777777439146450067, 31 | 4.0000000132337935071, 3.9999999968569015366, 32 | 1.0000000003426703174, 33 | 1.5476870780515238488e-10, 1.2685004214732975355e-9, 34 | 9.2776861851114223267e-8, 1.9063070109379044378e-6, 35 | 4.0698004389917945832e-5, 6.4370447244298070713e-4, 36 | 0.0079044749458444976958, 0.071105052411749363882, 37 | 0.44445280640924755082, 1.7777694934432109713, 38 | 4.0000055808824003386, 3.9999977081165740932, 39 | 1.0000004333949319118, 40 | 2.0675200625006793075e-10, -6.1689554705125681442e-10, 41 | 1.2436765915401571654e-7, 1.5830429403520613423e-6, 42 | 4.2947227560776583326e-5, 6.3249861665073441312e-4, 43 | 0.0079454472840953930811, 0.070994327785661860575, 44 | 0.44467219586283000332, 1.7774588182255374745, 45 | 4.0003038986252717972, 3.9998233869142057195, 46 | 1.0000472932961288324, 47 | 2.7475684794982708655e-10, -3.8991472076521332023e-9, 48 | 1.9730170483976049388e-7, 5.9651531561967674521e-7, 49 | 5.1992971474748995357e-5, 5.7327338675433770752e-4, 50 | 0.0082293143836530412024, 0.069990934858728039037, 51 | 0.44726764292723985087, 1.7726685170014087784, 52 | 4.0062907863712704432, 3.9952750700487845355, 53 | 1.0016354346654179322 54 | }; 55 | /** */ 56 | private static final double[] b = { 57 | 6.7852367144945531383e-8, 4.6266061382821826854e-7, 58 | 6.9703135812354071774e-6, 7.6637663462953234134e-5, 59 | 7.9113515222612691636e-4, 0.0073401204731103808981, 60 | 0.060677114958668837046, 0.43994941411651569622, 61 | 2.7420017097661750609, 14.289661921740860534, 62 | 59.820609640320710779, 188.78998681199150629, 63 | 399.8731367825601118, 427.56411572180478514, 64 | 1.8042097874891098754e-7, 1.2277164312044637357e-6, 65 | 1.8484393221474274861e-5, 2.0293995900091309208e-4, 66 | 0.0020918539850246207459, 0.019375315654033949297, 67 | 0.15985869016767185908, 1.1565260527420641724, 68 | 7.1896341224206072113, 37.354773811947484532, 69 | 155.80993164266268457, 489.5211371158540918, 70 | 1030.9147225169564806, 1093.5883545113746958, 71 | 4.8017305613187493564e-7, 3.261317843912380074e-6, 72 | 4.9073137508166159639e-5, 5.3806506676487583755e-4, 73 | 0.0055387918291051866561, 0.051223717488786549025, 74 | 0.42190298621367914765, 3.0463625987357355872, 75 | 18.895299447327733204, 97.915189029455461554, 76 | 407.13940115493494659, 1274.3088990480582632, 77 | 2670.9883037012547506, 2815.7166284662544712, 78 | 1.2789926338424623394e-6, 8.6718263067604918916e-6, 79 | 1.3041508821299929489e-4, 0.001428224737372747892, 80 | 0.014684070635768789378, 0.13561403190404185755, 81 | 1.1152592585977393953, 8.0387088559465389038, 82 | 49.761318895895479206, 257.2684232313529138, 83 | 1066.8543146269566231, 3328.3874581009636362, 84 | 6948.8586598121634874, 7288.4893398212481055, 85 | 3.409350368197032893e-6, 2.3079025203103376076e-5, 86 | 3.4691373283901830239e-4, 0.003794994977222908545, 87 | 0.038974209677945602145, 0.3594948380414878371, 88 | 2.9522878893539528226, 21.246564609514287056, 89 | 131.28727387146173141, 677.38107093296675421, 90 | 2802.3724744545046518, 8718.5731420798254081, 91 | 18141.348781638832286, 18948.925349296308859 92 | }; 93 | /** */ 94 | private static final double[] c = { 95 | 2.5568678676452702768e-15, 3.0393953792305924324e-14, 96 | 6.3343751991094840009e-13, 1.5041298011833009649e-11, 97 | 4.4569436918556541414e-10, 1.746393051427167951e-8, 98 | 1.0059224011079852317e-6, 1.0729838945088577089e-4, 99 | 0.05150322693642527738, 100 | 5.2527963991711562216e-15, 7.202118481421005641e-15, 101 | 7.2561421229904797156e-13, 1.482312146673104251e-11, 102 | 4.4602670450376245434e-10, 1.7463600061788679671e-8, 103 | 1.005922609132234756e-6, 1.0729838937545111487e-4, 104 | 0.051503226936437300716, 105 | 1.3365917359358069908e-14, -1.2932643065888544835e-13, 106 | 1.7450199447905602915e-12, 1.0419051209056979788e-11, 107 | 4.58047881980598326e-10, 1.7442405450073548966e-8, 108 | 1.0059461453281292278e-6, 1.0729837434500161228e-4, 109 | 0.051503226940658446941, 110 | 5.3771611477352308649e-14, -1.1396193006413731702e-12, 111 | 1.2858641335221653409e-11, -5.9802086004570057703e-11, 112 | 7.3666894305929510222e-10, 1.6731837150730356448e-8, 113 | 1.0070831435812128922e-6, 1.0729733111203704813e-4, 114 | 0.051503227360726294675, 115 | 3.7819492084858931093e-14, -4.8600496888588034879e-13, 116 | 1.6898350504817224909e-12, 4.5884624327524255865e-11, 117 | 1.2521615963377513729e-10, 1.8959658437754727957e-8, 118 | 1.0020716710561353622e-6, 1.073037119856927559e-4, 119 | 0.05150322383300230775 120 | }; 121 | 122 | /** 123 | * 124 | * @param x 125 | * @return 126 | */ 127 | public static double value(double x) { 128 | int k; 129 | double w, t, y; 130 | w = Math.abs(x); 131 | if (w < 8.5) { 132 | t = w * w * 0.0625; 133 | k = 13 * ((int) t); 134 | y = (((((((((((a[k] * t + a[k + 1]) * t + 135 | a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t + 136 | a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t + 137 | a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t + 138 | a[k + 11]) * t + a[k + 12]; 139 | } else if (w < 12.5) { 140 | k = (int) w; 141 | t = w - k; 142 | k = 14 * (k - 8); 143 | y = ((((((((((((b[k] * t + b[k + 1]) * t + 144 | b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t + 145 | b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t + 146 | b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t + 147 | b[k + 11]) * t + b[k + 12]) * t + b[k + 13]; 148 | } else { 149 | t = 60 / w; 150 | k = 9 * ((int) t); 151 | y = ((((((((c[k] * t + c[k + 1]) * t + 152 | c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t + 153 | c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t + 154 | c[k + 8]) * Math.sqrt(t) * Math.exp(w); 155 | } 156 | return y; 157 | } 158 | } 159 | 160 | /* */ 161 | -------------------------------------------------------------------------------- /src/vavi/util/SplitRadixFft.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Takuya OOURA, 1996-2001 3 | * 4 | * You may use, copy, modify and distribute this code 5 | * for any purpose (include commercial use) and without fee. 6 | * Please refer to this package when you modify this code. 7 | */ 8 | package vavi.util; 9 | 10 | 11 | 12 | 13 | /** 14 | * Fast Fourier/Cosine/Sine Transform. 15 | *
  16 |  *  dimension   :one
  17 |  *  data length :power of 2
  18 |  *  decimation  :frequency
  19 |  *  radix       :split-radix
  20 |  *  data        :inplace
  21 |  *  table       :use
  22 |  * 
23 | *

Appendix:

24 | *

25 | * The cos/sin table is recalculated when the larger table required. 26 | * w[] and ip[] are compatible with all routines. 27 | *

28 | * @author Takuya OOURA 29 | * @author Naohide Sano (nsano) 30 | * @version 0.00 060127 nsano port to java version
31 | */ 32 | public class SplitRadixFft { 33 | 34 | /** */ 35 | private static final int CDFT_RECURSIVE_N = 512; 36 | 37 | /** 38 | * Complex Discrete Fourier Transform. 39 | *
  40 |      *  [definition]
  41 |      *      <case1>
  42 |      *          X[k] = sum_j=0&circ;n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
  43 |      *      <case2>
  44 |      *          X[k] = sum_j=0&circ;n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
  45 |      *      (notes: sum_j=0&circ;n-1 is a summation from j=0 to n-1)
  46 |      *  [usage]
  47 |      *      <case1>
  48 |      *          ip[0] = 0; // first time only
  49 |      *          cdft(2*n, 1, a, ip, w);
  50 |      *      <case2>
  51 |      *          ip[0] = 0; // first time only
  52 |      *          cdft(2*n, -1, a, ip, w);
  53 |      *  [remark]
  54 |      *      Inverse of
  55 |      *          cdft(2*n, -1, a, ip, w);
  56 |      *      is
  57 |      *          cdft(2*n, 1, a, ip, w);
  58 |      *          for (j = 0; j <= 2 * n - 1; j++) {
  59 |      *              a[j] *= 1.0 / n;
  60 |      *          }
  61 |      *      .
  62 |      * 
63 | * @param n 2*n data length (int) 64 | * n >= 1, n = power of 2 65 | * @param isgn 66 | * @param a a[0...2*n-1] input/output data (REAL *) 67 | * input data 68 | * a[2*j] = Re(x[j]), 69 | * a[2*j+1] = Im(x[j]), 0<=j<n 70 | * output data 71 | * a[2*k] = Re(X[k]), 72 | * a[2*k+1] = Im(X[k]), 0<=k<n 73 | * @param ip ip[0...*] work area for bit reversal (int *) 74 | * length of ip >= 2+sqrt(n) 75 | * strictly, 76 | * length of ip >= 77 | * 2+(1<<(int)(log(n+0.5)/log(2))/2). 78 | * ip[0],ip[1] are pointers of the cos/sin table. 79 | * @param w w[0...n/2-1] cos/sin table (REAL *) 80 | * w[],ip[] are initialized if ip[0] == 0. 81 | */ 82 | public void cdft(int n, int isgn, double[] a, int[] ip, double[] w) { 83 | int nw; 84 | 85 | nw = ip[0]; 86 | if (n > (nw << 2)) { 87 | nw = n >> 2; 88 | makewt(nw, ip, w); 89 | } 90 | if (isgn >= 0) { 91 | cftfsub(n, a, ip, 2, nw, w); 92 | } else { 93 | cftbsub(n, a, ip, 2, nw, w); 94 | } 95 | } 96 | 97 | /** 98 | * Real Discrete Fourier Transform. 99 | *
 100 |      *  [definition]
 101 |      *      <case1> RDFT
 102 |      *          R[k] = sum_j = 0 & ˆ (n - 1) a[j] * cos(2 * pi * j * k / n), 0 <= k <= n / 2
 103 |      *          I[k] = sum_j = 0 & ˆ (n - 1) a[j] * sin(2 * pi * j * k / n), 0 < k < n / 2
 104 |      *      <case2> IRDFT (excluding scale)
 105 |      *          a[k] = (R[0] + R[n / 2] * cos(pi * k)) / 2 +
 106 |      *              sum_j = 1 & ˆ (n / 2 - 1) R[j] * cos(2 * pi * j * k / n) +
 107 |      *              sum_j = 1 & ˆ (n / 2 - 1) I[j] * sin(2 * pi * j * k / n), 0 <= k < n
 108 |      *  [usage]
 109 |      *      <case1>
 110 |      *          ip[0] = 0; // first time only
 111 |      *          rdft(n, 1, a, ip, w);
 112 |      *      <case2>
 113 |      *          ip[0] = 0; // first time only
 114 |      *          rdft(n, -1, a, ip, w);
 115 |      *  [remark]
 116 |      *      Inverse of
 117 |      *          rdft(n, 1, a, ip, w);
 118 |      *      is
 119 |      *          rdft(n, -1, a, ip, w);
 120 |      *          for (j = 0; j <= n - 1; j++) {
 121 |      *              a[j] *= 2.0 / n;
 122 |      *          }
 123 |      *      .
 124 |      * 
125 | * @param n data length
126 | * n >= 2, n = power of 2 127 | * @param isgn 128 | * @param a [0...n-1] input/output data 129 | *
 130 |      *  <case1>
 131 |      *      output data
 132 |      *          a[2 * k] = R[k], 0 <= k < n / 2
 133 |      *          a[2 * k + 1] = I[k], 0 < k < n / 2
 134 |      *          a[1] = R[n/2]
 135 |      *  <case2>
 136 |      *      input data
 137 |      *          a[2 * j] = R[j], 0 <= j < n / 2
 138 |      *          a[2 * j + 1] = I[j], 0 < j < n / 2
 139 |      *          a[1] = R[n / 2]
 140 |      * 
141 | * @param ip [0...*] work area for bit reversal 142 | *
 143 |      *  length of ip >= 2 + sqrt(n / 2)
 144 |      *  strictly,
 145 |      *  length of ip >=
 146 |      *      2 + (1 << (int) (log(n / 2 + 0.5) / log(2)) / 2).
 147 |      * 
148 | * ip[0],ip[1] are pointers of the cos/sin table. 149 | * @param w [0...n/2-1] cos/sin table
150 | * w[],ip[] are initialized if ip[0] == 0. 151 | */ 152 | public void rdft(int n, int isgn, double[] a, int[] ip, double[] w) { 153 | int nw, nc; 154 | double xi; 155 | 156 | nw = ip[0]; 157 | if (n > (nw << 2)) { 158 | nw = n >> 2; 159 | makewt(nw, ip, w); 160 | } 161 | nc = ip[1]; 162 | if (n > (nc << 2)) { 163 | nc = n >> 2; 164 | makect(nc, ip, w, nw); 165 | } 166 | if (isgn >= 0) { 167 | if (n > 4) { 168 | cftfsub(n, a, ip, 2, nw, w); 169 | rftfsub(n, a, nc, w, nw); 170 | } else if (n == 4) { 171 | cftfsub(n, a, ip, 2, nw, w); 172 | } 173 | xi = a[0] - a[1]; 174 | a[0] += a[1]; 175 | a[1] = xi; 176 | } else { 177 | a[1] = 0.5 * (a[0] - a[1]); 178 | a[0] -= a[1]; 179 | if (n > 4) { 180 | rftbsub(n, a, nc, w, nw); 181 | cftbsub(n, a, ip, 2, nw, w); 182 | } else if (n == 4) { 183 | cftbsub(n, a, ip, 2, nw, w); 184 | } 185 | } 186 | } 187 | 188 | /** 189 | * Discrete Cosine Transform. 190 | *
 191 |      *  [definition]
 192 |      *      <case1> IDCT (excluding scale)
 193 |      *          C[k] = sum_j=0&circ;n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n
 194 |      *      <case2> DCT
 195 |      *          C[k] = sum_j=0&circ;n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n
 196 |      *  [usage]
 197 |      *      <case1>
 198 |      *          ip[0] = 0; // first time only
 199 |      *          ddct(n, 1, a, ip, w);
 200 |      *      <case2>
 201 |      *          ip[0] = 0; // first time only
 202 |      *          ddct(n, -1, a, ip, w);
 203 |      *  [remark]
 204 |      *      Inverse of
 205 |      *          ddct(n, -1, a, ip, w);
 206 |      *      is
 207 |      *          a[0] *= 0.5;
 208 |      *          ddct(n, 1, a, ip, w);
 209 |      *          for (j = 0; j <= n - 1; j++) {
 210 |      *              a[j] *= 2.0 / n;
 211 |      *          }
 212 |      *      .
 213 |      * 
214 | * @param n data length (int) 215 | *
 216 |      *  n >= 2, n = power of 2
 217 |      * 
218 | * @param isgn 219 | * @param a [0...n-1] input/output data (REAL *) 220 | *
 221 |      *  output data
 222 |      *      a[k] = C[k], 0<=k<n
 223 |      * 
224 | * @param ip [0...*] work area for bit reversal (int *) 225 | *
 226 |      *  length of ip >= 2+sqrt(n/2)
 227 |      *  strictly,
 228 |      *  length of ip >=
 229 |      *      2+(1<<(int)(log(n/2+0.5)/log(2))/2).
 230 |      *  ip[0],ip[1] are pointers of the cos/sin table.
 231 |      * 
232 | * @param w [0...n*5/4-1] cos/sin table (REAL *) 233 | *
 234 |      *  w[],ip[] are initialized if ip[0] == 0.
 235 |      * 
236 | */ 237 | public void ddct(int n, int isgn, double[] a, int[] ip, double[] w) { 238 | int j, nw, nc; 239 | double xr; 240 | 241 | nw = ip[0]; 242 | if (n > (nw << 2)) { 243 | nw = n >> 2; 244 | makewt(nw, ip, w); 245 | } 246 | nc = ip[1]; 247 | if (n > nc) { 248 | nc = n; 249 | makect(nc, ip, w, nw); 250 | } 251 | if (isgn < 0) { 252 | xr = a[n - 1]; 253 | for (j = n - 2; j >= 2; j -= 2) { 254 | a[j + 1] = a[j] - a[j - 1]; 255 | a[j] += a[j - 1]; 256 | } 257 | a[1] = a[0] - xr; 258 | a[0] += xr; 259 | if (n > 4) { 260 | rftbsub(n, a, nc, w, nw); 261 | cftbsub(n, a, ip, 2, nw, w); 262 | } else if (n == 4) { 263 | cftbsub(n, a, ip, 2, nw, w); 264 | } 265 | } 266 | dctsub(n, a, nc, w, nw); 267 | if (isgn >= 0) { 268 | if (n > 4) { 269 | cftfsub(n, a, ip, 2, nw, w); 270 | rftfsub(n, a, nc, w, nw); 271 | } else if (n == 4) { 272 | cftfsub(n, a, ip, 2, nw, w); 273 | } 274 | xr = a[0] - a[1]; 275 | a[0] += a[1]; 276 | for (j = 2; j < n; j += 2) { 277 | a[j - 1] = a[j] - a[j + 1]; 278 | a[j] += a[j + 1]; 279 | } 280 | a[n - 1] = xr; 281 | } 282 | } 283 | 284 | /** 285 | * Discrete Sine Transform. 286 | *
 287 |      *  [definition]
 288 |      *      <case1> IDST (excluding scale)
 289 |      *          S[k] = sum_j=1ˆn A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n
 290 |      *      <case2> DST
 291 |      *          S[k] = sum_j=0ˆn-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n
 292 |      *  [usage]
 293 |      *      <case1>
 294 |      *          ip[0] = 0; // first time only
 295 |      *          ddst(n, 1, a, ip, w);
 296 |      *      <case2>
 297 |      *          ip[0] = 0; // first time only
 298 |      *          ddst(n, -1, a, ip, w);
 299 |      *  [remark]
 300 |      *      Inverse of
 301 |      *          ddst(n, -1, a, ip, w);
 302 |      *      is
 303 |      *          a[0] *= 0.5;
 304 |      *          ddst(n, 1, a, ip, w);
 305 |      *          for (j = 0; j <= n - 1; j++) {
 306 |      *              a[j] *= 2.0 / n;
 307 |      *          }
 308 |      *      .
 309 |      * 
310 | * @param n data length (int) 311 | * n >= 2, n = power of 2 312 | * @param isgn 313 | * @param a [0...n-1] input/output data (REAL *) 314 | * <case1> 315 | * input data 316 | * a[j] = A[j], 0<j<n 317 | * a[0] = A[n] 318 | * output data 319 | * a[k] = S[k], 0<=k<n 320 | * <case2> 321 | * output data 322 | * a[k] = S[k], 0<k<n 323 | * a[0] = S[n] 324 | * @param ip [0...*] work area for bit reversal (int *) 325 | * length of ip >= 2+sqrt(n/2) 326 | * strictly, 327 | * length of ip >= 328 | * 2+(1<<(int)(log(n/2+0.5)/log(2))/2). 329 | * ip[0],ip[1] are pointers of the cos/sin table. 330 | * @param w [0...n*5/4-1] cos/sin table (REAL *) 331 | * w[],ip[] are initialized if ip[0] == 0. 332 | */ 333 | public void ddst(int n, int isgn, double[] a, int[] ip, double[] w) { 334 | int j, nw, nc; 335 | double xr; 336 | 337 | nw = ip[0]; 338 | if (n > (nw << 2)) { 339 | nw = n >> 2; 340 | makewt(nw, ip, w); 341 | } 342 | nc = ip[1]; 343 | if (n > nc) { 344 | nc = n; 345 | makect(nc, ip, w, nw); 346 | } 347 | if (isgn < 0) { 348 | xr = a[n - 1]; 349 | for (j = n - 2; j >= 2; j -= 2) { 350 | a[j + 1] = -a[j] - a[j - 1]; 351 | a[j] -= a[j - 1]; 352 | } 353 | a[1] = a[0] + xr; 354 | a[0] -= xr; 355 | if (n > 4) { 356 | rftbsub(n, a, nc, w, nw); 357 | cftbsub(n, a, ip, 2, nw, w); 358 | } else if (n == 4) { 359 | cftbsub(n, a, ip, 2, nw, w); 360 | } 361 | } 362 | dstsub(n, a, nc, w, nw); 363 | if (isgn >= 0) { 364 | if (n > 4) { 365 | cftfsub(n, a, ip, 2, nw, w); 366 | rftfsub(n, a, nc, w, nw); 367 | } else if (n == 4) { 368 | cftfsub(n, a, ip, 2, nw, w); 369 | } 370 | xr = a[0] - a[1]; 371 | a[0] += a[1]; 372 | for (j = 2; j < n; j += 2) { 373 | a[j - 1] = -a[j] - a[j + 1]; 374 | a[j] -= a[j + 1]; 375 | } 376 | a[n - 1] = -xr; 377 | } 378 | } 379 | 380 | /** 381 | * Cosine Transform of RDFT (Real Symmetric DFT). 382 | *
 383 |      *  [definition]
 384 |      *      C[k] = sum_j=0ˆn a[j]*cos(pi*j*k/n), 0<=k<=n
 385 |      *  [usage]
 386 |      *      ip[0] = 0; // first time only
 387 |      *      dfct(n, a, t, ip, w);
 388 |      *  [parameters]
 389 |      *  [remark]
 390 |      *      Inverse of
 391 |      *          a[0] *= 0.5;
 392 |      *          a[n] *= 0.5;
 393 |      *          dfct(n, a, t, ip, w);
 394 |      *      is
 395 |      *          a[0] *= 0.5;
 396 |      *          a[n] *= 0.5;
 397 |      *          dfct(n, a, t, ip, w);
 398 |      *          for (j = 0; j <= n; j++) {
 399 |      *              a[j] *= 2.0 / n;
 400 |      *          }
 401 |      *      .
 402 |      * 
403 | * @param n data length - 1 (int) 404 | *
 405 |      *  n >= 2, n = power of 2
 406 |      * 
407 | * @param a [0...n] input/output data (REAL *) 408 | *
 409 |      *  output data
 410 |      *      a[k] = C[k], 0<=k<=n
 411 |      * 
412 | * @param t [0...n/2] work area (REAL *) 413 | * @param ip [0...*] work area for bit reversal (int *) 414 | *
 415 |      *  length of ip >= 2+sqrt(n/4)
 416 |      *  strictly,
 417 |      *  length of ip >=
 418 |      *      2+(1<<(int)(log(n/4+0.5)/log(2))/2).
 419 |      *  ip[0],ip[1] are pointers of the cos/sin table.
 420 |      * 
421 | * @param w [0...n*5/8-1] cos/sin table (REAL *) 422 | *
 423 |      *  w[],ip[] are initialized if ip[0] == 0.
 424 |      * 
425 | */ 426 | public void dfct(int n, double[] a, double[] t, int[] ip, double[] w) { 427 | int j, k, l, m, mh, nw, nc; 428 | double xr, xi, yr, yi; 429 | 430 | nw = ip[0]; 431 | if (n > (nw << 3)) { 432 | nw = n >> 3; 433 | makewt(nw, ip, w); 434 | } 435 | nc = ip[1]; 436 | if (n > (nc << 1)) { 437 | nc = n >> 1; 438 | makect(nc, ip, w, nw); 439 | } 440 | m = n >> 1; 441 | yi = a[m]; 442 | xi = a[0] + a[n]; 443 | a[0] -= a[n]; 444 | t[0] = xi - yi; 445 | t[m] = xi + yi; 446 | if (n > 2) { 447 | mh = m >> 1; 448 | for (j = 1; j < mh; j++) { 449 | k = m - j; 450 | xr = a[j] - a[n - j]; 451 | xi = a[j] + a[n - j]; 452 | yr = a[k] - a[n - k]; 453 | yi = a[k] + a[n - k]; 454 | a[j] = xr; 455 | a[k] = yr; 456 | t[j] = xi - yi; 457 | t[k] = xi + yi; 458 | } 459 | t[mh] = a[mh] + a[n - mh]; 460 | a[mh] -= a[n - mh]; 461 | dctsub(m, a, nc, w, nw); 462 | if (m > 4) { 463 | cftfsub(m, a, ip, 2, nw, w); 464 | rftfsub(m, a, nc, w, nw); 465 | } else if (m == 4) { 466 | cftfsub(m, a, ip, 2, nw, w); 467 | } 468 | a[n - 1] = a[0] - a[1]; 469 | a[1] = a[0] + a[1]; 470 | for (j = m - 2; j >= 2; j -= 2) { 471 | a[2 * j + 1] = a[j] + a[j + 1]; 472 | a[2 * j - 1] = a[j] - a[j + 1]; 473 | } 474 | l = 2; 475 | m = mh; 476 | while (m >= 2) { 477 | dctsub(m, t, nc, w, nw); 478 | if (m > 4) { 479 | cftfsub(m, t, ip, 2, nw, w); 480 | rftfsub(m, t, nc, w, nw); 481 | } else if (m == 4) { 482 | cftfsub(m, t, ip, 2, nw, w); 483 | } 484 | a[n - l] = t[0] - t[1]; 485 | a[l] = t[0] + t[1]; 486 | k = 0; 487 | for (j = 2; j < m; j += 2) { 488 | k += l << 2; 489 | a[k - l] = t[j] - t[j + 1]; 490 | a[k + l] = t[j] + t[j + 1]; 491 | } 492 | l <<= 1; 493 | mh = m >> 1; 494 | for (j = 0; j < mh; j++) { 495 | k = m - j; 496 | t[j] = t[m + k] - t[m + j]; 497 | t[k] = t[m + k] + t[m + j]; 498 | } 499 | t[mh] = t[m + mh]; 500 | m = mh; 501 | } 502 | a[l] = t[0]; 503 | a[n] = t[2] - t[1]; 504 | a[0] = t[2] + t[1]; 505 | } else { 506 | a[1] = a[0]; 507 | a[2] = t[0]; 508 | a[0] = t[1]; 509 | } 510 | } 511 | 512 | /** 513 | * Sine Transform of RDFT (Real Anti-symmetric DFT). 514 | *
 515 |      *  [definition]
 516 |      *      S[k] = sum_j=1&circ;n-1 a[j]*sin(pi*j*k/n), 0<k<n
 517 |      *  [usage]
 518 |      *      ip[0] = 0; // first time only
 519 |      *      dfst(n, a, t, ip, w);
 520 |      *  [remark]
 521 |      *      Inverse of
 522 |      *          dfst(n, a, t, ip, w);
 523 |      *      is
 524 |      *          dfst(n, a, t, ip, w);
 525 |      *          for (j = 1; j <= n - 1; j++) {
 526 |      *              a[j] *= 2.0 / n;
 527 |      *          }
 528 |      *      .
 529 |      * 
530 | * @param n data length + 1 (int) 531 | *
 532 |      *  n >= 2, n = power of 2
 533 |      * 
534 | * @param a [0...n-1] input/output data (REAL *) 535 | *
 536 |      *  output data
 537 |      *      a[k] = S[k], 0<k<n
 538 |      *      (a[0] is used for work area)
 539 |      * 
540 | * @param t [0...n/2-1] work area (REAL *) 541 | * @param ip [0...*] work area for bit reversal (int *) 542 | *
 543 |      *  length of ip >= 2+sqrt(n/4)
 544 |      *  strictly,
 545 |      *  length of ip >=
 546 |      *      2+(1<<(int)(log(n/4+0.5)/log(2))/2).
 547 |      *  ip[0],ip[1] are pointers of the cos/sin table.
 548 |      * 
549 | * @param w [0...n*5/8-1] cos/sin table (REAL *) 550 | *
 551 |      *  w[],ip[] are initialized if ip[0] == 0.
 552 |      * 
553 | */ 554 | public void dfst(int n, double[] a, double[] t, int[] ip, double[] w) { 555 | int j, k, l, m, mh, nw, nc; 556 | double xr, xi, yr, yi; 557 | 558 | nw = ip[0]; 559 | if (n > (nw << 3)) { 560 | nw = n >> 3; 561 | makewt(nw, ip, w); 562 | } 563 | nc = ip[1]; 564 | if (n > (nc << 1)) { 565 | nc = n >> 1; 566 | makect(nc, ip, w, nw); 567 | } 568 | if (n > 2) { 569 | m = n >> 1; 570 | mh = m >> 1; 571 | for (j = 1; j < mh; j++) { 572 | k = m - j; 573 | xr = a[j] + a[n - j]; 574 | xi = a[j] - a[n - j]; 575 | yr = a[k] + a[n - k]; 576 | yi = a[k] - a[n - k]; 577 | a[j] = xr; 578 | a[k] = yr; 579 | t[j] = xi + yi; 580 | t[k] = xi - yi; 581 | } 582 | t[0] = a[mh] - a[n - mh]; 583 | a[mh] += a[n - mh]; 584 | a[0] = a[m]; 585 | dstsub(m, a, nc, w, nw); 586 | if (m > 4) { 587 | cftfsub(m, a, ip, 2, nw, w); 588 | rftfsub(m, a, nc, w, nw); 589 | } else if (m == 4) { 590 | cftfsub(m, a, ip, 2, nw, w); 591 | } 592 | a[n - 1] = a[1] - a[0]; 593 | a[1] = a[0] + a[1]; 594 | for (j = m - 2; j >= 2; j -= 2) { 595 | a[2 * j + 1] = a[j] - a[j + 1]; 596 | a[2 * j - 1] = -a[j] - a[j + 1]; 597 | } 598 | l = 2; 599 | m = mh; 600 | while (m >= 2) { 601 | dstsub(m, t, nc, w, nw); 602 | if (m > 4) { 603 | cftfsub(m, t, ip, 2, nw, w); 604 | rftfsub(m, t, nc, w, nw); 605 | } else if (m == 4) { 606 | cftfsub(m, t, ip, 2, nw, w); 607 | } 608 | a[n - l] = t[1] - t[0]; 609 | a[l] = t[0] + t[1]; 610 | k = 0; 611 | for (j = 2; j < m; j += 2) { 612 | k += l << 2; 613 | a[k - l] = -t[j] - t[j + 1]; 614 | a[k + l] = t[j] - t[j + 1]; 615 | } 616 | l <<= 1; 617 | mh = m >> 1; 618 | for (j = 1; j < mh; j++) { 619 | k = m - j; 620 | t[j] = t[m + k] + t[m + j]; 621 | t[k] = t[m + k] - t[m + j]; 622 | } 623 | t[0] = t[m + mh]; 624 | m = mh; 625 | } 626 | a[l] = t[0]; 627 | } 628 | a[0] = 0; 629 | } 630 | 631 | // -------- initializing routines -------- 632 | 633 | /** */ 634 | private void makewt(int nw, int[] ip, double[] w) { 635 | int j, nwh, nw0, nw1; 636 | double delta, wn4r, wk1r, wk1i, wk3r, wk3i; 637 | 638 | ip[0] = nw; 639 | ip[1] = 1; 640 | if (nw > 2) { 641 | nwh = nw >> 1; 642 | // delta = Math.atan(1.0) / nwh; 643 | delta = Math.PI / 4 / nwh; 644 | wn4r = Math.cos(delta * nwh); 645 | w[0] = 1; 646 | w[1] = wn4r; 647 | if (nwh >= 4) { 648 | w[2] = 0.5 / Math.cos(delta * 2); 649 | w[3] = 0.5 / Math.cos(delta * 6); 650 | } 651 | for (j = 4; j < nwh; j += 4) { 652 | w[j] = Math.cos(delta * j); 653 | w[j + 1] = Math.sin(delta * j); 654 | w[j + 2] = Math.cos(3 * delta * j); 655 | w[j + 3] = Math.sin(3 * delta * j); 656 | } 657 | nw0 = 0; 658 | while (nwh > 2) { 659 | nw1 = nw0 + nwh; 660 | nwh >>= 1; 661 | w[nw1] = 1; 662 | w[nw1 + 1] = wn4r; 663 | if (nwh >= 4) { 664 | wk1r = w[nw0 + 4]; 665 | wk3r = w[nw0 + 6]; 666 | w[nw1 + 2] = 0.5 / wk1r; 667 | w[nw1 + 3] = 0.5 / wk3r; 668 | } 669 | for (j = 4; j < nwh; j += 4) { 670 | wk1r = w[nw0 + 2 * j]; 671 | wk1i = w[nw0 + 2 * j + 1]; 672 | wk3r = w[nw0 + 2 * j + 2]; 673 | wk3i = w[nw0 + 2 * j + 3]; 674 | w[nw1 + j] = wk1r; 675 | w[nw1 + j + 1] = wk1i; 676 | w[nw1 + j + 2] = wk3r; 677 | w[nw1 + j + 3] = wk3i; 678 | } 679 | nw0 = nw1; 680 | } 681 | } 682 | } 683 | 684 | /** */ 685 | private void makect(int nc, int[] ip, double[] c, int cP) { 686 | int j, nch; 687 | double delta; 688 | 689 | ip[1] = nc; 690 | if (nc > 1) { 691 | nch = nc >> 1; 692 | // delta = Math.atan(1.0) / nch; 693 | delta = Math.PI / 4 / nch; 694 | c[cP + 0] = Math.cos(delta * nch); 695 | c[cP + nch] = 0.5 * c[cP + 0]; 696 | for (j = 1; j < nch; j++) { 697 | c[cP + j] = 0.5 * Math.cos(delta * j); 698 | c[cP + nc - j] = 0.5 * Math.sin(delta * j); 699 | } 700 | } 701 | } 702 | 703 | // -------- child routines -------- 704 | 705 | /** 706 | * 2nd 707 | * @see #rdft(int, int, double[], int[], double[]) 708 | * @see #ddct(int, int, double[], int[], double[]) 709 | * @see #cdft(int, int, double[], int[], double[]) 710 | * @see #ddst(int, int, double[], int[], double[]) 711 | * @see #dfst(int, double[], double[], int[], double[]) 712 | * @see #dfct(int, double[], double[], int[], double[]) 713 | */ 714 | private void cftfsub(int n, double[] a, int[] ip, int ipP, int nw, double[] w) { 715 | int m; 716 | 717 | if (n > 32) { 718 | m = n >> 2; 719 | cftf1st(n, a, w, nw - m); 720 | if (n > CDFT_RECURSIVE_N) { 721 | cftrec1(m, a, 0, nw, w); 722 | cftrec2(m, a, m, nw, w); 723 | cftrec1(m, a, 2 * m, nw, w); 724 | cftrec1(m, a, 3 * m, nw, w); 725 | } else if (m > 32) { 726 | cftexp1(n, a, 0, nw, w); 727 | } else { 728 | cftfx41(n, a, 0, nw, w); 729 | } 730 | bitrv2(n, ip, ipP, a); 731 | } else if (n > 8) { 732 | if (n == 32) { 733 | cftf161(a, 0, w, nw - 8); 734 | bitrv216(a); 735 | } else { 736 | cftf081(a, 0, w, 0); 737 | bitrv208(a); 738 | } 739 | } else if (n == 8) { 740 | cftf040(a); 741 | } else if (n == 4) { 742 | cftx020(a); 743 | } 744 | } 745 | 746 | /** 747 | * 2nd 748 | * @see #rdft(int, int, double[], int[], double[]) 749 | * @see #ddct(int, int, double[], int[], double[]) 750 | * @see #cdft(int, int, double[], int[], double[]) 751 | * @see #ddst(int, int, double[], int[], double[]) 752 | */ 753 | private void cftbsub(int n, double[] a, int[] ip, int ipP, int nw, double[] w) { 754 | int m; 755 | 756 | if (n > 32) { 757 | m = n >> 2; 758 | cftb1st(n, a, w, nw - m); 759 | if (n > CDFT_RECURSIVE_N) { 760 | cftrec1(m, a, 0, nw, w); 761 | cftrec2(m, a, m, nw, w); 762 | cftrec1(m, a, 2 * m, nw, w); 763 | cftrec1(m, a, 3 * m, nw, w); 764 | } else if (m > 32) { 765 | cftexp1(n, a, 0, nw, w); 766 | } else { 767 | cftfx41(n, a, 0, nw, w); 768 | } 769 | bitrv2conj(n, ip, ipP, a); 770 | } else if (n > 8) { 771 | if (n == 32) { 772 | cftf161(a, 0, w, nw - 8); 773 | bitrv216neg(a); 774 | } else { 775 | cftf081(a, 0, w, 0); 776 | bitrv208neg(a); 777 | } 778 | } else if (n == 8) { 779 | cftb040(a); 780 | } else if (n == 4) { 781 | cftx020(a); 782 | } 783 | } 784 | 785 | /** 786 | * 3rd 787 | * @see #cftfsub(int, double[], int[], int, int, double[]) 788 | */ 789 | private final void bitrv2(int n, int[] ip, int ipP, double[] a) { 790 | int j, j1, k, k1, l, m, m2; 791 | double xr, xi, yr, yi; 792 | 793 | ip[ipP + 0] = 0; 794 | l = n; 795 | m = 1; 796 | while ((m << 3) < l) { 797 | l >>= 1; 798 | for (j = 0; j < m; j++) { 799 | ip[ipP + m + j] = ip[ipP + j] + l; 800 | } 801 | m <<= 1; 802 | } 803 | m2 = 2 * m; 804 | if ((m << 3) == l) { 805 | for (k = 0; k < m; k++) { 806 | for (j = 0; j < k; j++) { 807 | j1 = 2 * j + ip[ipP + k]; 808 | k1 = 2 * k + ip[ipP + j]; 809 | xr = a[j1]; 810 | xi = a[j1 + 1]; 811 | yr = a[k1]; 812 | yi = a[k1 + 1]; 813 | a[j1] = yr; 814 | a[j1 + 1] = yi; 815 | a[k1] = xr; 816 | a[k1 + 1] = xi; 817 | j1 += m2; 818 | k1 += 2 * m2; 819 | xr = a[j1]; 820 | xi = a[j1 + 1]; 821 | yr = a[k1]; 822 | yi = a[k1 + 1]; 823 | a[j1] = yr; 824 | a[j1 + 1] = yi; 825 | a[k1] = xr; 826 | a[k1 + 1] = xi; 827 | j1 += m2; 828 | k1 -= m2; 829 | xr = a[j1]; 830 | xi = a[j1 + 1]; 831 | yr = a[k1]; 832 | yi = a[k1 + 1]; 833 | a[j1] = yr; 834 | a[j1 + 1] = yi; 835 | a[k1] = xr; 836 | a[k1 + 1] = xi; 837 | j1 += m2; 838 | k1 += 2 * m2; 839 | xr = a[j1]; 840 | xi = a[j1 + 1]; 841 | yr = a[k1]; 842 | yi = a[k1 + 1]; 843 | a[j1] = yr; 844 | a[j1 + 1] = yi; 845 | a[k1] = xr; 846 | a[k1 + 1] = xi; 847 | } 848 | j1 = 2 * k + m2 + ip[ipP + k]; 849 | k1 = j1 + m2; 850 | xr = a[j1]; 851 | xi = a[j1 + 1]; 852 | yr = a[k1]; 853 | yi = a[k1 + 1]; 854 | a[j1] = yr; 855 | a[j1 + 1] = yi; 856 | a[k1] = xr; 857 | a[k1 + 1] = xi; 858 | } 859 | } else { 860 | for (k = 1; k < m; k++) { 861 | for (j = 0; j < k; j++) { 862 | j1 = 2 * j + ip[ipP + k]; 863 | k1 = 2 * k + ip[ipP + j]; 864 | xr = a[j1]; 865 | xi = a[j1 + 1]; 866 | yr = a[k1]; 867 | yi = a[k1 + 1]; 868 | a[j1] = yr; 869 | a[j1 + 1] = yi; 870 | a[k1] = xr; 871 | a[k1 + 1] = xi; 872 | j1 += m2; 873 | k1 += m2; 874 | xr = a[j1]; 875 | xi = a[j1 + 1]; 876 | yr = a[k1]; 877 | yi = a[k1 + 1]; 878 | a[j1] = yr; 879 | a[j1 + 1] = yi; 880 | a[k1] = xr; 881 | a[k1 + 1] = xi; 882 | } 883 | } 884 | } 885 | } 886 | 887 | /** 888 | * 3rd 889 | * @see #cftbsub(int, double[], int[], int, int, double[]) 890 | */ 891 | private final void bitrv2conj(int n, int[] ip, int ipP, double[] a) { 892 | int j, j1, k, k1, l, m, m2; 893 | double xr, xi, yr, yi; 894 | 895 | ip[ipP + 0] = 0; 896 | l = n; 897 | m = 1; 898 | while ((m << 3) < l) { 899 | l >>= 1; 900 | for (j = 0; j < m; j++) { 901 | ip[ipP + m + j] = ip[ipP + j] + l; 902 | } 903 | m <<= 1; 904 | } 905 | m2 = 2 * m; 906 | if ((m << 3) == l) { 907 | for (k = 0; k < m; k++) { 908 | for (j = 0; j < k; j++) { 909 | j1 = 2 * j + ip[ipP + k]; 910 | k1 = 2 * k + ip[ipP + j]; 911 | xr = a[j1]; 912 | xi = -a[j1 + 1]; 913 | yr = a[k1]; 914 | yi = -a[k1 + 1]; 915 | a[j1] = yr; 916 | a[j1 + 1] = yi; 917 | a[k1] = xr; 918 | a[k1 + 1] = xi; 919 | j1 += m2; 920 | k1 += 2 * m2; 921 | xr = a[j1]; 922 | xi = -a[j1 + 1]; 923 | yr = a[k1]; 924 | yi = -a[k1 + 1]; 925 | a[j1] = yr; 926 | a[j1 + 1] = yi; 927 | a[k1] = xr; 928 | a[k1 + 1] = xi; 929 | j1 += m2; 930 | k1 -= m2; 931 | xr = a[j1]; 932 | xi = -a[j1 + 1]; 933 | yr = a[k1]; 934 | yi = -a[k1 + 1]; 935 | a[j1] = yr; 936 | a[j1 + 1] = yi; 937 | a[k1] = xr; 938 | a[k1 + 1] = xi; 939 | j1 += m2; 940 | k1 += 2 * m2; 941 | xr = a[j1]; 942 | xi = -a[j1 + 1]; 943 | yr = a[k1]; 944 | yi = -a[k1 + 1]; 945 | a[j1] = yr; 946 | a[j1 + 1] = yi; 947 | a[k1] = xr; 948 | a[k1 + 1] = xi; 949 | } 950 | k1 = 2 * k + ip[ipP + k]; 951 | a[k1 + 1] = -a[k1 + 1]; 952 | j1 = k1 + m2; 953 | k1 = j1 + m2; 954 | xr = a[j1]; 955 | xi = -a[j1 + 1]; 956 | yr = a[k1]; 957 | yi = -a[k1 + 1]; 958 | a[j1] = yr; 959 | a[j1 + 1] = yi; 960 | a[k1] = xr; 961 | a[k1 + 1] = xi; 962 | k1 += m2; 963 | a[k1 + 1] = -a[k1 + 1]; 964 | } 965 | } else { 966 | a[1] = -a[1]; 967 | a[m2 + 1] = -a[m2 + 1]; 968 | for (k = 1; k < m; k++) { 969 | for (j = 0; j < k; j++) { 970 | j1 = 2 * j + ip[ipP + k]; 971 | k1 = 2 * k + ip[ipP + j]; 972 | xr = a[j1]; 973 | xi = -a[j1 + 1]; 974 | yr = a[k1]; 975 | yi = -a[k1 + 1]; 976 | a[j1] = yr; 977 | a[j1 + 1] = yi; 978 | a[k1] = xr; 979 | a[k1 + 1] = xi; 980 | j1 += m2; 981 | k1 += m2; 982 | xr = a[j1]; 983 | xi = -a[j1 + 1]; 984 | yr = a[k1]; 985 | yi = -a[k1 + 1]; 986 | a[j1] = yr; 987 | a[j1 + 1] = yi; 988 | a[k1] = xr; 989 | a[k1 + 1] = xi; 990 | } 991 | k1 = 2 * k + ip[ipP + k]; 992 | a[k1 + 1] = -a[k1 + 1]; 993 | a[k1 + m2 + 1] = -a[k1 + m2 + 1]; 994 | } 995 | } 996 | } 997 | 998 | /** 999 | * 3rd 1000 | * @see #cftfsub(int, double[], int[], int, int, double[]) 1001 | */ 1002 | private void bitrv216(double[] a) { 1003 | double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; 1004 | 1005 | x1r = a[2]; 1006 | x1i = a[3]; 1007 | x2r = a[4]; 1008 | x2i = a[5]; 1009 | x3r = a[6]; 1010 | x3i = a[7]; 1011 | x4r = a[8]; 1012 | x4i = a[9]; 1013 | x5r = a[10]; 1014 | x5i = a[11]; 1015 | x7r = a[14]; 1016 | x7i = a[15]; 1017 | x8r = a[16]; 1018 | x8i = a[17]; 1019 | x10r = a[20]; 1020 | x10i = a[21]; 1021 | x11r = a[22]; 1022 | x11i = a[23]; 1023 | x12r = a[24]; 1024 | x12i = a[25]; 1025 | x13r = a[26]; 1026 | x13i = a[27]; 1027 | x14r = a[28]; 1028 | x14i = a[29]; 1029 | a[2] = x8r; 1030 | a[3] = x8i; 1031 | a[4] = x4r; 1032 | a[5] = x4i; 1033 | a[6] = x12r; 1034 | a[7] = x12i; 1035 | a[8] = x2r; 1036 | a[9] = x2i; 1037 | a[10] = x10r; 1038 | a[11] = x10i; 1039 | a[14] = x14r; 1040 | a[15] = x14i; 1041 | a[16] = x1r; 1042 | a[17] = x1i; 1043 | a[20] = x5r; 1044 | a[21] = x5i; 1045 | a[22] = x13r; 1046 | a[23] = x13i; 1047 | a[24] = x3r; 1048 | a[25] = x3i; 1049 | a[26] = x11r; 1050 | a[27] = x11i; 1051 | a[28] = x7r; 1052 | a[29] = x7i; 1053 | } 1054 | 1055 | /** 1056 | * 3rd 1057 | * @see #cftbsub(int, double[], int[], int, int, double[]) 1058 | */ 1059 | private void bitrv216neg(double[] a) { 1060 | double 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; 1061 | 1062 | x1r = a[2]; 1063 | x1i = a[3]; 1064 | x2r = a[4]; 1065 | x2i = a[5]; 1066 | x3r = a[6]; 1067 | x3i = a[7]; 1068 | x4r = a[8]; 1069 | x4i = a[9]; 1070 | x5r = a[10]; 1071 | x5i = a[11]; 1072 | x6r = a[12]; 1073 | x6i = a[13]; 1074 | x7r = a[14]; 1075 | x7i = a[15]; 1076 | x8r = a[16]; 1077 | x8i = a[17]; 1078 | x9r = a[18]; 1079 | x9i = a[19]; 1080 | x10r = a[20]; 1081 | x10i = a[21]; 1082 | x11r = a[22]; 1083 | x11i = a[23]; 1084 | x12r = a[24]; 1085 | x12i = a[25]; 1086 | x13r = a[26]; 1087 | x13i = a[27]; 1088 | x14r = a[28]; 1089 | x14i = a[29]; 1090 | x15r = a[30]; 1091 | x15i = a[31]; 1092 | a[2] = x15r; 1093 | a[3] = x15i; 1094 | a[4] = x7r; 1095 | a[5] = x7i; 1096 | a[6] = x11r; 1097 | a[7] = x11i; 1098 | a[8] = x3r; 1099 | a[9] = x3i; 1100 | a[10] = x13r; 1101 | a[11] = x13i; 1102 | a[12] = x5r; 1103 | a[13] = x5i; 1104 | a[14] = x9r; 1105 | a[15] = x9i; 1106 | a[16] = x1r; 1107 | a[17] = x1i; 1108 | a[18] = x14r; 1109 | a[19] = x14i; 1110 | a[20] = x6r; 1111 | a[21] = x6i; 1112 | a[22] = x10r; 1113 | a[23] = x10i; 1114 | a[24] = x2r; 1115 | a[25] = x2i; 1116 | a[26] = x12r; 1117 | a[27] = x12i; 1118 | a[28] = x4r; 1119 | a[29] = x4i; 1120 | a[30] = x8r; 1121 | a[31] = x8i; 1122 | } 1123 | 1124 | /** 1125 | * 3rd 1126 | * @see #cftfsub(int, double[], int[], int, int, double[]) 1127 | */ 1128 | private void bitrv208(double[] a) { 1129 | double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; 1130 | 1131 | x1r = a[2]; 1132 | x1i = a[3]; 1133 | x3r = a[6]; 1134 | x3i = a[7]; 1135 | x4r = a[8]; 1136 | x4i = a[9]; 1137 | x6r = a[12]; 1138 | x6i = a[13]; 1139 | a[2] = x4r; 1140 | a[3] = x4i; 1141 | a[6] = x6r; 1142 | a[7] = x6i; 1143 | a[8] = x1r; 1144 | a[9] = x1i; 1145 | a[12] = x3r; 1146 | a[13] = x3i; 1147 | } 1148 | 1149 | /** 1150 | * 3rd 1151 | * @see #cftbsub(int, double[], int[], int, int, double[]) 1152 | */ 1153 | private void bitrv208neg(double[] a) { 1154 | double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i; 1155 | 1156 | x1r = a[2]; 1157 | x1i = a[3]; 1158 | x2r = a[4]; 1159 | x2i = a[5]; 1160 | x3r = a[6]; 1161 | x3i = a[7]; 1162 | x4r = a[8]; 1163 | x4i = a[9]; 1164 | x5r = a[10]; 1165 | x5i = a[11]; 1166 | x6r = a[12]; 1167 | x6i = a[13]; 1168 | x7r = a[14]; 1169 | x7i = a[15]; 1170 | a[2] = x7r; 1171 | a[3] = x7i; 1172 | a[4] = x3r; 1173 | a[5] = x3i; 1174 | a[6] = x5r; 1175 | a[7] = x5i; 1176 | a[8] = x1r; 1177 | a[9] = x1i; 1178 | a[10] = x6r; 1179 | a[11] = x6i; 1180 | a[12] = x2r; 1181 | a[13] = x2i; 1182 | a[14] = x4r; 1183 | a[15] = x4i; 1184 | } 1185 | 1186 | /** 1187 | * 3rd 1188 | * @see #cftfsub(int, double[], int[], int, int, double[]) 1189 | */ 1190 | private void cftf1st(int n, double[] a, double[] w, int wP) { 1191 | int j, j0, j1, j2, j3, k, m, mh; 1192 | double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; 1193 | double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; 1194 | 1195 | mh = n >> 3; 1196 | m = 2 * mh; 1197 | j1 = m; 1198 | j2 = j1 + m; 1199 | j3 = j2 + m; 1200 | x0r = a[0] + a[j2]; 1201 | x0i = a[1] + a[j2 + 1]; 1202 | x1r = a[0] - a[j2]; 1203 | x1i = a[1] - a[j2 + 1]; 1204 | x2r = a[j1] + a[j3]; 1205 | x2i = a[j1 + 1] + a[j3 + 1]; 1206 | x3r = a[j1] - a[j3]; 1207 | x3i = a[j1 + 1] - a[j3 + 1]; 1208 | a[0] = x0r + x2r; 1209 | a[1] = x0i + x2i; 1210 | a[j1] = x0r - x2r; 1211 | a[j1 + 1] = x0i - x2i; 1212 | a[j2] = x1r - x3i; 1213 | a[j2 + 1] = x1i + x3r; 1214 | a[j3] = x1r + x3i; 1215 | a[j3 + 1] = x1i - x3r; 1216 | wn4r = w[wP + 1]; 1217 | csc1 = w[wP + 2]; 1218 | csc3 = w[wP + 3]; 1219 | wd1r = 1; 1220 | wd1i = 0; 1221 | wd3r = 1; 1222 | wd3i = 0; 1223 | k = 0; 1224 | for (j = 2; j < mh - 2; j += 4) { 1225 | k += 4; 1226 | wk1r = csc1 * (wd1r + w[wP + k]); 1227 | wk1i = csc1 * (wd1i + w[wP + k + 1]); 1228 | wk3r = csc3 * (wd3r + w[wP + k + 2]); 1229 | wk3i = csc3 * (wd3i - w[wP + k + 3]); 1230 | wd1r = w[wP + k]; 1231 | wd1i = w[wP + k + 1]; 1232 | wd3r = w[wP + k + 2]; 1233 | wd3i = -w[wP + k + 3]; 1234 | j1 = j + m; 1235 | j2 = j1 + m; 1236 | j3 = j2 + m; 1237 | x0r = a[j] + a[j2]; 1238 | x0i = a[j + 1] + a[j2 + 1]; 1239 | x1r = a[j] - a[j2]; 1240 | x1i = a[j + 1] - a[j2 + 1]; 1241 | y0r = a[j + 2] + a[j2 + 2]; 1242 | y0i = a[j + 3] + a[j2 + 3]; 1243 | y1r = a[j + 2] - a[j2 + 2]; 1244 | y1i = a[j + 3] - a[j2 + 3]; 1245 | x2r = a[j1] + a[j3]; 1246 | x2i = a[j1 + 1] + a[j3 + 1]; 1247 | x3r = a[j1] - a[j3]; 1248 | x3i = a[j1 + 1] - a[j3 + 1]; 1249 | y2r = a[j1 + 2] + a[j3 + 2]; 1250 | y2i = a[j1 + 3] + a[j3 + 3]; 1251 | y3r = a[j1 + 2] - a[j3 + 2]; 1252 | y3i = a[j1 + 3] - a[j3 + 3]; 1253 | a[j] = x0r + x2r; 1254 | a[j + 1] = x0i + x2i; 1255 | a[j + 2] = y0r + y2r; 1256 | a[j + 3] = y0i + y2i; 1257 | a[j1] = x0r - x2r; 1258 | a[j1 + 1] = x0i - x2i; 1259 | a[j1 + 2] = y0r - y2r; 1260 | a[j1 + 3] = y0i - y2i; 1261 | x0r = x1r - x3i; 1262 | x0i = x1i + x3r; 1263 | a[j2] = wk1r * x0r - wk1i * x0i; 1264 | a[j2 + 1] = wk1r * x0i + wk1i * x0r; 1265 | x0r = y1r - y3i; 1266 | x0i = y1i + y3r; 1267 | a[j2 + 2] = wd1r * x0r - wd1i * x0i; 1268 | a[j2 + 3] = wd1r * x0i + wd1i * x0r; 1269 | x0r = x1r + x3i; 1270 | x0i = x1i - x3r; 1271 | a[j3] = wk3r * x0r + wk3i * x0i; 1272 | a[j3 + 1] = wk3r * x0i - wk3i * x0r; 1273 | x0r = y1r + y3i; 1274 | x0i = y1i - y3r; 1275 | a[j3 + 2] = wd3r * x0r + wd3i * x0i; 1276 | a[j3 + 3] = wd3r * x0i - wd3i * x0r; 1277 | j0 = m - j; 1278 | j1 = j0 + m; 1279 | j2 = j1 + m; 1280 | j3 = j2 + m; 1281 | x0r = a[j0] + a[j2]; 1282 | x0i = a[j0 + 1] + a[j2 + 1]; 1283 | x1r = a[j0] - a[j2]; 1284 | x1i = a[j0 + 1] - a[j2 + 1]; 1285 | y0r = a[j0 - 2] + a[j2 - 2]; 1286 | y0i = a[j0 - 1] + a[j2 - 1]; 1287 | y1r = a[j0 - 2] - a[j2 - 2]; 1288 | y1i = a[j0 - 1] - a[j2 - 1]; 1289 | x2r = a[j1] + a[j3]; 1290 | x2i = a[j1 + 1] + a[j3 + 1]; 1291 | x3r = a[j1] - a[j3]; 1292 | x3i = a[j1 + 1] - a[j3 + 1]; 1293 | y2r = a[j1 - 2] + a[j3 - 2]; 1294 | y2i = a[j1 - 1] + a[j3 - 1]; 1295 | y3r = a[j1 - 2] - a[j3 - 2]; 1296 | y3i = a[j1 - 1] - a[j3 - 1]; 1297 | a[j0] = x0r + x2r; 1298 | a[j0 + 1] = x0i + x2i; 1299 | a[j0 - 2] = y0r + y2r; 1300 | a[j0 - 1] = y0i + y2i; 1301 | a[j1] = x0r - x2r; 1302 | a[j1 + 1] = x0i - x2i; 1303 | a[j1 - 2] = y0r - y2r; 1304 | a[j1 - 1] = y0i - y2i; 1305 | x0r = x1r - x3i; 1306 | x0i = x1i + x3r; 1307 | a[j2] = wk1i * x0r - wk1r * x0i; 1308 | a[j2 + 1] = wk1i * x0i + wk1r * x0r; 1309 | x0r = y1r - y3i; 1310 | x0i = y1i + y3r; 1311 | a[j2 - 2] = wd1i * x0r - wd1r * x0i; 1312 | a[j2 - 1] = wd1i * x0i + wd1r * x0r; 1313 | x0r = x1r + x3i; 1314 | x0i = x1i - x3r; 1315 | a[j3] = wk3i * x0r + wk3r * x0i; 1316 | a[j3 + 1] = wk3i * x0i - wk3r * x0r; 1317 | x0r = y1r + y3i; 1318 | x0i = y1i - y3r; 1319 | a[j3 - 2] = wd3i * x0r + wd3r * x0i; 1320 | a[j3 - 1] = wd3i * x0i - wd3r * x0r; 1321 | } 1322 | wk1r = csc1 * (wd1r + wn4r); 1323 | wk1i = csc1 * (wd1i + wn4r); 1324 | wk3r = csc3 * (wd3r - wn4r); 1325 | wk3i = csc3 * (wd3i - wn4r); 1326 | j0 = mh; 1327 | j1 = j0 + m; 1328 | j2 = j1 + m; 1329 | j3 = j2 + m; 1330 | x0r = a[j0 - 2] + a[j2 - 2]; 1331 | x0i = a[j0 - 1] + a[j2 - 1]; 1332 | x1r = a[j0 - 2] - a[j2 - 2]; 1333 | x1i = a[j0 - 1] - a[j2 - 1]; 1334 | x2r = a[j1 - 2] + a[j3 - 2]; 1335 | x2i = a[j1 - 1] + a[j3 - 1]; 1336 | x3r = a[j1 - 2] - a[j3 - 2]; 1337 | x3i = a[j1 - 1] - a[j3 - 1]; 1338 | a[j0 - 2] = x0r + x2r; 1339 | a[j0 - 1] = x0i + x2i; 1340 | a[j1 - 2] = x0r - x2r; 1341 | a[j1 - 1] = x0i - x2i; 1342 | x0r = x1r - x3i; 1343 | x0i = x1i + x3r; 1344 | a[j2 - 2] = wk1r * x0r - wk1i * x0i; 1345 | a[j2 - 1] = wk1r * x0i + wk1i * x0r; 1346 | x0r = x1r + x3i; 1347 | x0i = x1i - x3r; 1348 | a[j3 - 2] = wk3r * x0r + wk3i * x0i; 1349 | a[j3 - 1] = wk3r * x0i - wk3i * x0r; 1350 | x0r = a[j0] + a[j2]; 1351 | x0i = a[j0 + 1] + a[j2 + 1]; 1352 | x1r = a[j0] - a[j2]; 1353 | x1i = a[j0 + 1] - a[j2 + 1]; 1354 | x2r = a[j1] + a[j3]; 1355 | x2i = a[j1 + 1] + a[j3 + 1]; 1356 | x3r = a[j1] - a[j3]; 1357 | x3i = a[j1 + 1] - a[j3 + 1]; 1358 | a[j0] = x0r + x2r; 1359 | a[j0 + 1] = x0i + x2i; 1360 | a[j1] = x0r - x2r; 1361 | a[j1 + 1] = x0i - x2i; 1362 | x0r = x1r - x3i; 1363 | x0i = x1i + x3r; 1364 | a[j2] = wn4r * (x0r - x0i); 1365 | a[j2 + 1] = wn4r * (x0i + x0r); 1366 | x0r = x1r + x3i; 1367 | x0i = x1i - x3r; 1368 | a[j3] = -wn4r * (x0r + x0i); 1369 | a[j3 + 1] = -wn4r * (x0i - x0r); 1370 | x0r = a[j0 + 2] + a[j2 + 2]; 1371 | x0i = a[j0 + 3] + a[j2 + 3]; 1372 | x1r = a[j0 + 2] - a[j2 + 2]; 1373 | x1i = a[j0 + 3] - a[j2 + 3]; 1374 | x2r = a[j1 + 2] + a[j3 + 2]; 1375 | x2i = a[j1 + 3] + a[j3 + 3]; 1376 | x3r = a[j1 + 2] - a[j3 + 2]; 1377 | x3i = a[j1 + 3] - a[j3 + 3]; 1378 | a[j0 + 2] = x0r + x2r; 1379 | a[j0 + 3] = x0i + x2i; 1380 | a[j1 + 2] = x0r - x2r; 1381 | a[j1 + 3] = x0i - x2i; 1382 | x0r = x1r - x3i; 1383 | x0i = x1i + x3r; 1384 | a[j2 + 2] = wk1i * x0r - wk1r * x0i; 1385 | a[j2 + 3] = wk1i * x0i + wk1r * x0r; 1386 | x0r = x1r + x3i; 1387 | x0i = x1i - x3r; 1388 | a[j3 + 2] = wk3i * x0r + wk3r * x0i; 1389 | a[j3 + 3] = wk3i * x0i - wk3r * x0r; 1390 | } 1391 | 1392 | /** 1393 | * 3rd 1394 | * @see #cftbsub(int, double[], int[], int, int, double[]) 1395 | */ 1396 | private final void cftb1st(int n, double[] a, double[] w, int wP) { 1397 | int j, j0, j1, j2, j3, k, m, mh; 1398 | double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; 1399 | double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; 1400 | 1401 | mh = n >> 3; 1402 | m = 2 * mh; 1403 | j1 = m; 1404 | j2 = j1 + m; 1405 | j3 = j2 + m; 1406 | x0r = a[0] + a[j2]; 1407 | x0i = -a[1] - a[j2 + 1]; 1408 | x1r = a[0] - a[j2]; 1409 | x1i = -a[1] + a[j2 + 1]; 1410 | x2r = a[j1] + a[j3]; 1411 | x2i = a[j1 + 1] + a[j3 + 1]; 1412 | x3r = a[j1] - a[j3]; 1413 | x3i = a[j1 + 1] - a[j3 + 1]; 1414 | a[0] = x0r + x2r; 1415 | a[1] = x0i - x2i; 1416 | a[j1] = x0r - x2r; 1417 | a[j1 + 1] = x0i + x2i; 1418 | a[j2] = x1r + x3i; 1419 | a[j2 + 1] = x1i + x3r; 1420 | a[j3] = x1r - x3i; 1421 | a[j3 + 1] = x1i - x3r; 1422 | wn4r = w[wP + 1]; 1423 | csc1 = w[wP + 2]; 1424 | csc3 = w[wP + 3]; 1425 | wd1r = 1; 1426 | wd1i = 0; 1427 | wd3r = 1; 1428 | wd3i = 0; 1429 | k = 0; 1430 | for (j = 2; j < mh - 2; j += 4) { 1431 | k += 4; 1432 | wk1r = csc1 * (wd1r + w[wP + k]); 1433 | wk1i = csc1 * (wd1i + w[wP + k + 1]); 1434 | wk3r = csc3 * (wd3r + w[wP + k + 2]); 1435 | wk3i = csc3 * (wd3i - w[wP + k + 3]); 1436 | wd1r = w[wP + k]; 1437 | wd1i = w[wP + k + 1]; 1438 | wd3r = w[wP + k + 2]; 1439 | wd3i = -w[wP + k + 3]; 1440 | j1 = j + m; 1441 | j2 = j1 + m; 1442 | j3 = j2 + m; 1443 | x0r = a[j] + a[j2]; 1444 | x0i = -a[j + 1] - a[j2 + 1]; 1445 | x1r = a[j] - a[j2]; 1446 | x1i = -a[j + 1] + a[j2 + 1]; 1447 | y0r = a[j + 2] + a[j2 + 2]; 1448 | y0i = -a[j + 3] - a[j2 + 3]; 1449 | y1r = a[j + 2] - a[j2 + 2]; 1450 | y1i = -a[j + 3] + a[j2 + 3]; 1451 | x2r = a[j1] + a[j3]; 1452 | x2i = a[j1 + 1] + a[j3 + 1]; 1453 | x3r = a[j1] - a[j3]; 1454 | x3i = a[j1 + 1] - a[j3 + 1]; 1455 | y2r = a[j1 + 2] + a[j3 + 2]; 1456 | y2i = a[j1 + 3] + a[j3 + 3]; 1457 | y3r = a[j1 + 2] - a[j3 + 2]; 1458 | y3i = a[j1 + 3] - a[j3 + 3]; 1459 | a[j] = x0r + x2r; 1460 | a[j + 1] = x0i - x2i; 1461 | a[j + 2] = y0r + y2r; 1462 | a[j + 3] = y0i - y2i; 1463 | a[j1] = x0r - x2r; 1464 | a[j1 + 1] = x0i + x2i; 1465 | a[j1 + 2] = y0r - y2r; 1466 | a[j1 + 3] = y0i + y2i; 1467 | x0r = x1r + x3i; 1468 | x0i = x1i + x3r; 1469 | a[j2] = wk1r * x0r - wk1i * x0i; 1470 | a[j2 + 1] = wk1r * x0i + wk1i * x0r; 1471 | x0r = y1r + y3i; 1472 | x0i = y1i + y3r; 1473 | a[j2 + 2] = wd1r * x0r - wd1i * x0i; 1474 | a[j2 + 3] = wd1r * x0i + wd1i * x0r; 1475 | x0r = x1r - x3i; 1476 | x0i = x1i - x3r; 1477 | a[j3] = wk3r * x0r + wk3i * x0i; 1478 | a[j3 + 1] = wk3r * x0i - wk3i * x0r; 1479 | x0r = y1r - y3i; 1480 | x0i = y1i - y3r; 1481 | a[j3 + 2] = wd3r * x0r + wd3i * x0i; 1482 | a[j3 + 3] = wd3r * x0i - wd3i * x0r; 1483 | j0 = m - j; 1484 | j1 = j0 + m; 1485 | j2 = j1 + m; 1486 | j3 = j2 + m; 1487 | x0r = a[j0] + a[j2]; 1488 | x0i = -a[j0 + 1] - a[j2 + 1]; 1489 | x1r = a[j0] - a[j2]; 1490 | x1i = -a[j0 + 1] + a[j2 + 1]; 1491 | y0r = a[j0 - 2] + a[j2 - 2]; 1492 | y0i = -a[j0 - 1] - a[j2 - 1]; 1493 | y1r = a[j0 - 2] - a[j2 - 2]; 1494 | y1i = -a[j0 - 1] + a[j2 - 1]; 1495 | x2r = a[j1] + a[j3]; 1496 | x2i = a[j1 + 1] + a[j3 + 1]; 1497 | x3r = a[j1] - a[j3]; 1498 | x3i = a[j1 + 1] - a[j3 + 1]; 1499 | y2r = a[j1 - 2] + a[j3 - 2]; 1500 | y2i = a[j1 - 1] + a[j3 - 1]; 1501 | y3r = a[j1 - 2] - a[j3 - 2]; 1502 | y3i = a[j1 - 1] - a[j3 - 1]; 1503 | a[j0] = x0r + x2r; 1504 | a[j0 + 1] = x0i - x2i; 1505 | a[j0 - 2] = y0r + y2r; 1506 | a[j0 - 1] = y0i - y2i; 1507 | a[j1] = x0r - x2r; 1508 | a[j1 + 1] = x0i + x2i; 1509 | a[j1 - 2] = y0r - y2r; 1510 | a[j1 - 1] = y0i + y2i; 1511 | x0r = x1r + x3i; 1512 | x0i = x1i + x3r; 1513 | a[j2] = wk1i * x0r - wk1r * x0i; 1514 | a[j2 + 1] = wk1i * x0i + wk1r * x0r; 1515 | x0r = y1r + y3i; 1516 | x0i = y1i + y3r; 1517 | a[j2 - 2] = wd1i * x0r - wd1r * x0i; 1518 | a[j2 - 1] = wd1i * x0i + wd1r * x0r; 1519 | x0r = x1r - x3i; 1520 | x0i = x1i - x3r; 1521 | a[j3] = wk3i * x0r + wk3r * x0i; 1522 | a[j3 + 1] = wk3i * x0i - wk3r * x0r; 1523 | x0r = y1r - y3i; 1524 | x0i = y1i - y3r; 1525 | a[j3 - 2] = wd3i * x0r + wd3r * x0i; 1526 | a[j3 - 1] = wd3i * x0i - wd3r * x0r; 1527 | } 1528 | wk1r = csc1 * (wd1r + wn4r); 1529 | wk1i = csc1 * (wd1i + wn4r); 1530 | wk3r = csc3 * (wd3r - wn4r); 1531 | wk3i = csc3 * (wd3i - wn4r); 1532 | j0 = mh; 1533 | j1 = j0 + m; 1534 | j2 = j1 + m; 1535 | j3 = j2 + m; 1536 | x0r = a[j0 - 2] + a[j2 - 2]; 1537 | x0i = -a[j0 - 1] - a[j2 - 1]; 1538 | x1r = a[j0 - 2] - a[j2 - 2]; 1539 | x1i = -a[j0 - 1] + a[j2 - 1]; 1540 | x2r = a[j1 - 2] + a[j3 - 2]; 1541 | x2i = a[j1 - 1] + a[j3 - 1]; 1542 | x3r = a[j1 - 2] - a[j3 - 2]; 1543 | x3i = a[j1 - 1] - a[j3 - 1]; 1544 | a[j0 - 2] = x0r + x2r; 1545 | a[j0 - 1] = x0i - x2i; 1546 | a[j1 - 2] = x0r - x2r; 1547 | a[j1 - 1] = x0i + x2i; 1548 | x0r = x1r + x3i; 1549 | x0i = x1i + x3r; 1550 | a[j2 - 2] = wk1r * x0r - wk1i * x0i; 1551 | a[j2 - 1] = wk1r * x0i + wk1i * x0r; 1552 | x0r = x1r - x3i; 1553 | x0i = x1i - x3r; 1554 | a[j3 - 2] = wk3r * x0r + wk3i * x0i; 1555 | a[j3 - 1] = wk3r * x0i - wk3i * x0r; 1556 | x0r = a[j0] + a[j2]; 1557 | x0i = -a[j0 + 1] - a[j2 + 1]; 1558 | x1r = a[j0] - a[j2]; 1559 | x1i = -a[j0 + 1] + a[j2 + 1]; 1560 | x2r = a[j1] + a[j3]; 1561 | x2i = a[j1 + 1] + a[j3 + 1]; 1562 | x3r = a[j1] - a[j3]; 1563 | x3i = a[j1 + 1] - a[j3 + 1]; 1564 | a[j0] = x0r + x2r; 1565 | a[j0 + 1] = x0i - x2i; 1566 | a[j1] = x0r - x2r; 1567 | a[j1 + 1] = x0i + x2i; 1568 | x0r = x1r + x3i; 1569 | x0i = x1i + x3r; 1570 | a[j2] = wn4r * (x0r - x0i); 1571 | a[j2 + 1] = wn4r * (x0i + x0r); 1572 | x0r = x1r - x3i; 1573 | x0i = x1i - x3r; 1574 | a[j3] = -wn4r * (x0r + x0i); 1575 | a[j3 + 1] = -wn4r * (x0i - x0r); 1576 | x0r = a[j0 + 2] + a[j2 + 2]; 1577 | x0i = -a[j0 + 3] - a[j2 + 3]; 1578 | x1r = a[j0 + 2] - a[j2 + 2]; 1579 | x1i = -a[j0 + 3] + a[j2 + 3]; 1580 | x2r = a[j1 + 2] + a[j3 + 2]; 1581 | x2i = a[j1 + 3] + a[j3 + 3]; 1582 | x3r = a[j1 + 2] - a[j3 + 2]; 1583 | x3i = a[j1 + 3] - a[j3 + 3]; 1584 | a[j0 + 2] = x0r + x2r; 1585 | a[j0 + 3] = x0i - x2i; 1586 | a[j1 + 2] = x0r - x2r; 1587 | a[j1 + 3] = x0i + x2i; 1588 | x0r = x1r + x3i; 1589 | x0i = x1i + x3r; 1590 | a[j2 + 2] = wk1i * x0r - wk1r * x0i; 1591 | a[j2 + 3] = wk1i * x0i + wk1r * x0r; 1592 | x0r = x1r - x3i; 1593 | x0i = x1i - x3r; 1594 | a[j3 + 2] = wk3i * x0r + wk3r * x0i; 1595 | a[j3 + 3] = wk3i * x0i - wk3r * x0r; 1596 | } 1597 | 1598 | /** */ 1599 | private void cftrec1(int n, double[] a, int aP, int nw, double[] w) { 1600 | int m; 1601 | 1602 | m = n >> 2; 1603 | cftmdl1(n, a, aP, w, nw - 2 * m); 1604 | if (n > CDFT_RECURSIVE_N) { 1605 | cftrec1(m, a, aP, nw, w); 1606 | cftrec2(m, a, aP + m, nw, w); 1607 | cftrec1(m, a, aP + 2 * m, nw, w); 1608 | cftrec1(m, a, aP + 3 * m, nw, w); 1609 | } else { 1610 | cftexp1(n, a, aP, nw, w); 1611 | } 1612 | } 1613 | 1614 | /** */ 1615 | private void cftrec2(int n, double[] a, int aP, int nw, double[] w) { 1616 | int m; 1617 | 1618 | m = n >> 2; 1619 | cftmdl2(n, a, aP, w, nw - n); 1620 | if (n > CDFT_RECURSIVE_N) { 1621 | cftrec1(m, a, aP, nw, w); 1622 | cftrec2(m, a, aP + m, nw, w); 1623 | cftrec1(m, a, aP + 2 * m, nw, w); 1624 | cftrec2(m, a, aP + 3 * m, nw, w); 1625 | } else { 1626 | cftexp2(n, a, aP, nw, w); 1627 | } 1628 | } 1629 | 1630 | /** */ 1631 | private void cftexp1(int n, double[] a, int aP, int nw, double[] w) { 1632 | int j, k, l; 1633 | 1634 | l = n >> 2; 1635 | while (l > 128) { 1636 | for (k = l; k < n; k <<= 2) { 1637 | for (j = k - l; j < n; j += 4 * k) { 1638 | cftmdl1(l, a, aP + j, w, nw - (l >> 1)); 1639 | cftmdl2(l, a, aP + k + j, w, nw - l); 1640 | cftmdl1(l, a, aP + 2 * k + j, w, nw - (l >> 1)); 1641 | } 1642 | } 1643 | cftmdl1(l, a, aP + n - l, w, nw - (l >> 1)); 1644 | l >>= 2; 1645 | } 1646 | for (k = l; k < n; k <<= 2) { 1647 | for (j = k - l; j < n; j += 4 * k) { 1648 | cftmdl1(l, a, aP + j, w, nw - (l >> 1)); 1649 | cftfx41(l, a, aP + j, nw, w); 1650 | cftmdl2(l, a, aP + k + j, w, nw - l); 1651 | cftfx42(l, a, aP + k + j, nw, w); 1652 | cftmdl1(l, a, aP + 2 * k + j, w, nw - (l >> 1)); 1653 | cftfx41(l, a, aP + 2 * k + j, nw, w); 1654 | } 1655 | } 1656 | cftmdl1(l, a, aP + n - l, w, nw - (l >> 1)); 1657 | cftfx41(l, a, aP + n - l, nw, w); 1658 | } 1659 | 1660 | /** */ 1661 | private void cftexp2(int n, double[] a, int aP, int nw, double[] w) { 1662 | int j, k, l, m; 1663 | 1664 | m = n >> 1; 1665 | l = n >> 2; 1666 | while (l > 128) { 1667 | for (k = l; k < m; k <<= 2) { 1668 | for (j = k - l; j < m; j += 2 * k) { 1669 | cftmdl1(l, a, aP + j, w, nw - (l >> 1)); 1670 | cftmdl1(l, a, aP + m + j, w, nw - (l >> 1)); 1671 | } 1672 | for (j = 2 * k - l; j < m; j += 4 * k) { 1673 | cftmdl2(l, a, aP + j, w, nw - l); 1674 | cftmdl2(l, a, aP + m + j, w, nw - l); 1675 | } 1676 | } 1677 | l >>= 2; 1678 | } 1679 | for (k = l; k < m; k <<= 2) { 1680 | for (j = k - l; j < m; j += 2 * k) { 1681 | cftmdl1(l, a, aP + j, w, nw - (l >> 1)); 1682 | cftfx41(l, a, aP + j, nw, w); 1683 | cftmdl1(l, a, aP + m + j, w, nw - (l >> 1)); 1684 | cftfx41(l, a, aP + m + j, nw, w); 1685 | } 1686 | for (j = 2 * k - l; j < m; j += 4 * k) { 1687 | cftmdl2(l, a, aP + j, w, nw - l); 1688 | cftfx42(l, a, aP + j, nw, w); 1689 | cftmdl2(l, a, aP + m + j, w, nw - l); 1690 | cftfx42(l, a, aP + m + j, nw, w); 1691 | } 1692 | } 1693 | } 1694 | 1695 | /** */ 1696 | private final void cftmdl1(int n, double[] a, int aP, double[] w, int wP) { 1697 | int j, j0, j1, j2, j3, k, m, mh; 1698 | double wn4r, wk1r, wk1i, wk3r, wk3i; 1699 | double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; 1700 | 1701 | mh = n >> 3; 1702 | m = 2 * mh; 1703 | j1 = m; 1704 | j2 = j1 + m; 1705 | j3 = j2 + m; 1706 | x0r = a[aP + 0] + a[aP + j2]; 1707 | x0i = a[aP + 1] + a[aP + j2 + 1]; 1708 | x1r = a[aP + 0] - a[aP + j2]; 1709 | x1i = a[aP + 1] - a[aP + j2 + 1]; 1710 | x2r = a[aP + j1] + a[aP + j3]; 1711 | x2i = a[aP + j1 + 1] + a[aP + j3 + 1]; 1712 | x3r = a[aP + j1] - a[aP + j3]; 1713 | x3i = a[aP + j1 + 1] - a[aP + j3 + 1]; 1714 | a[aP + 0] = x0r + x2r; 1715 | a[aP + 1] = x0i + x2i; 1716 | a[aP + j1] = x0r - x2r; 1717 | a[aP + j1 + 1] = x0i - x2i; 1718 | a[aP + j2] = x1r - x3i; 1719 | a[aP + j2 + 1] = x1i + x3r; 1720 | a[aP + j3] = x1r + x3i; 1721 | a[aP + j3 + 1] = x1i - x3r; 1722 | wn4r = w[wP + 1]; 1723 | k = 0; 1724 | for (j = 2; j < mh; j += 2) { 1725 | k += 4; 1726 | wk1r = w[wP + k]; 1727 | wk1i = w[wP + k + 1]; 1728 | wk3r = w[wP + k + 2]; 1729 | wk3i = -w[wP + k + 3]; 1730 | j1 = j + m; 1731 | j2 = j1 + m; 1732 | j3 = j2 + m; 1733 | x0r = a[aP + j] + a[aP + j2]; 1734 | x0i = a[aP + j + 1] + a[aP + j2 + 1]; 1735 | x1r = a[aP + j] - a[aP + j2]; 1736 | x1i = a[aP + j + 1] - a[aP + j2 + 1]; 1737 | x2r = a[aP + j1] + a[aP + j3]; 1738 | x2i = a[aP + j1 + 1] + a[aP + j3 + 1]; 1739 | x3r = a[aP + j1] - a[aP + j3]; 1740 | x3i = a[aP + j1 + 1] - a[aP + j3 + 1]; 1741 | a[aP + j] = x0r + x2r; 1742 | a[aP + j + 1] = x0i + x2i; 1743 | a[aP + j1] = x0r - x2r; 1744 | a[aP + j1 + 1] = x0i - x2i; 1745 | x0r = x1r - x3i; 1746 | x0i = x1i + x3r; 1747 | a[aP + j2] = wk1r * x0r - wk1i * x0i; 1748 | a[aP + j2 + 1] = wk1r * x0i + wk1i * x0r; 1749 | x0r = x1r + x3i; 1750 | x0i = x1i - x3r; 1751 | a[aP + j3] = wk3r * x0r + wk3i * x0i; 1752 | a[aP + j3 + 1] = wk3r * x0i - wk3i * x0r; 1753 | j0 = m - j; 1754 | j1 = j0 + m; 1755 | j2 = j1 + m; 1756 | j3 = j2 + m; 1757 | x0r = a[aP + j0] + a[aP + j2]; 1758 | x0i = a[aP + j0 + 1] + a[aP + j2 + 1]; 1759 | x1r = a[aP + j0] - a[aP + j2]; 1760 | x1i = a[aP + j0 + 1] - a[aP + j2 + 1]; 1761 | x2r = a[aP + j1] + a[aP + j3]; 1762 | x2i = a[aP + j1 + 1] + a[aP + j3 + 1]; 1763 | x3r = a[aP + j1] - a[aP + j3]; 1764 | x3i = a[aP + j1 + 1] - a[aP + j3 + 1]; 1765 | a[aP + j0] = x0r + x2r; 1766 | a[aP + j0 + 1] = x0i + x2i; 1767 | a[aP + j1] = x0r - x2r; 1768 | a[aP + j1 + 1] = x0i - x2i; 1769 | x0r = x1r - x3i; 1770 | x0i = x1i + x3r; 1771 | a[aP + j2] = wk1i * x0r - wk1r * x0i; 1772 | a[aP + j2 + 1] = wk1i * x0i + wk1r * x0r; 1773 | x0r = x1r + x3i; 1774 | x0i = x1i - x3r; 1775 | a[aP + j3] = wk3i * x0r + wk3r * x0i; 1776 | a[aP + j3 + 1] = wk3i * x0i - wk3r * x0r; 1777 | } 1778 | j0 = mh; 1779 | j1 = j0 + m; 1780 | j2 = j1 + m; 1781 | j3 = j2 + m; 1782 | x0r = a[aP + j0] + a[aP + j2]; 1783 | x0i = a[aP + j0 + 1] + a[aP + j2 + 1]; 1784 | x1r = a[aP + j0] - a[aP + j2]; 1785 | x1i = a[aP + j0 + 1] - a[aP + j2 + 1]; 1786 | x2r = a[aP + j1] + a[aP + j3]; 1787 | x2i = a[aP + j1 + 1] + a[aP + j3 + 1]; 1788 | x3r = a[aP + j1] - a[aP + j3]; 1789 | x3i = a[aP + j1 + 1] - a[aP + j3 + 1]; 1790 | a[aP + j0] = x0r + x2r; 1791 | a[aP + j0 + 1] = x0i + x2i; 1792 | a[aP + j1] = x0r - x2r; 1793 | a[aP + j1 + 1] = x0i - x2i; 1794 | x0r = x1r - x3i; 1795 | x0i = x1i + x3r; 1796 | a[aP + j2] = wn4r * (x0r - x0i); 1797 | a[aP + j2 + 1] = wn4r * (x0i + x0r); 1798 | x0r = x1r + x3i; 1799 | x0i = x1i - x3r; 1800 | a[aP + j3] = -wn4r * (x0r + x0i); 1801 | a[aP + j3 + 1] = -wn4r * (x0i - x0r); 1802 | } 1803 | 1804 | /** */ 1805 | private final void cftmdl2(int n, double[] a, int aP, double[] w, int wP) { 1806 | int j, j0, j1, j2, j3, k, kr, m, mh; 1807 | double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; 1808 | double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; 1809 | 1810 | mh = n >> 3; 1811 | m = 2 * mh; 1812 | wn4r = w[wP + 1]; 1813 | j1 = m; 1814 | j2 = j1 + m; 1815 | j3 = j2 + m; 1816 | x0r = a[aP + 0] - a[aP + j2 + 1]; 1817 | x0i = a[aP + 1] + a[aP + j2]; 1818 | x1r = a[aP + 0] + a[aP + j2 + 1]; 1819 | x1i = a[aP + 1] - a[aP + j2]; 1820 | x2r = a[aP + j1] - a[aP + j3 + 1]; 1821 | x2i = a[aP + j1 + 1] + a[aP + j3]; 1822 | x3r = a[aP + j1] + a[aP + j3 + 1]; 1823 | x3i = a[aP + j1 + 1] - a[aP + j3]; 1824 | y0r = wn4r * (x2r - x2i); 1825 | y0i = wn4r * (x2i + x2r); 1826 | a[aP + 0] = x0r + y0r; 1827 | a[aP + 1] = x0i + y0i; 1828 | a[aP + j1] = x0r - y0r; 1829 | a[aP + j1 + 1] = x0i - y0i; 1830 | y0r = wn4r * (x3r - x3i); 1831 | y0i = wn4r * (x3i + x3r); 1832 | a[aP + j2] = x1r - y0i; 1833 | a[aP + j2 + 1] = x1i + y0r; 1834 | a[aP + j3] = x1r + y0i; 1835 | a[aP + j3 + 1] = x1i - y0r; 1836 | k = 0; 1837 | kr = 2 * m; 1838 | for (j = 2; j < mh; j += 2) { 1839 | k += 4; 1840 | wk1r = w[wP + k]; 1841 | wk1i = w[wP + k + 1]; 1842 | wk3r = w[wP + k + 2]; 1843 | wk3i = -w[wP + k + 3]; 1844 | kr -= 4; 1845 | wd1i = w[wP + kr]; 1846 | wd1r = w[wP + kr + 1]; 1847 | wd3i = w[wP + kr + 2]; 1848 | wd3r = -w[wP + kr + 3]; 1849 | j1 = j + m; 1850 | j2 = j1 + m; 1851 | j3 = j2 + m; 1852 | x0r = a[aP + j] - a[aP + j2 + 1]; 1853 | x0i = a[aP + j + 1] + a[aP + j2]; 1854 | x1r = a[aP + j] + a[aP + j2 + 1]; 1855 | x1i = a[aP + j + 1] - a[aP + j2]; 1856 | x2r = a[aP + j1] - a[aP + j3 + 1]; 1857 | x2i = a[aP + j1 + 1] + a[aP + j3]; 1858 | x3r = a[aP + j1] + a[aP + j3 + 1]; 1859 | x3i = a[aP + j1 + 1] - a[aP + j3]; 1860 | y0r = wk1r * x0r - wk1i * x0i; 1861 | y0i = wk1r * x0i + wk1i * x0r; 1862 | y2r = wd1r * x2r - wd1i * x2i; 1863 | y2i = wd1r * x2i + wd1i * x2r; 1864 | a[aP + j] = y0r + y2r; 1865 | a[aP + j + 1] = y0i + y2i; 1866 | a[aP + j1] = y0r - y2r; 1867 | a[aP + j1 + 1] = y0i - y2i; 1868 | y0r = wk3r * x1r + wk3i * x1i; 1869 | y0i = wk3r * x1i - wk3i * x1r; 1870 | y2r = wd3r * x3r + wd3i * x3i; 1871 | y2i = wd3r * x3i - wd3i * x3r; 1872 | a[aP + j2] = y0r + y2r; 1873 | a[aP + j2 + 1] = y0i + y2i; 1874 | a[aP + j3] = y0r - y2r; 1875 | a[aP + j3 + 1] = y0i - y2i; 1876 | j0 = m - j; 1877 | j1 = j0 + m; 1878 | j2 = j1 + m; 1879 | j3 = j2 + m; 1880 | x0r = a[aP + j0] - a[aP + j2 + 1]; 1881 | x0i = a[aP + j0 + 1] + a[aP + j2]; 1882 | x1r = a[aP + j0] + a[aP + j2 + 1]; 1883 | x1i = a[aP + j0 + 1] - a[aP + j2]; 1884 | x2r = a[aP + j1] - a[aP + j3 + 1]; 1885 | x2i = a[aP + j1 + 1] + a[aP + j3]; 1886 | x3r = a[aP + j1] + a[aP + j3 + 1]; 1887 | x3i = a[aP + j1 + 1] - a[aP + j3]; 1888 | y0r = wd1i * x0r - wd1r * x0i; 1889 | y0i = wd1i * x0i + wd1r * x0r; 1890 | y2r = wk1i * x2r - wk1r * x2i; 1891 | y2i = wk1i * x2i + wk1r * x2r; 1892 | a[aP + j0] = y0r + y2r; 1893 | a[aP + j0 + 1] = y0i + y2i; 1894 | a[aP + j1] = y0r - y2r; 1895 | a[aP + j1 + 1] = y0i - y2i; 1896 | y0r = wd3i * x1r + wd3r * x1i; 1897 | y0i = wd3i * x1i - wd3r * x1r; 1898 | y2r = wk3i * x3r + wk3r * x3i; 1899 | y2i = wk3i * x3i - wk3r * x3r; 1900 | a[aP + j2] = y0r + y2r; 1901 | a[aP + j2 + 1] = y0i + y2i; 1902 | a[aP + j3] = y0r - y2r; 1903 | a[aP + j3 + 1] = y0i - y2i; 1904 | } 1905 | wk1r = w[wP + m]; 1906 | wk1i = w[wP + m + 1]; 1907 | j0 = mh; 1908 | j1 = j0 + m; 1909 | j2 = j1 + m; 1910 | j3 = j2 + m; 1911 | x0r = a[aP + j0] - a[aP + j2 + 1]; 1912 | x0i = a[aP + j0 + 1] + a[aP + j2]; 1913 | x1r = a[aP + j0] + a[aP + j2 + 1]; 1914 | x1i = a[aP + j0 + 1] - a[aP + j2]; 1915 | x2r = a[aP + j1] - a[aP + j3 + 1]; 1916 | x2i = a[aP + j1 + 1] + a[aP + j3]; 1917 | x3r = a[aP + j1] + a[aP + j3 + 1]; 1918 | x3i = a[aP + j1 + 1] - a[aP + j3]; 1919 | y0r = wk1r * x0r - wk1i * x0i; 1920 | y0i = wk1r * x0i + wk1i * x0r; 1921 | y2r = wk1i * x2r - wk1r * x2i; 1922 | y2i = wk1i * x2i + wk1r * x2r; 1923 | a[aP + j0] = y0r + y2r; 1924 | a[aP + j0 + 1] = y0i + y2i; 1925 | a[aP + j1] = y0r - y2r; 1926 | a[aP + j1 + 1] = y0i - y2i; 1927 | y0r = wk1i * x1r - wk1r * x1i; 1928 | y0i = wk1i * x1i + wk1r * x1r; 1929 | y2r = wk1r * x3r - wk1i * x3i; 1930 | y2i = wk1r * x3i + wk1i * x3r; 1931 | a[aP + j2] = y0r - y2r; 1932 | a[aP + j2 + 1] = y0i - y2i; 1933 | a[aP + j3] = y0r + y2r; 1934 | a[aP + j3 + 1] = y0i + y2i; 1935 | } 1936 | 1937 | /** */ 1938 | private void cftfx41(int n, double[] a, int aP, int nw, double[] w) { 1939 | if (n == 128) { 1940 | cftf161(a, aP, w, nw - 8); 1941 | cftf162(a, aP + 32, w, nw - 32); 1942 | cftf161(a, aP + 64, w, nw - 8); 1943 | cftf161(a, aP + 96, w, nw - 8); 1944 | } else { 1945 | cftf081(a, aP, w, nw - 16); 1946 | cftf082(a, aP + 16, w, nw - 16); 1947 | cftf081(a, aP + 32, w, nw - 16); 1948 | cftf081(a, aP + 48, w, nw - 16); 1949 | } 1950 | } 1951 | 1952 | /** */ 1953 | private void cftfx42(int n, double[] a, int aP, int nw, double[] w) { 1954 | if (n == 128) { 1955 | cftf161(a, aP, w, nw - 8); 1956 | cftf162(a, aP + 32, w, nw - 32); 1957 | cftf161(a, aP + 64, w, nw - 8); 1958 | cftf162(a, aP + 96, w, nw - 32); 1959 | } else { 1960 | cftf081(a, aP, w, nw - 16); 1961 | cftf082(a, aP + 16, w, nw - 16); 1962 | cftf081(a, aP + 32, w, nw - 16); 1963 | cftf082(a, aP + 48, w, nw - 16); 1964 | } 1965 | } 1966 | 1967 | /** */ 1968 | private void cftf161(double[] a, int aP, double[] w, int wP) { 1969 | double 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; 1970 | 1971 | wn4r = w[wP + 1]; 1972 | wk1i = wn4r * w[wP + 2]; 1973 | wk1r = wk1i + w[wP + 2]; 1974 | x0r = a[aP + 0] + a[aP + 16]; 1975 | x0i = a[aP + 1] + a[aP + 17]; 1976 | x1r = a[aP + 0] - a[aP + 16]; 1977 | x1i = a[aP + 1] - a[aP + 17]; 1978 | x2r = a[aP + 8] + a[aP + 24]; 1979 | x2i = a[aP + 9] + a[aP + 25]; 1980 | x3r = a[aP + 8] - a[aP + 24]; 1981 | x3i = a[aP + 9] - a[aP + 25]; 1982 | y0r = x0r + x2r; 1983 | y0i = x0i + x2i; 1984 | y4r = x0r - x2r; 1985 | y4i = x0i - x2i; 1986 | y8r = x1r - x3i; 1987 | y8i = x1i + x3r; 1988 | y12r = x1r + x3i; 1989 | y12i = x1i - x3r; 1990 | x0r = a[aP + 2] + a[aP + 18]; 1991 | x0i = a[aP + 3] + a[aP + 19]; 1992 | x1r = a[aP + 2] - a[aP + 18]; 1993 | x1i = a[aP + 3] - a[aP + 19]; 1994 | x2r = a[aP + 10] + a[aP + 26]; 1995 | x2i = a[aP + 11] + a[aP + 27]; 1996 | x3r = a[aP + 10] - a[aP + 26]; 1997 | x3i = a[aP + 11] - a[aP + 27]; 1998 | y1r = x0r + x2r; 1999 | y1i = x0i + x2i; 2000 | y5r = x0r - x2r; 2001 | y5i = x0i - x2i; 2002 | x0r = x1r - x3i; 2003 | x0i = x1i + x3r; 2004 | y9r = wk1r * x0r - wk1i * x0i; 2005 | y9i = wk1r * x0i + wk1i * x0r; 2006 | x0r = x1r + x3i; 2007 | x0i = x1i - x3r; 2008 | y13r = wk1i * x0r - wk1r * x0i; 2009 | y13i = wk1i * x0i + wk1r * x0r; 2010 | x0r = a[aP + 4] + a[aP + 20]; 2011 | x0i = a[aP + 5] + a[aP + 21]; 2012 | x1r = a[aP + 4] - a[aP + 20]; 2013 | x1i = a[aP + 5] - a[aP + 21]; 2014 | x2r = a[aP + 12] + a[aP + 28]; 2015 | x2i = a[aP + 13] + a[aP + 29]; 2016 | x3r = a[aP + 12] - a[aP + 28]; 2017 | x3i = a[aP + 13] - a[aP + 29]; 2018 | y2r = x0r + x2r; 2019 | y2i = x0i + x2i; 2020 | y6r = x0r - x2r; 2021 | y6i = x0i - x2i; 2022 | x0r = x1r - x3i; 2023 | x0i = x1i + x3r; 2024 | y10r = wn4r * (x0r - x0i); 2025 | y10i = wn4r * (x0i + x0r); 2026 | x0r = x1r + x3i; 2027 | x0i = x1i - x3r; 2028 | y14r = wn4r * (x0r + x0i); 2029 | y14i = wn4r * (x0i - x0r); 2030 | x0r = a[aP + 6] + a[aP + 22]; 2031 | x0i = a[aP + 7] + a[aP + 23]; 2032 | x1r = a[aP + 6] - a[aP + 22]; 2033 | x1i = a[aP + 7] - a[aP + 23]; 2034 | x2r = a[aP + 14] + a[aP + 30]; 2035 | x2i = a[aP + 15] + a[aP + 31]; 2036 | x3r = a[aP + 14] - a[aP + 30]; 2037 | x3i = a[aP + 15] - a[aP + 31]; 2038 | y3r = x0r + x2r; 2039 | y3i = x0i + x2i; 2040 | y7r = x0r - x2r; 2041 | y7i = x0i - x2i; 2042 | x0r = x1r - x3i; 2043 | x0i = x1i + x3r; 2044 | y11r = wk1i * x0r - wk1r * x0i; 2045 | y11i = wk1i * x0i + wk1r * x0r; 2046 | x0r = x1r + x3i; 2047 | x0i = x1i - x3r; 2048 | y15r = wk1r * x0r - wk1i * x0i; 2049 | y15i = wk1r * x0i + wk1i * x0r; 2050 | x0r = y12r - y14r; 2051 | x0i = y12i - y14i; 2052 | x1r = y12r + y14r; 2053 | x1i = y12i + y14i; 2054 | x2r = y13r - y15r; 2055 | x2i = y13i - y15i; 2056 | x3r = y13r + y15r; 2057 | x3i = y13i + y15i; 2058 | a[aP + 24] = x0r + x2r; 2059 | a[aP + 25] = x0i + x2i; 2060 | a[aP + 26] = x0r - x2r; 2061 | a[aP + 27] = x0i - x2i; 2062 | a[aP + 28] = x1r - x3i; 2063 | a[aP + 29] = x1i + x3r; 2064 | a[aP + 30] = x1r + x3i; 2065 | a[aP + 31] = x1i - x3r; 2066 | x0r = y8r + y10r; 2067 | x0i = y8i + y10i; 2068 | x1r = y8r - y10r; 2069 | x1i = y8i - y10i; 2070 | x2r = y9r + y11r; 2071 | x2i = y9i + y11i; 2072 | x3r = y9r - y11r; 2073 | x3i = y9i - y11i; 2074 | a[aP + 16] = x0r + x2r; 2075 | a[aP + 17] = x0i + x2i; 2076 | a[aP + 18] = x0r - x2r; 2077 | a[aP + 19] = x0i - x2i; 2078 | a[aP + 20] = x1r - x3i; 2079 | a[aP + 21] = x1i + x3r; 2080 | a[aP + 22] = x1r + x3i; 2081 | a[aP + 23] = x1i - x3r; 2082 | x0r = y5r - y7i; 2083 | x0i = y5i + y7r; 2084 | x2r = wn4r * (x0r - x0i); 2085 | x2i = wn4r * (x0i + x0r); 2086 | x0r = y5r + y7i; 2087 | x0i = y5i - y7r; 2088 | x3r = wn4r * (x0r - x0i); 2089 | x3i = wn4r * (x0i + x0r); 2090 | x0r = y4r - y6i; 2091 | x0i = y4i + y6r; 2092 | x1r = y4r + y6i; 2093 | x1i = y4i - y6r; 2094 | a[aP + 8] = x0r + x2r; 2095 | a[aP + 9] = x0i + x2i; 2096 | a[aP + 10] = x0r - x2r; 2097 | a[aP + 11] = x0i - x2i; 2098 | a[aP + 12] = x1r - x3i; 2099 | a[aP + 13] = x1i + x3r; 2100 | a[aP + 14] = x1r + x3i; 2101 | a[aP + 15] = x1i - x3r; 2102 | x0r = y0r + y2r; 2103 | x0i = y0i + y2i; 2104 | x1r = y0r - y2r; 2105 | x1i = y0i - y2i; 2106 | x2r = y1r + y3r; 2107 | x2i = y1i + y3i; 2108 | x3r = y1r - y3r; 2109 | x3i = y1i - y3i; 2110 | a[aP + 0] = x0r + x2r; 2111 | a[aP + 1] = x0i + x2i; 2112 | a[aP + 2] = x0r - x2r; 2113 | a[aP + 3] = x0i - x2i; 2114 | a[aP + 4] = x1r - x3i; 2115 | a[aP + 5] = x1i + x3r; 2116 | a[aP + 6] = x1r + x3i; 2117 | a[aP + 7] = x1i - x3r; 2118 | } 2119 | 2120 | /** */ 2121 | private void cftf162(double[] a, int aP, double[] w, int wP) { 2122 | double 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; 2123 | 2124 | wn4r = w[wP + 1]; 2125 | wk1r = w[wP + 4]; 2126 | wk1i = w[wP + 5]; 2127 | wk3r = w[wP + 6]; 2128 | wk3i = w[wP + 7]; 2129 | wk2r = w[wP + 8]; 2130 | wk2i = w[wP + 9]; 2131 | x1r = a[aP + 0] - a[aP + 17]; 2132 | x1i = a[aP + 1] + a[aP + 16]; 2133 | x0r = a[aP + 8] - a[aP + 25]; 2134 | x0i = a[aP + 9] + a[aP + 24]; 2135 | x2r = wn4r * (x0r - x0i); 2136 | x2i = wn4r * (x0i + x0r); 2137 | y0r = x1r + x2r; 2138 | y0i = x1i + x2i; 2139 | y4r = x1r - x2r; 2140 | y4i = x1i - x2i; 2141 | x1r = a[aP + 0] + a[aP + 17]; 2142 | x1i = a[aP + 1] - a[aP + 16]; 2143 | x0r = a[aP + 8] + a[aP + 25]; 2144 | x0i = a[aP + 9] - a[aP + 24]; 2145 | x2r = wn4r * (x0r - x0i); 2146 | x2i = wn4r * (x0i + x0r); 2147 | y8r = x1r - x2i; 2148 | y8i = x1i + x2r; 2149 | y12r = x1r + x2i; 2150 | y12i = x1i - x2r; 2151 | x0r = a[aP + 2] - a[aP + 19]; 2152 | x0i = a[aP + 3] + a[aP + 18]; 2153 | x1r = wk1r * x0r - wk1i * x0i; 2154 | x1i = wk1r * x0i + wk1i * x0r; 2155 | x0r = a[aP + 10] - a[aP + 27]; 2156 | x0i = a[aP + 11] + a[aP + 26]; 2157 | x2r = wk3i * x0r - wk3r * x0i; 2158 | x2i = wk3i * x0i + wk3r * x0r; 2159 | y1r = x1r + x2r; 2160 | y1i = x1i + x2i; 2161 | y5r = x1r - x2r; 2162 | y5i = x1i - x2i; 2163 | x0r = a[aP + 2] + a[aP + 19]; 2164 | x0i = a[aP + 3] - a[aP + 18]; 2165 | x1r = wk3r * x0r - wk3i * x0i; 2166 | x1i = wk3r * x0i + wk3i * x0r; 2167 | x0r = a[aP + 10] + a[aP + 27]; 2168 | x0i = a[aP + 11] - a[aP + 26]; 2169 | x2r = wk1r * x0r + wk1i * x0i; 2170 | x2i = wk1r * x0i - wk1i * x0r; 2171 | y9r = x1r - x2r; 2172 | y9i = x1i - x2i; 2173 | y13r = x1r + x2r; 2174 | y13i = x1i + x2i; 2175 | x0r = a[aP + 4] - a[aP + 21]; 2176 | x0i = a[aP + 5] + a[aP + 20]; 2177 | x1r = wk2r * x0r - wk2i * x0i; 2178 | x1i = wk2r * x0i + wk2i * x0r; 2179 | x0r = a[aP + 12] - a[aP + 29]; 2180 | x0i = a[aP + 13] + a[aP + 28]; 2181 | x2r = wk2i * x0r - wk2r * x0i; 2182 | x2i = wk2i * x0i + wk2r * x0r; 2183 | y2r = x1r + x2r; 2184 | y2i = x1i + x2i; 2185 | y6r = x1r - x2r; 2186 | y6i = x1i - x2i; 2187 | x0r = a[aP + 4] + a[aP + 21]; 2188 | x0i = a[aP + 5] - a[aP + 20]; 2189 | x1r = wk2i * x0r - wk2r * x0i; 2190 | x1i = wk2i * x0i + wk2r * x0r; 2191 | x0r = a[aP + 12] + a[aP + 29]; 2192 | x0i = a[aP + 13] - a[aP + 28]; 2193 | x2r = wk2r * x0r - wk2i * x0i; 2194 | x2i = wk2r * x0i + wk2i * x0r; 2195 | y10r = x1r - x2r; 2196 | y10i = x1i - x2i; 2197 | y14r = x1r + x2r; 2198 | y14i = x1i + x2i; 2199 | x0r = a[aP + 6] - a[aP + 23]; 2200 | x0i = a[aP + 7] + a[aP + 22]; 2201 | x1r = wk3r * x0r - wk3i * x0i; 2202 | x1i = wk3r * x0i + wk3i * x0r; 2203 | x0r = a[aP + 14] - a[aP + 31]; 2204 | x0i = a[aP + 15] + a[aP + 30]; 2205 | x2r = wk1i * x0r - wk1r * x0i; 2206 | x2i = wk1i * x0i + wk1r * x0r; 2207 | y3r = x1r + x2r; 2208 | y3i = x1i + x2i; 2209 | y7r = x1r - x2r; 2210 | y7i = x1i - x2i; 2211 | x0r = a[aP + 6] + a[aP + 23]; 2212 | x0i = a[aP + 7] - a[aP + 22]; 2213 | x1r = wk1i * x0r + wk1r * x0i; 2214 | x1i = wk1i * x0i - wk1r * x0r; 2215 | x0r = a[aP + 14] + a[aP + 31]; 2216 | x0i = a[aP + 15] - a[aP + 30]; 2217 | x2r = wk3i * x0r - wk3r * x0i; 2218 | x2i = wk3i * x0i + wk3r * x0r; 2219 | y11r = x1r + x2r; 2220 | y11i = x1i + x2i; 2221 | y15r = x1r - x2r; 2222 | y15i = x1i - x2i; 2223 | x1r = y0r + y2r; 2224 | x1i = y0i + y2i; 2225 | x2r = y1r + y3r; 2226 | x2i = y1i + y3i; 2227 | a[aP + 0] = x1r + x2r; 2228 | a[aP + 1] = x1i + x2i; 2229 | a[aP + 2] = x1r - x2r; 2230 | a[aP + 3] = x1i - x2i; 2231 | x1r = y0r - y2r; 2232 | x1i = y0i - y2i; 2233 | x2r = y1r - y3r; 2234 | x2i = y1i - y3i; 2235 | a[aP + 4] = x1r - x2i; 2236 | a[aP + 5] = x1i + x2r; 2237 | a[aP + 6] = x1r + x2i; 2238 | a[aP + 7] = x1i - x2r; 2239 | x1r = y4r - y6i; 2240 | x1i = y4i + y6r; 2241 | x0r = y5r - y7i; 2242 | x0i = y5i + y7r; 2243 | x2r = wn4r * (x0r - x0i); 2244 | x2i = wn4r * (x0i + x0r); 2245 | a[aP + 8] = x1r + x2r; 2246 | a[aP + 9] = x1i + x2i; 2247 | a[aP + 10] = x1r - x2r; 2248 | a[aP + 11] = x1i - x2i; 2249 | x1r = y4r + y6i; 2250 | x1i = y4i - y6r; 2251 | x0r = y5r + y7i; 2252 | x0i = y5i - y7r; 2253 | x2r = wn4r * (x0r - x0i); 2254 | x2i = wn4r * (x0i + x0r); 2255 | a[aP + 12] = x1r - x2i; 2256 | a[aP + 13] = x1i + x2r; 2257 | a[aP + 14] = x1r + x2i; 2258 | a[aP + 15] = x1i - x2r; 2259 | x1r = y8r + y10r; 2260 | x1i = y8i + y10i; 2261 | x2r = y9r - y11r; 2262 | x2i = y9i - y11i; 2263 | a[aP + 16] = x1r + x2r; 2264 | a[aP + 17] = x1i + x2i; 2265 | a[aP + 18] = x1r - x2r; 2266 | a[aP + 19] = x1i - x2i; 2267 | x1r = y8r - y10r; 2268 | x1i = y8i - y10i; 2269 | x2r = y9r + y11r; 2270 | x2i = y9i + y11i; 2271 | a[aP + 20] = x1r - x2i; 2272 | a[aP + 21] = x1i + x2r; 2273 | a[aP + 22] = x1r + x2i; 2274 | a[aP + 23] = x1i - x2r; 2275 | x1r = y12r - y14i; 2276 | x1i = y12i + y14r; 2277 | x0r = y13r + y15i; 2278 | x0i = y13i - y15r; 2279 | x2r = wn4r * (x0r - x0i); 2280 | x2i = wn4r * (x0i + x0r); 2281 | a[aP + 24] = x1r + x2r; 2282 | a[aP + 25] = x1i + x2i; 2283 | a[aP + 26] = x1r - x2r; 2284 | a[aP + 27] = x1i - x2i; 2285 | x1r = y12r + y14i; 2286 | x1i = y12i - y14r; 2287 | x0r = y13r - y15i; 2288 | x0i = y13i + y15r; 2289 | x2r = wn4r * (x0r - x0i); 2290 | x2i = wn4r * (x0i + x0r); 2291 | a[aP + 28] = x1r - x2i; 2292 | a[aP + 29] = x1i + x2r; 2293 | a[aP + 30] = x1r + x2i; 2294 | a[aP + 31] = x1i - x2r; 2295 | } 2296 | 2297 | /** */ 2298 | private void cftf081(double[] a, int aP, double[] w, int wP) { 2299 | double 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; 2300 | 2301 | wn4r = w[wP + 1]; 2302 | x0r = a[aP + 0] + a[aP + 8]; 2303 | x0i = a[aP + 1] + a[aP + 9]; 2304 | x1r = a[aP + 0] - a[aP + 8]; 2305 | x1i = a[aP + 1] - a[aP + 9]; 2306 | x2r = a[aP + 4] + a[aP + 12]; 2307 | x2i = a[aP + 5] + a[aP + 13]; 2308 | x3r = a[aP + 4] - a[aP + 12]; 2309 | x3i = a[aP + 5] - a[aP + 13]; 2310 | y0r = x0r + x2r; 2311 | y0i = x0i + x2i; 2312 | y2r = x0r - x2r; 2313 | y2i = x0i - x2i; 2314 | y1r = x1r - x3i; 2315 | y1i = x1i + x3r; 2316 | y3r = x1r + x3i; 2317 | y3i = x1i - x3r; 2318 | x0r = a[aP + 2] + a[aP + 10]; 2319 | x0i = a[aP + 3] + a[aP + 11]; 2320 | x1r = a[aP + 2] - a[aP + 10]; 2321 | x1i = a[aP + 3] - a[aP + 11]; 2322 | x2r = a[aP + 6] + a[aP + 14]; 2323 | x2i = a[aP + 7] + a[aP + 15]; 2324 | x3r = a[aP + 6] - a[aP + 14]; 2325 | x3i = a[aP + 7] - a[aP + 15]; 2326 | y4r = x0r + x2r; 2327 | y4i = x0i + x2i; 2328 | y6r = x0r - x2r; 2329 | y6i = x0i - x2i; 2330 | x0r = x1r - x3i; 2331 | x0i = x1i + x3r; 2332 | x2r = x1r + x3i; 2333 | x2i = x1i - x3r; 2334 | y5r = wn4r * (x0r - x0i); 2335 | y5i = wn4r * (x0r + x0i); 2336 | y7r = wn4r * (x2r - x2i); 2337 | y7i = wn4r * (x2r + x2i); 2338 | a[aP + 8] = y1r + y5r; 2339 | a[aP + 9] = y1i + y5i; 2340 | a[aP + 10] = y1r - y5r; 2341 | a[aP + 11] = y1i - y5i; 2342 | a[aP + 12] = y3r - y7i; 2343 | a[aP + 13] = y3i + y7r; 2344 | a[aP + 14] = y3r + y7i; 2345 | a[aP + 15] = y3i - y7r; 2346 | a[aP + 0] = y0r + y4r; 2347 | a[aP + 1] = y0i + y4i; 2348 | a[aP + 2] = y0r - y4r; 2349 | a[aP + 3] = y0i - y4i; 2350 | a[aP + 4] = y2r - y6i; 2351 | a[aP + 5] = y2i + y6r; 2352 | a[aP + 6] = y2r + y6i; 2353 | a[aP + 7] = y2i - y6r; 2354 | } 2355 | 2356 | /** */ 2357 | private void cftf082(double[] a, int aP, double[] w, int wP) { 2358 | double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; 2359 | 2360 | wn4r = w[wP + 1]; 2361 | wk1r = w[wP + 4]; 2362 | wk1i = w[wP + 5]; 2363 | y0r = a[aP + 0] - a[aP + 9]; 2364 | y0i = a[aP + 1] + a[aP + 8]; 2365 | y1r = a[aP + 0] + a[aP + 9]; 2366 | y1i = a[aP + 1] - a[aP + 8]; 2367 | x0r = a[aP + 4] - a[aP + 13]; 2368 | x0i = a[aP + 5] + a[aP + 12]; 2369 | y2r = wn4r * (x0r - x0i); 2370 | y2i = wn4r * (x0i + x0r); 2371 | x0r = a[aP + 4] + a[aP + 13]; 2372 | x0i = a[aP + 5] - a[aP + 12]; 2373 | y3r = wn4r * (x0r - x0i); 2374 | y3i = wn4r * (x0i + x0r); 2375 | x0r = a[aP + 2] - a[aP + 11]; 2376 | x0i = a[aP + 3] + a[aP + 10]; 2377 | y4r = wk1r * x0r - wk1i * x0i; 2378 | y4i = wk1r * x0i + wk1i * x0r; 2379 | x0r = a[aP + 2] + a[aP + 11]; 2380 | x0i = a[aP + 3] - a[aP + 10]; 2381 | y5r = wk1i * x0r - wk1r * x0i; 2382 | y5i = wk1i * x0i + wk1r * x0r; 2383 | x0r = a[aP + 6] - a[aP + 15]; 2384 | x0i = a[aP + 7] + a[aP + 14]; 2385 | y6r = wk1i * x0r - wk1r * x0i; 2386 | y6i = wk1i * x0i + wk1r * x0r; 2387 | x0r = a[aP + 6] + a[aP + 15]; 2388 | x0i = a[aP + 7] - a[aP + 14]; 2389 | y7r = wk1r * x0r - wk1i * x0i; 2390 | y7i = wk1r * x0i + wk1i * x0r; 2391 | x0r = y0r + y2r; 2392 | x0i = y0i + y2i; 2393 | x1r = y4r + y6r; 2394 | x1i = y4i + y6i; 2395 | a[aP + 0] = x0r + x1r; 2396 | a[aP + 1] = x0i + x1i; 2397 | a[aP + 2] = x0r - x1r; 2398 | a[aP + 3] = x0i - x1i; 2399 | x0r = y0r - y2r; 2400 | x0i = y0i - y2i; 2401 | x1r = y4r - y6r; 2402 | x1i = y4i - y6i; 2403 | a[aP + 4] = x0r - x1i; 2404 | a[aP + 5] = x0i + x1r; 2405 | a[aP + 6] = x0r + x1i; 2406 | a[aP + 7] = x0i - x1r; 2407 | x0r = y1r - y3i; 2408 | x0i = y1i + y3r; 2409 | x1r = y5r - y7r; 2410 | x1i = y5i - y7i; 2411 | a[aP + 8] = x0r + x1r; 2412 | a[aP + 9] = x0i + x1i; 2413 | a[aP + 10] = x0r - x1r; 2414 | a[aP + 11] = x0i - x1i; 2415 | x0r = y1r + y3i; 2416 | x0i = y1i - y3r; 2417 | x1r = y5r + y7r; 2418 | x1i = y5i + y7i; 2419 | a[aP + 12] = x0r - x1i; 2420 | a[aP + 13] = x0i + x1r; 2421 | a[aP + 14] = x0r + x1i; 2422 | a[aP + 15] = x0i - x1r; 2423 | } 2424 | 2425 | /** 2426 | * 3rd 2427 | * when n = 8. 2428 | * @see #cftfsub(int, double[], int[], int, int, double[]) 2429 | */ 2430 | private void cftf040(double[] a) { 2431 | double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; 2432 | 2433 | x0r = a[0] + a[4]; 2434 | x0i = a[1] + a[5]; 2435 | x1r = a[0] - a[4]; 2436 | x1i = a[1] - a[5]; 2437 | x2r = a[2] + a[6]; 2438 | x2i = a[3] + a[7]; 2439 | x3r = a[2] - a[6]; 2440 | x3i = a[3] - a[7]; 2441 | a[0] = x0r + x2r; 2442 | a[1] = x0i + x2i; 2443 | a[4] = x0r - x2r; 2444 | a[5] = x0i - x2i; 2445 | a[2] = x1r - x3i; 2446 | a[3] = x1i + x3r; 2447 | a[6] = x1r + x3i; 2448 | a[7] = x1i - x3r; 2449 | } 2450 | 2451 | /** 2452 | * 3rd 2453 | * when n = 8. 2454 | * @see #cftbsub(int, double[], int[], int, int, double[]) 2455 | */ 2456 | private void cftb040(double[] a) { 2457 | double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; 2458 | 2459 | x0r = a[0] + a[4]; 2460 | x0i = a[1] + a[5]; 2461 | x1r = a[0] - a[4]; 2462 | x1i = a[1] - a[5]; 2463 | x2r = a[2] + a[6]; 2464 | x2i = a[3] + a[7]; 2465 | x3r = a[2] - a[6]; 2466 | x3i = a[3] - a[7]; 2467 | a[0] = x0r + x2r; 2468 | a[1] = x0i + x2i; 2469 | a[4] = x0r - x2r; 2470 | a[5] = x0i - x2i; 2471 | a[2] = x1r + x3i; 2472 | a[3] = x1i - x3r; 2473 | a[6] = x1r - x3i; 2474 | a[7] = x1i + x3r; 2475 | } 2476 | 2477 | /** 2478 | * 3rd 2479 | * when n = 4. 2480 | * @see #cftbsub(int, double[], int[], int, int, double[]) 2481 | * @see #cftfsub(int, double[], int[], int, int, double[]) 2482 | */ 2483 | private void cftx020(double[] a) { 2484 | double x0r, x0i; 2485 | 2486 | x0r = a[0] - a[2]; 2487 | x0i = a[1] - a[3]; 2488 | a[0] += a[2]; 2489 | a[1] += a[3]; 2490 | a[2] = x0r; 2491 | a[3] = x0i; 2492 | } 2493 | 2494 | /** 2495 | * 2nd 2496 | * @see #rdft(int, int, double[], int[], double[]) 2497 | * @see #ddct(int, int, double[], int[], double[]) 2498 | * @see #ddst(int, int, double[], int[], double[]) 2499 | * @see #dfst(int, double[], double[], int[], double[]) 2500 | * @see #dfct(int, double[], double[], int[], double[]) 2501 | */ 2502 | private void rftfsub(int n, double[] a, int nc, double[] c, int cP) { 2503 | int j, k, kk, ks, m; 2504 | double wkr, wki, xr, xi, yr, yi; 2505 | 2506 | m = n >> 1; 2507 | ks = 2 * nc / m; 2508 | kk = 0; 2509 | for (j = 2; j < m; j += 2) { 2510 | k = n - j; 2511 | kk += ks; 2512 | wkr = 0.5 - c[cP + nc - kk]; 2513 | wki = c[cP + kk]; 2514 | xr = a[j] - a[k]; 2515 | xi = a[j + 1] + a[k + 1]; 2516 | yr = wkr * xr - wki * xi; 2517 | yi = wkr * xi + wki * xr; 2518 | a[j] -= yr; 2519 | a[j + 1] -= yi; 2520 | a[k] += yr; 2521 | a[k + 1] -= yi; 2522 | } 2523 | } 2524 | 2525 | /** 2526 | * 2nd 2527 | * @see #rdft(int, int, double[], int[], double[]) 2528 | * @see #ddct(int, int, double[], int[], double[]) 2529 | * @see #ddst(int, int, double[], int[], double[]) 2530 | */ 2531 | private void rftbsub(int n, double[] a, int nc, double[] c, int cP) { 2532 | int j, k, kk, ks, m; 2533 | double wkr, wki, xr, xi, yr, yi; 2534 | 2535 | m = n >> 1; 2536 | ks = 2 * nc / m; 2537 | kk = 0; 2538 | for (j = 2; j < m; j += 2) { 2539 | k = n - j; 2540 | kk += ks; 2541 | wkr = 0.5 - c[cP + nc - kk]; 2542 | wki = c[cP + kk]; 2543 | xr = a[j] - a[k]; 2544 | xi = a[j + 1] + a[k + 1]; 2545 | yr = wkr * xr + wki * xi; 2546 | yi = wkr * xi - wki * xr; 2547 | a[j] -= yr; 2548 | a[j + 1] -= yi; 2549 | a[k] += yr; 2550 | a[k + 1] -= yi; 2551 | } 2552 | } 2553 | 2554 | /** 2555 | * 2nd 2556 | * @see #ddct(int, int, double[], int[], double[]) 2557 | * @see #dfct(int, double[], double[], int[], double[]) 2558 | */ 2559 | private void dctsub(int n, double[] a, int nc, double[] c, int cP) { 2560 | int j, k, kk, ks, m; 2561 | double wkr, wki, xr; 2562 | 2563 | m = n >> 1; 2564 | ks = nc / n; 2565 | kk = 0; 2566 | for (j = 1; j < m; j++) { 2567 | k = n - j; 2568 | kk += ks; 2569 | wkr = c[cP + kk] - c[cP + nc - kk]; 2570 | wki = c[cP + kk] + c[cP + nc - kk]; 2571 | xr = wki * a[j] - wkr * a[k]; 2572 | a[j] = wkr * a[j] + wki * a[k]; 2573 | a[k] = xr; 2574 | } 2575 | a[m] *= c[cP + 0]; 2576 | } 2577 | 2578 | /** 2579 | * 2nd 2580 | * @see #ddst(int, int, double[], int[], double[]) 2581 | * @see #dfst(int, double[], double[], int[], double[]) 2582 | */ 2583 | private void dstsub(int n, double[] a, int nc, double[] c, int cP) { 2584 | int j, k, kk, ks, m; 2585 | double wkr, wki, xr; 2586 | 2587 | m = n >> 1; 2588 | ks = nc / n; 2589 | kk = 0; 2590 | for (j = 1; j < m; j++) { 2591 | k = n - j; 2592 | kk += ks; 2593 | wkr = c[cP + kk] - c[cP + nc - kk]; 2594 | wki = c[cP + kk] + c[cP + nc - kk]; 2595 | xr = wki * a[k] - wkr * a[j]; 2596 | a[k] = wkr * a[k] + wki * a[j]; 2597 | a[j] = xr; 2598 | } 2599 | a[m] *= c[cP + 0]; 2600 | } 2601 | } 2602 | 2603 | /* */ 2604 | --------------------------------------------------------------------------------