Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/media/sound/FFT.java
38924 views
/*1* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package com.sun.media.sound;2526/**27* Fast Fourier Transformer.28*29* @author Karl Helgason30*/31public final class FFT {3233private final double[] w;34private final int fftFrameSize;35private final int sign;36private final int[] bitm_array;37private final int fftFrameSize2;3839// Sign = -1 is FFT, 1 is IFFT (inverse FFT)40// Data = Interlaced double array to be transformed.41// The order is: real (sin), complex (cos)42// Framesize must be power of 243public FFT(int fftFrameSize, int sign) {44w = computeTwiddleFactors(fftFrameSize, sign);4546this.fftFrameSize = fftFrameSize;47this.sign = sign;48fftFrameSize2 = fftFrameSize << 1;4950// Pre-process Bit-Reversal51bitm_array = new int[fftFrameSize2];52for (int i = 2; i < fftFrameSize2; i += 2) {53int j;54int bitm;55for (bitm = 2, j = 0; bitm < fftFrameSize2; bitm <<= 1) {56if ((i & bitm) != 0)57j++;58j <<= 1;59}60bitm_array[i] = j;61}6263}6465public void transform(double[] data) {66bitreversal(data);67calc(fftFrameSize, data, sign, w);68}6970private final static double[] computeTwiddleFactors(int fftFrameSize,71int sign) {7273int imax = (int) (Math.log(fftFrameSize) / Math.log(2.));7475double[] warray = new double[(fftFrameSize - 1) * 4];76int w_index = 0;7778for (int i = 0, nstep = 2; i < imax; i++) {79int jmax = nstep;80nstep <<= 1;8182double wr = 1.0;83double wi = 0.0;8485double arg = Math.PI / (jmax >> 1);86double wfr = Math.cos(arg);87double wfi = sign * Math.sin(arg);8889for (int j = 0; j < jmax; j += 2) {90warray[w_index++] = wr;91warray[w_index++] = wi;9293double tempr = wr;94wr = tempr * wfr - wi * wfi;95wi = tempr * wfi + wi * wfr;96}97}9899// PRECOMPUTATION of wwr1, wwi1 for factor 4 Decomposition (3 * complex100// operators and 8 +/- complex operators)101{102w_index = 0;103int w_index2 = warray.length >> 1;104for (int i = 0, nstep = 2; i < (imax - 1); i++) {105int jmax = nstep;106nstep *= 2;107108int ii = w_index + jmax;109for (int j = 0; j < jmax; j += 2) {110double wr = warray[w_index++];111double wi = warray[w_index++];112double wr1 = warray[ii++];113double wi1 = warray[ii++];114warray[w_index2++] = wr * wr1 - wi * wi1;115warray[w_index2++] = wr * wi1 + wi * wr1;116}117}118119}120121return warray;122}123124private final static void calc(int fftFrameSize, double[] data, int sign,125double[] w) {126127final int fftFrameSize2 = fftFrameSize << 1;128129int nstep = 2;130131if (nstep >= fftFrameSize2)132return;133int i = nstep - 2;134if (sign == -1)135calcF4F(fftFrameSize, data, i, nstep, w);136else137calcF4I(fftFrameSize, data, i, nstep, w);138139}140141private final static void calcF2E(int fftFrameSize, double[] data, int i,142int nstep, double[] w) {143int jmax = nstep;144for (int n = 0; n < jmax; n += 2) {145double wr = w[i++];146double wi = w[i++];147int m = n + jmax;148double datam_r = data[m];149double datam_i = data[m + 1];150double datan_r = data[n];151double datan_i = data[n + 1];152double tempr = datam_r * wr - datam_i * wi;153double tempi = datam_r * wi + datam_i * wr;154data[m] = datan_r - tempr;155data[m + 1] = datan_i - tempi;156data[n] = datan_r + tempr;157data[n + 1] = datan_i + tempi;158}159return;160161}162163// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-164// complex operators165private final static void calcF4F(int fftFrameSize, double[] data, int i,166int nstep, double[] w) {167final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;168// Factor-4 Decomposition169170int w_len = w.length >> 1;171while (nstep < fftFrameSize2) {172173if (nstep << 2 == fftFrameSize2) {174// Goto Factor-4 Final Decomposition175// calcF4E(data, i, nstep, -1, w);176calcF4FE(fftFrameSize, data, i, nstep, w);177return;178}179int jmax = nstep;180int nnstep = nstep << 1;181if (nnstep == fftFrameSize2) {182// Factor-4 Decomposition not possible183calcF2E(fftFrameSize, data, i, nstep, w);184return;185}186nstep <<= 2;187int ii = i + jmax;188int iii = i + w_len;189190{191i += 2;192ii += 2;193iii += 2;194195for (int n = 0; n < fftFrameSize2; n += nstep) {196int m = n + jmax;197198double datam1_r = data[m];199double datam1_i = data[m + 1];200double datan1_r = data[n];201double datan1_i = data[n + 1];202203n += nnstep;204m += nnstep;205double datam2_r = data[m];206double datam2_i = data[m + 1];207double datan2_r = data[n];208double datan2_i = data[n + 1];209210double tempr = datam1_r;211double tempi = datam1_i;212213datam1_r = datan1_r - tempr;214datam1_i = datan1_i - tempi;215datan1_r = datan1_r + tempr;216datan1_i = datan1_i + tempi;217218double n2w1r = datan2_r;219double n2w1i = datan2_i;220double m2ww1r = datam2_r;221double m2ww1i = datam2_i;222223tempr = m2ww1r - n2w1r;224tempi = m2ww1i - n2w1i;225226datam2_r = datam1_r + tempi;227datam2_i = datam1_i - tempr;228datam1_r = datam1_r - tempi;229datam1_i = datam1_i + tempr;230231tempr = n2w1r + m2ww1r;232tempi = n2w1i + m2ww1i;233234datan2_r = datan1_r - tempr;235datan2_i = datan1_i - tempi;236datan1_r = datan1_r + tempr;237datan1_i = datan1_i + tempi;238239data[m] = datam2_r;240data[m + 1] = datam2_i;241data[n] = datan2_r;242data[n + 1] = datan2_i;243244n -= nnstep;245m -= nnstep;246data[m] = datam1_r;247data[m + 1] = datam1_i;248data[n] = datan1_r;249data[n + 1] = datan1_i;250251}252}253254for (int j = 2; j < jmax; j += 2) {255double wr = w[i++];256double wi = w[i++];257double wr1 = w[ii++];258double wi1 = w[ii++];259double wwr1 = w[iii++];260double wwi1 = w[iii++];261// double wwr1 = wr * wr1 - wi * wi1; // these numbers can be262// precomputed!!!263// double wwi1 = wr * wi1 + wi * wr1;264265for (int n = j; n < fftFrameSize2; n += nstep) {266int m = n + jmax;267268double datam1_r = data[m];269double datam1_i = data[m + 1];270double datan1_r = data[n];271double datan1_i = data[n + 1];272273n += nnstep;274m += nnstep;275double datam2_r = data[m];276double datam2_i = data[m + 1];277double datan2_r = data[n];278double datan2_i = data[n + 1];279280double tempr = datam1_r * wr - datam1_i * wi;281double tempi = datam1_r * wi + datam1_i * wr;282283datam1_r = datan1_r - tempr;284datam1_i = datan1_i - tempi;285datan1_r = datan1_r + tempr;286datan1_i = datan1_i + tempi;287288double n2w1r = datan2_r * wr1 - datan2_i * wi1;289double n2w1i = datan2_r * wi1 + datan2_i * wr1;290double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;291double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;292293tempr = m2ww1r - n2w1r;294tempi = m2ww1i - n2w1i;295296datam2_r = datam1_r + tempi;297datam2_i = datam1_i - tempr;298datam1_r = datam1_r - tempi;299datam1_i = datam1_i + tempr;300301tempr = n2w1r + m2ww1r;302tempi = n2w1i + m2ww1i;303304datan2_r = datan1_r - tempr;305datan2_i = datan1_i - tempi;306datan1_r = datan1_r + tempr;307datan1_i = datan1_i + tempi;308309data[m] = datam2_r;310data[m + 1] = datam2_i;311data[n] = datan2_r;312data[n + 1] = datan2_i;313314n -= nnstep;315m -= nnstep;316data[m] = datam1_r;317data[m + 1] = datam1_i;318data[n] = datan1_r;319data[n + 1] = datan1_i;320}321}322323i += jmax << 1;324325}326327calcF2E(fftFrameSize, data, i, nstep, w);328329}330331// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-332// complex operators333private final static void calcF4I(int fftFrameSize, double[] data, int i,334int nstep, double[] w) {335final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;336// Factor-4 Decomposition337338int w_len = w.length >> 1;339while (nstep < fftFrameSize2) {340341if (nstep << 2 == fftFrameSize2) {342// Goto Factor-4 Final Decomposition343// calcF4E(data, i, nstep, 1, w);344calcF4IE(fftFrameSize, data, i, nstep, w);345return;346}347int jmax = nstep;348int nnstep = nstep << 1;349if (nnstep == fftFrameSize2) {350// Factor-4 Decomposition not possible351calcF2E(fftFrameSize, data, i, nstep, w);352return;353}354nstep <<= 2;355int ii = i + jmax;356int iii = i + w_len;357{358i += 2;359ii += 2;360iii += 2;361362for (int n = 0; n < fftFrameSize2; n += nstep) {363int m = n + jmax;364365double datam1_r = data[m];366double datam1_i = data[m + 1];367double datan1_r = data[n];368double datan1_i = data[n + 1];369370n += nnstep;371m += nnstep;372double datam2_r = data[m];373double datam2_i = data[m + 1];374double datan2_r = data[n];375double datan2_i = data[n + 1];376377double tempr = datam1_r;378double tempi = datam1_i;379380datam1_r = datan1_r - tempr;381datam1_i = datan1_i - tempi;382datan1_r = datan1_r + tempr;383datan1_i = datan1_i + tempi;384385double n2w1r = datan2_r;386double n2w1i = datan2_i;387double m2ww1r = datam2_r;388double m2ww1i = datam2_i;389390tempr = n2w1r - m2ww1r;391tempi = n2w1i - m2ww1i;392393datam2_r = datam1_r + tempi;394datam2_i = datam1_i - tempr;395datam1_r = datam1_r - tempi;396datam1_i = datam1_i + tempr;397398tempr = n2w1r + m2ww1r;399tempi = n2w1i + m2ww1i;400401datan2_r = datan1_r - tempr;402datan2_i = datan1_i - tempi;403datan1_r = datan1_r + tempr;404datan1_i = datan1_i + tempi;405406data[m] = datam2_r;407data[m + 1] = datam2_i;408data[n] = datan2_r;409data[n + 1] = datan2_i;410411n -= nnstep;412m -= nnstep;413data[m] = datam1_r;414data[m + 1] = datam1_i;415data[n] = datan1_r;416data[n + 1] = datan1_i;417418}419420}421for (int j = 2; j < jmax; j += 2) {422double wr = w[i++];423double wi = w[i++];424double wr1 = w[ii++];425double wi1 = w[ii++];426double wwr1 = w[iii++];427double wwi1 = w[iii++];428// double wwr1 = wr * wr1 - wi * wi1; // these numbers can be429// precomputed!!!430// double wwi1 = wr * wi1 + wi * wr1;431432for (int n = j; n < fftFrameSize2; n += nstep) {433int m = n + jmax;434435double datam1_r = data[m];436double datam1_i = data[m + 1];437double datan1_r = data[n];438double datan1_i = data[n + 1];439440n += nnstep;441m += nnstep;442double datam2_r = data[m];443double datam2_i = data[m + 1];444double datan2_r = data[n];445double datan2_i = data[n + 1];446447double tempr = datam1_r * wr - datam1_i * wi;448double tempi = datam1_r * wi + datam1_i * wr;449450datam1_r = datan1_r - tempr;451datam1_i = datan1_i - tempi;452datan1_r = datan1_r + tempr;453datan1_i = datan1_i + tempi;454455double n2w1r = datan2_r * wr1 - datan2_i * wi1;456double n2w1i = datan2_r * wi1 + datan2_i * wr1;457double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;458double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;459460tempr = n2w1r - m2ww1r;461tempi = n2w1i - m2ww1i;462463datam2_r = datam1_r + tempi;464datam2_i = datam1_i - tempr;465datam1_r = datam1_r - tempi;466datam1_i = datam1_i + tempr;467468tempr = n2w1r + m2ww1r;469tempi = n2w1i + m2ww1i;470471datan2_r = datan1_r - tempr;472datan2_i = datan1_i - tempi;473datan1_r = datan1_r + tempr;474datan1_i = datan1_i + tempi;475476data[m] = datam2_r;477data[m + 1] = datam2_i;478data[n] = datan2_r;479data[n + 1] = datan2_i;480481n -= nnstep;482m -= nnstep;483data[m] = datam1_r;484data[m + 1] = datam1_i;485data[n] = datan1_r;486data[n + 1] = datan1_i;487488}489}490491i += jmax << 1;492493}494495calcF2E(fftFrameSize, data, i, nstep, w);496497}498499// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-500// complex operators501private final static void calcF4FE(int fftFrameSize, double[] data, int i,502int nstep, double[] w) {503final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;504// Factor-4 Decomposition505506int w_len = w.length >> 1;507while (nstep < fftFrameSize2) {508509int jmax = nstep;510int nnstep = nstep << 1;511if (nnstep == fftFrameSize2) {512// Factor-4 Decomposition not possible513calcF2E(fftFrameSize, data, i, nstep, w);514return;515}516nstep <<= 2;517int ii = i + jmax;518int iii = i + w_len;519for (int n = 0; n < jmax; n += 2) {520double wr = w[i++];521double wi = w[i++];522double wr1 = w[ii++];523double wi1 = w[ii++];524double wwr1 = w[iii++];525double wwi1 = w[iii++];526// double wwr1 = wr * wr1 - wi * wi1; // these numbers can be527// precomputed!!!528// double wwi1 = wr * wi1 + wi * wr1;529530int m = n + jmax;531532double datam1_r = data[m];533double datam1_i = data[m + 1];534double datan1_r = data[n];535double datan1_i = data[n + 1];536537n += nnstep;538m += nnstep;539double datam2_r = data[m];540double datam2_i = data[m + 1];541double datan2_r = data[n];542double datan2_i = data[n + 1];543544double tempr = datam1_r * wr - datam1_i * wi;545double tempi = datam1_r * wi + datam1_i * wr;546547datam1_r = datan1_r - tempr;548datam1_i = datan1_i - tempi;549datan1_r = datan1_r + tempr;550datan1_i = datan1_i + tempi;551552double n2w1r = datan2_r * wr1 - datan2_i * wi1;553double n2w1i = datan2_r * wi1 + datan2_i * wr1;554double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;555double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;556557tempr = m2ww1r - n2w1r;558tempi = m2ww1i - n2w1i;559560datam2_r = datam1_r + tempi;561datam2_i = datam1_i - tempr;562datam1_r = datam1_r - tempi;563datam1_i = datam1_i + tempr;564565tempr = n2w1r + m2ww1r;566tempi = n2w1i + m2ww1i;567568datan2_r = datan1_r - tempr;569datan2_i = datan1_i - tempi;570datan1_r = datan1_r + tempr;571datan1_i = datan1_i + tempi;572573data[m] = datam2_r;574data[m + 1] = datam2_i;575data[n] = datan2_r;576data[n + 1] = datan2_i;577578n -= nnstep;579m -= nnstep;580data[m] = datam1_r;581data[m + 1] = datam1_i;582data[n] = datan1_r;583data[n + 1] = datan1_i;584585}586587i += jmax << 1;588589}590591}592593// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-594// complex operators595private final static void calcF4IE(int fftFrameSize, double[] data, int i,596int nstep, double[] w) {597final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;598// Factor-4 Decomposition599600int w_len = w.length >> 1;601while (nstep < fftFrameSize2) {602603int jmax = nstep;604int nnstep = nstep << 1;605if (nnstep == fftFrameSize2) {606// Factor-4 Decomposition not possible607calcF2E(fftFrameSize, data, i, nstep, w);608return;609}610nstep <<= 2;611int ii = i + jmax;612int iii = i + w_len;613for (int n = 0; n < jmax; n += 2) {614double wr = w[i++];615double wi = w[i++];616double wr1 = w[ii++];617double wi1 = w[ii++];618double wwr1 = w[iii++];619double wwi1 = w[iii++];620// double wwr1 = wr * wr1 - wi * wi1; // these numbers can be621// precomputed!!!622// double wwi1 = wr * wi1 + wi * wr1;623624int m = n + jmax;625626double datam1_r = data[m];627double datam1_i = data[m + 1];628double datan1_r = data[n];629double datan1_i = data[n + 1];630631n += nnstep;632m += nnstep;633double datam2_r = data[m];634double datam2_i = data[m + 1];635double datan2_r = data[n];636double datan2_i = data[n + 1];637638double tempr = datam1_r * wr - datam1_i * wi;639double tempi = datam1_r * wi + datam1_i * wr;640641datam1_r = datan1_r - tempr;642datam1_i = datan1_i - tempi;643datan1_r = datan1_r + tempr;644datan1_i = datan1_i + tempi;645646double n2w1r = datan2_r * wr1 - datan2_i * wi1;647double n2w1i = datan2_r * wi1 + datan2_i * wr1;648double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;649double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;650651tempr = n2w1r - m2ww1r;652tempi = n2w1i - m2ww1i;653654datam2_r = datam1_r + tempi;655datam2_i = datam1_i - tempr;656datam1_r = datam1_r - tempi;657datam1_i = datam1_i + tempr;658659tempr = n2w1r + m2ww1r;660tempi = n2w1i + m2ww1i;661662datan2_r = datan1_r - tempr;663datan2_i = datan1_i - tempi;664datan1_r = datan1_r + tempr;665datan1_i = datan1_i + tempi;666667data[m] = datam2_r;668data[m + 1] = datam2_i;669data[n] = datan2_r;670data[n + 1] = datan2_i;671672n -= nnstep;673m -= nnstep;674data[m] = datam1_r;675data[m + 1] = datam1_i;676data[n] = datan1_r;677data[n + 1] = datan1_i;678679}680681i += jmax << 1;682683}684685}686687private final void bitreversal(double[] data) {688if (fftFrameSize < 4)689return;690691int inverse = fftFrameSize2 - 2;692for (int i = 0; i < fftFrameSize; i += 4) {693int j = bitm_array[i];694695// Performing Bit-Reversal, even v.s. even, O(2N)696if (i < j) {697698int n = i;699int m = j;700701// COMPLEX: SWAP(data[n], data[m])702// Real Part703double tempr = data[n];704data[n] = data[m];705data[m] = tempr;706// Imagery Part707n++;708m++;709double tempi = data[n];710data[n] = data[m];711data[m] = tempi;712713n = inverse - i;714m = inverse - j;715716// COMPLEX: SWAP(data[n], data[m])717// Real Part718tempr = data[n];719data[n] = data[m];720data[m] = tempr;721// Imagery Part722n++;723m++;724tempi = data[n];725data[n] = data[m];726data[m] = tempi;727}728729// Performing Bit-Reversal, odd v.s. even, O(N)730731int m = j + fftFrameSize; // bitm_array[i+2];732// COMPLEX: SWAP(data[n], data[m])733// Real Part734int n = i + 2;735double tempr = data[n];736data[n] = data[m];737data[m] = tempr;738// Imagery Part739n++;740m++;741double tempi = data[n];742data[n] = data[m];743data[m] = tempi;744}745746}747}748749750