| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- /*
- * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
- * http://www.trevorwishart.co.uk
- * http://www.composersdesktop.com
- *
- This file is part of the CDP System.
- The CDP System is free software; you can redistribute it
- and/or modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The CDP System is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the CDP System; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <structures.h>
- #include <globcon.h>
- #include <pvoc.h>
- #include <math.h> /*RWD*/
- // int fft_(),fftmx(),reals_();
- /*
- *-----------------------------------------------------------------------
- * subroutine: fft
- * multivariate complex fourier transform, computed in place
- * using mixed-radix fast fourier transform algorithm.
- *-----------------------------------------------------------------------
- *
- * this is the call from C:
- * fft_(anal,banal,&one,&N2,&one,&mtwo);
- * CHANGED TO:-
- * fft_(anal,banal,one,N2,one,mtwo);
- */
- int fft_(float *a, float *b, int nseg, int n, int nspn, int isn)
- /* a: pointer to array 'anal' */
- /* b: pointer to array 'banal' */
- {
- int exit_status;
- int nfac[16]; /* These are one bigger than needed */
- /* because wish to use Fortran array */
- /* index which runs 1 to n, not 0 to n */
- int m = 0, nf, k, kt, ntot, j, jj, maxf, maxp=0;
- /* work space pointers */
- float *at, *ck, *bt, *sk;
- int *np;
- /* reduce the pointers to input arrays - by doing this, FFT uses FORTRAN
- indexing but retains compatibility with C arrays */
- a--; b--;
- /*
- * determine the factors of n
- */
- k=nf=abs(n);
- if(nf==1)
- return(FINISHED);
- nspn=abs(nf*nspn);
- ntot=abs(nspn*nseg);
- if(isn*ntot == 0){
- sprintf(errstr,"zero in FFT parameters %d %d %d %d",nseg, n, nspn, isn);
- return(DATA_ERROR);
- }
- for (m=0; !(k%16); nfac[++m]=4,k/=16);
- for (j=3,jj=9; jj<=k; j+=2,jj=j*j)
- for (; !(k%jj); nfac[++m]=j,k/=jj);
- if (k<=4){
- kt = m;
- nfac[m+1] = k;
- if(k != 1)
- m++;
- }
- else{
- if(k%4==0){
- nfac[++m]=2;
- k/=4;
- }
- kt = m;
- maxp = max((kt+kt+2),(k-1));
- for(j=2; j<=k; j=1+((j+1)/2)*2)
- if(k%j==0){
- nfac[++m]=j;
- k/=j;
- }
- }
- if(m <= kt+1)
- maxp = m + kt + 1;
- if(m+kt > 15) {
- sprintf(errstr,"FFT parameter n has more than 15 factors : %d", n);
- return(DATA_ERROR);
- }
- if(kt!=0){
- j = kt;
- while(j)
- nfac[++m]=nfac[j--];
- }
- maxf = nfac[m-kt];
- if(kt > 0)
- maxf = max(nfac[kt],maxf);
- /* allocate workspace - assume no errors! */
- at = (float *) calloc(maxf,sizeof(float));
- ck = (float *) calloc(maxf,sizeof(float));
- bt = (float *) calloc(maxf,sizeof(float));
- sk = (float *) calloc(maxf,sizeof(float));
- np = (int *) calloc(maxp,sizeof(int));
- /* decrement pointers to allow FORTRAN type usage in fftmx */
- at--; bt--; ck--; sk--; np--;
- /* call fft driver */
- if((exit_status = fftmx(a,b,ntot,nf,nspn,isn,m,&kt,at,ck,bt,sk,np,nfac))<0)
- return(exit_status);
- /* restore pointers before releasing */
- at++; bt++; ck++; sk++; np++;
- /* release working storage before returning - assume no problems */
- (void) free(at);
- (void) free(sk);
- (void) free(bt);
- (void) free(ck);
- (void) free(np);
- return(FINISHED);
- }
- /*
- *-----------------------------------------------------------------------
- * subroutine: fftmx
- * called by subroutine 'fft' to compute mixed-radix fourier transform
- *-----------------------------------------------------------------------
- */
- int fftmx(float *a,float *b,int ntot,int n,int nspan,int isn,int m,int *kt,
- float *at,float *ck,float *bt,float *sk,int *np,int nfac[])
- {
- int i,inc,
- j,jc,jf, jj,
- k, k1, k2, k3=0, k4,
- kk,klim,ks,kspan, kspnn,
- lim,
- maxf,mm,
- nn,nt;
- double aa, aj, ajm, ajp, ak, akm, akp,
- bb, bj, bjm, bjp, bk, bkm, bkp,
- c1, c2=0.0, c3=0.0, c72, cd,
- dr,
- rad,
- sd, s1, s2=0.0, s3=0.0, s72, s120;
- double xx; /****** ADDED APRIL 1991 *********/
- inc=abs(isn);
- nt = inc*ntot;
- ks = inc*nspan;
- /******************* REPLACED MARCH 29: ***********************
- rad = atan((double)1.0);
- **************************************************************/
- rad = 0.785398163397448278900;
- /******************* REPLACED MARCH 29: ***********************
- s72 = rad/0.625;
- c72 = cos(s72);
- s72 = sin(s72);
- **************************************************************/
- c72 = 0.309016994374947451270;
- s72 = 0.951056516295153531190;
- /******************* REPLACED MARCH 29: ***********************
- s120 = sqrt((double)0.75);
- **************************************************************/
- s120 = 0.866025403784438707600;
- /* scale by 1/n for isn > 0 ( reverse transform ) */
- if (isn < 0){
- s72 = -s72;
- s120 = -s120;
- rad = -rad;}
- else{ ak = 1.0/(double)n;
- for(j=1; j<=nt;j += inc){
- a[j] = (float)(a[j] * ak);
- b[j] = (float)(b[j] * ak);
- }
- }
- kspan = ks;
- nn = nt - inc;
- jc = ks/n;
- /* sin, cos values are re-initialized each lim steps */
- lim = 32;
- klim = lim * jc;
- i = 0;
- jf = 0;
- maxf = m - (*kt);
- maxf = nfac[maxf];
- if((*kt) > 0)
- maxf = max(nfac[*kt],maxf);
- /*
- * compute fourier transform
- */
- lbl40:
- dr = (8.0 * (double)jc)/((double)kspan);
- /*************************** APRIL 1991 POW & POW2 not WORKING.. REPLACE *******
- cd = 2.0 * (pow2 ( sin((double)0.5 * dr * rad)) );
- *******************************************************************************/
- xx = sin((double)0.5 * dr * rad);
- cd = 2.0 * xx * xx;
- sd = sin(dr * rad);
- kk = 1;
- if(nfac[++i]!=2) goto lbl110;
- /*
- * transform for factor of 2 (including rotation factor)
- */
- kspan /= 2;
- k1 = kspan + 2;
- do{ do{ k2 = kk + kspan;
- ak = a[k2];
- bk = b[k2];
- a[k2] = (float)((a[kk]) - ak);
- b[k2] = (float)((b[kk]) - bk);
- a[kk] = (float)((a[kk]) + ak);
- b[kk] = (float)((b[kk]) + bk);
- kk = k2 + kspan;
- } while(kk <= nn);
- kk -= nn;
- }while(kk <= jc);
- if(kk > kspan) goto lbl350;
- lbl60: c1 = 1.0 - cd;
- s1 = sd;
- mm = min((k1/2),klim);
- goto lbl80;
- lbl70: ak = c1 - ((cd*c1)+(sd*s1));
- s1 = ((sd*c1)-(cd*s1)) + s1;
- c1 = ak;
- lbl80: do{ do{ k2 = kk + kspan;
- ak = a[kk] - a[k2];
- bk = b[kk] - b[k2];
- a[kk] = a[kk] + a[k2];
- b[kk] = b[kk] + b[k2];
- a[k2] = (float)((c1 * ak) - (s1 * bk));
- b[k2] = (float)((s1 * ak) + (c1 * bk));
- kk = k2 + kspan;
- }while(kk < nt);
- k2 = kk - nt;
- c1 = -c1;
- kk = k1 - k2;
- }while(kk > k2);
- kk += jc;
- if(kk <= mm) goto lbl70;
- if(kk < k2) goto lbl90;
- k1 += (inc + inc);
- kk = ((k1-kspan)/2) + jc;
- if(kk <= (jc+jc)) goto lbl60;
- goto lbl40;
- lbl90: s1 = ((double)((kk-1)/jc)) * dr * rad;
- c1 = cos(s1);
- s1 = sin(s1);
- mm = min( k1/2, mm+klim);
- goto lbl80;
- /*
- * transform for factor of 3 (optional code)
- */
- lbl100: k1 = kk + kspan;
- k2 = k1 + kspan;
- ak = a[kk];
- bk = b[kk];
- aj = a[k1] + a[k2];
- bj = b[k1] + b[k2];
- a[kk] = (float)(ak + aj);
- b[kk] = (float)(bk + bj);
- ak += (-0.5 * aj);
- bk += (-0.5 * bj);
- aj = (a[k1] - a[k2]) * s120;
- bj = (b[k1] - b[k2]) * s120;
- a[k1] = (float)(ak - bj);
- b[k1] = (float)(bk + aj);
- a[k2] = (float)(ak + bj);
- b[k2] = (float)(bk - aj);
- kk = k2 + kspan;
- if(kk < nn) goto lbl100;
- kk -= nn;
- if(kk <= kspan) goto lbl100;
- goto lbl290;
- /*
- * transform for factor of 4
- */
- lbl110: if(nfac[i] != 4) goto lbl230;
- kspnn = kspan;
- kspan = kspan/4;
- lbl120: c1 = 1.0;
- s1 = 0;
- mm = min( kspan, klim);
- goto lbl150;
- lbl130: c2 = c1 - ((cd*c1)+(sd*s1));
- s1 = ((sd*c1)-(cd*s1)) + s1;
- /*
- * the following three statements compensate for truncation
- * error. if rounded arithmetic is used, substitute
- * c1=c2
- *
- * c1 = (0.5/(pow2(c2)+pow2(s1))) + 0.5;
- * s1 = c1*s1;
- * c1 = c1*c2;
- */
- c1 = c2;
- lbl140: c2 = (c1 * c1) - (s1 * s1);
- s2 = c1 * s1 * 2.0;
- c3 = (c2 * c1) - (s2 * s1);
- s3 = (c2 * s1) + (s2 * c1);
- lbl150: k1 = kk + kspan;
- k2 = k1 + kspan;
- k3 = k2 + kspan;
- akp = a[kk] + a[k2];
- akm = a[kk] - a[k2];
- ajp = a[k1] + a[k3];
- ajm = a[k1] - a[k3];
- a[kk] = (float)(akp + ajp);
- ajp = akp - ajp;
- bkp = b[kk] + b[k2];
- bkm = b[kk] - b[k2];
- bjp = b[k1] + b[k3];
- bjm = b[k1] - b[k3];
- b[kk] = (float)(bkp + bjp);
- bjp = (float)(bkp - bjp);
- if(isn < 0) goto lbl180;
- akp = akm - bjm;
- akm = akm + bjm;
- bkp = bkm + ajm;
- bkm = bkm - ajm;
- if(s1 == 0.0) goto lbl190;
- lbl160: a[k1] = (float)((akp*c1) - (bkp*s1));
- b[k1] = (float)((akp*s1) + (bkp*c1));
- a[k2] = (float)((ajp*c2) - (bjp*s2));
- b[k2] = (float)((ajp*s2) + (bjp*c2));
- a[k3] = (float)((akm*c3) - (bkm*s3));
- b[k3] = (float)((akm*s3) + (bkm*c3));
- kk = k3 + kspan;
- if(kk <= nt) goto lbl150;
- lbl170: kk -= (nt - jc);
- if(kk <= mm) goto lbl130;
- if(kk < kspan) goto lbl200;
- kk -= (kspan - inc);
- if(kk <= jc) goto lbl120;
- if(kspan==jc) goto lbl350;
- goto lbl40;
- lbl180: akp = akm + bjm;
- akm = akm - bjm;
- bkp = bkm - ajm;
- bkm = bkm + ajm;
- if(s1 != 0.0) goto lbl160;
- lbl190: a[k1] = (float)akp;
- b[k1] = (float)bkp;
- a[k2] = (float)ajp;
- b[k2] = (float)bjp;
- a[k3] = (float)akm;
- b[k3] = (float)bkm;
- kk = k3 + kspan;
- if(kk <= nt) goto lbl150;
- goto lbl170;
- lbl200: s1 = ((double)((kk-1)/jc)) * dr * rad;
- c1 = cos(s1);
- s1 = sin(s1);
- mm = min( kspan, mm+klim);
- goto lbl140;
- /*
- * transform for factor of 5 (optional code)
- */
- lbl210: c2 = (c72*c72) - (s72*s72);
- s2 = 2.0 * c72 * s72;
- lbl220: k1 = kk + kspan;
- k2 = k1 + kspan;
- k3 = k2 + kspan;
- k4 = k3 + kspan;
- akp = a[k1] + a[k4];
- akm = a[k1] - a[k4];
- bkp = b[k1] + b[k4];
- bkm = b[k1] - b[k4];
- ajp = a[k2] + a[k3];
- ajm = a[k2] - a[k3];
- bjp = b[k2] + b[k3];
- bjm = b[k2] - b[k3];
- aa = a[kk];
- bb = b[kk];
- a[kk] = (float)(aa + akp + ajp);
- b[kk] = (float)(bb + bkp + bjp);
- ak = (akp*c72) + (ajp*c2) + aa;
- bk = (bkp*c72) + (bjp*c2) + bb;
- aj = (akm*s72) + (ajm*s2);
- bj = (bkm*s72) + (bjm*s2);
- a[k1] = (float)(ak - bj);
- a[k4] = (float)(ak + bj);
- b[k1] = (float)(bk + aj);
- b[k4] = (float)(bk - aj);
- ak = (akp*c2) + (ajp*c72) + aa;
- bk = (bkp*c2) + (bjp*c72) + bb;
- aj = (akm*s2) - (ajm*s72);
- bj = (bkm*s2) - (bjm*s72);
- a[k2] = (float)(ak - bj);
- a[k3] = (float)(ak + bj);
- b[k2] = (float)(bk + aj);
- b[k3] = (float)(bk - aj);
- kk = k4 + kspan;
- if(kk < nn) goto lbl220;
- kk -= nn;
- if(kk <= kspan) goto lbl220;
- goto lbl290;
- /*
- * transform for odd factors
- */
- lbl230: k = nfac[i];
- kspnn = kspan;
- kspan /= k;
- if(k==3) goto lbl100;
- if(k==5) goto lbl210;
- if(k==jf) goto lbl250;
- jf = k;
- s1 = rad/(((double)(k))/8.0);
- c1 = cos(s1);
- s1 = sin(s1);
- ck[jf] = 1.0f;
- sk[jf] = 0.0f;
- for(j=1; j<k ; j++){
- ck[j] = (float)((ck[k])*c1 + (sk[k])*s1);
- sk[j] = (float)((ck[k])*s1 - (sk[k])*c1);
- k--;
- ck[k] = ck[j];
- sk[k] = -(sk[j]);
- }
- lbl250: k1 = kk;
- k2 = kk + kspnn;
- aa = a[kk];
- bb = b[kk];
- ak = aa;
- bk = bb;
- j = 1;
- k1 += kspan;
- do{ k2 -= kspan;
- j++;
- at[j] = a[k1] + a[k2];
- ak = at[j] + ak;
- bt[j] = b[k1] + b[k2];
- bk = bt[j] + bk;
- j++;
- at[j] = a[k1] - a[k2];
- bt[j] = b[k1] - b[k2];
- k1 += kspan;
- }while(k1 < k2);
- a[kk] = (float)ak;
- b[kk] = (float)bk;
- k1 = kk;
- k2 = kk + kspnn;
- j = 1;
- lbl270: k1 += kspan;
- k2 -= kspan;
- jj = j;
- ak = aa;
- bk = bb;
- aj = 0.0;
- bj = 0.0;
- k = 1;
- do{ k++;
- ak = (at[k] * ck[jj]) + ak;
- bk = (bt[k] * ck[jj]) + bk;
- k++;
- aj = (at[k] * sk[jj]) + aj;
- bj = (bt[k] * sk[jj]) + bj;
- jj += j;
- if (jj > jf)
- jj -= jf;
- }while(k < jf);
- k = jf - j;
- a[k1] = (float)(ak - bj);
- b[k1] = (float)(bk + aj);
- a[k2] = (float)(ak + bj);
- b[k2] = (float)(bk - aj);
- j++;
- if(j < k) goto lbl270;
- kk += kspnn;
- if(kk <= nn) goto lbl250;
- kk -= nn;
- if(kk<=kspan) goto lbl250;
- /*
- * multiply by rotation factor (except for factors of 2 and 4)
- */
- lbl290: if(i==m) goto lbl350;
- kk = jc + 1;
- lbl300: c2 = 1.0 - cd;
- s1 = sd;
- mm = min( kspan, klim);
- goto lbl320;
- lbl310: c2 = c1 - ((cd*c1) + (sd*s1));
- s1 = s1 + ((sd*c1) - (cd*s1));
- lbl320: c1 = c2;
- s2 = s1;
- kk += kspan;
- lbl330: ak = a[kk];
- a[kk] = (float)((c2*ak) - (s2 * b[kk]));
- b[kk] = (float)((s2*ak) + (c2 * b[kk]));
- kk += kspnn;
- if(kk <= nt) goto lbl330;
- ak = s1*s2;
- s2 = (s1*c2) + (c1*s2);
- c2 = (c1*c2) - ak;
- kk -= (nt - kspan);
- if(kk <= kspnn) goto lbl330;
- kk -= (kspnn - jc);
- if(kk <= mm) goto lbl310;
- if(kk < kspan) goto lbl340;
- kk -= (kspan - jc - inc);
- if(kk <= (jc+jc)) goto lbl300;
- goto lbl40;
- lbl340: s1 = ((double)((kk-1)/jc)) * dr * rad;
- c2 = cos(s1);
- s1 = sin(s1);
- mm = min( kspan, mm+klim);
- goto lbl320;
- /*
- * permute the results to normal order---done in two stages
- * permutation for square factors of n
- */
- lbl350: np[1] = ks;
- if (!(*kt)) goto lbl440;
- k = *kt + *kt + 1;
- if(m < k)
- k--;
- np[k+1] = jc;
- for(j=1; j < k; j++,k--){
- np[j+1] = np[j] / nfac[j];
- np[k] = np[k+1] * nfac[j];
- }
- k3 = np[k+1];
- kspan = np[2];
- kk = jc + 1;
- k2 = kspan + 1;
- j = 1;
- if(n != ntot) goto lbl400;
- /*
- * permutation for single-variate transform (optional code)
- */
- lbl370: do{ ak = a[kk];
- a[kk] = a[k2];
- a[k2] = (float)ak;
- bk = b[kk];
- b[kk] = b[k2];
- b[k2] = (float)bk;
- kk += inc;
- k2 += kspan;
- }while(k2 < ks);
- lbl380: do{ k2 -= np[j++];
- k2 += np[j+1];
- }while(k2 > np[j]);
- j = 1;
- lbl390: if(kk < k2){
- goto lbl370;
- }
- kk += inc;
- k2 += kspan;
- if(k2 < ks) goto lbl390;
- if(kk < ks) goto lbl380;
- jc = k3;
- goto lbl440;
- /*
- * permutation for multivariate transform
- */
- lbl400: do{ do{ k = kk + jc;
- do{ ak = a[kk];
- a[kk] = a[k2];
- a[k2] = (float)ak;
- bk = b[kk];
- b[kk] = b[k2];
- b[k2] = (float)bk;
- kk += inc;
- k2 += inc;
- }while(kk < k);
- kk += (ks - jc);
- k2 += (ks - jc);
- }while(kk < nt);
- k2 -= (nt - kspan);
- kk -= (nt - jc);
- }while(k2 < ks);
- lbl420: do{ k2 -= np[j++];
- k2 += np[j+1];
- }while(k2 > np[j]);
- j = 1;
- lbl430: if(kk < k2) goto lbl400;
- kk += jc;
- k2 += kspan;
- if(k2 < ks) goto lbl430;
- if(kk < ks) goto lbl420;
- jc = k3;
- lbl440: if((2*(*kt))+1 >= m)
- return(FINISHED);
- kspnn = *(np + *(kt) + 1);
- j = m - *kt;
- nfac[j+1] = 1;
- lbl450: nfac[j] = nfac[j] * nfac[j+1];
- j--;
- if(j != *kt) goto lbl450;
- *kt = *(kt) + 1;
- nn = nfac[*kt] - 1;
- jj = 0;
- j = 0;
- goto lbl480;
- lbl460: jj -= k2;
- k2 = kk;
- kk = nfac[++k];
- lbl470: jj += kk;
- if(jj >= k2) goto lbl460;
- np[j] = jj;
- lbl480: k2 = nfac[*kt];
- k = *kt + 1;
- kk = nfac[k];
- j++;
- if(j <= nn) goto lbl470;
- /* Determine permutation cycles of length greater than 1 */
- j = 0;
- goto lbl500;
- lbl490: k = kk;
- kk = np[k];
- np[k] = -kk;
- if(kk != j) goto lbl490;
- k3 = kk;
- lbl500: kk = np[++j];
- if(kk < 0) goto lbl500;
- if(kk != j) goto lbl490;
- np[j] = -j;
- if(j != nn) goto lbl500;
- maxf *= inc;
- /* Perform reordering following permutation cycles */
- goto lbl570;
- lbl510: j--;
- if (np[j] < 0) goto lbl510;
- jj = jc;
- lbl520: kspan = jj;
- if(jj > maxf)
- kspan = maxf;
- jj -= kspan;
- k = np[j];
- kk = (jc*k) + i + jj;
- k1 = kk + kspan;
- k2 = 0;
- lbl530: k2++;
- at[k2] = a[k1];
- bt[k2] = b[k1];
- k1 -= inc;
- if(k1 != kk) goto lbl530;
- lbl540: k1 = kk + kspan;
- k2 = k1 - (jc * (k + np[k]));
- k = -(np[k]);
- lbl550: a[k1] = a[k2];
- b[k1] = b[k2];
- k1 -= inc;
- k2 -= inc;
- if(k1 != kk) goto lbl550;
- kk = k2;
- if(k != j) goto lbl540;
- k1 = kk + kspan;
- k2 = 0;
- lbl560: k2++;
- a[k1] = at[k2];
- b[k1] = bt[k2];
- k1 -= inc;
- if(k1 != kk) goto lbl560;
- if(jj) goto lbl520;
- if(j != 1) goto lbl510;
- lbl570: j = k3 + 1;
- nt -= kspnn;
- i = nt - inc + 1;
- if(nt >= 0) goto lbl510;
- return(FINISHED);;
- }
- /*
- *-----------------------------------------------------------------------
- * subroutine: reals
- * used with 'fft' to compute fourier transform or inverse for real data
- *-----------------------------------------------------------------------
- * this is the call from C:
- * reals_(anal,banal,N2,mtwo);
- * which has been changed from CARL call
- * reals_(anal,banal,&N2,&mtwo);
- */
- int reals_(float *a, float *b, int n, int isn)
- /* a refers to an array of floats 'anal' */
- /* b refers to an array of floats 'banal' */
- /* See IEEE book for a long comment here on usage */
- { int inc,
- j,
- k,
- lim,
- mm,ml,
- nf,nk,nh;
-
- double aa,ab,
- ba,bb,
- cd,cn,
- dr,
- em,
- rad,re,
- sd,sn;
- double xx; /******* ADDED APRIL 1991 ******/
- /* adjust input array pointers (called from C) */
- a--; b--;
- inc=abs(isn);
- nf=abs(n);
- if(nf*isn==0){
- sprintf(errstr,"zero in reals parameters in FFT : %d : %d ",n,isn);
- return(DATA_ERROR);;
- }
- nk = (nf*inc) + 2;
- nh = nk/2;
- /*****************************
- rad = atan((double)1.0);
- ******************************/
- rad = 0.785398163397448278900;
- dr = -4.0/(double)(nf);
- /********************************** POW2 REMOVED APRIL 1991 *****************
- cd = 2.0 * (pow2(sin((double)0.5 * dr * rad)));
- *****************************************************************************/
- xx = sin((double)0.5 * dr * rad);
- cd = 2.0 * xx * xx;
- sd = sin(dr * rad);
- /*
- * sin,cos values are re-initialized each lim steps
- */
- lim = 32;
- mm = lim;
- ml = 0;
- sn = 0.0;
- if(isn<0){
- cn = 1.0;
- a[nk-1] = a[1];
- b[nk-1] = b[1]; }
- else {
- cn = -1.0;
- sd = -sd;
- }
- for(j=1;j<=nh;j+=inc) {
- k = nk - j;
- aa = a[j] + a[k];
- ab = a[j] - a[k];
- ba = b[j] + b[k];
- bb = b[j] - b[k];
- re = (cn*ba) + (sn*ab);
- em = (sn*ba) - (cn*ab);
- b[k] = (float)((em-bb)*0.5);
- b[j] = (float)((em+bb)*0.5);
- a[k] = (float)((aa-re)*0.5);
- a[j] = (float)((aa+re)*0.5);
- ml++;
- if(ml!=mm){
- aa = cn - ((cd*cn)+(sd*sn));
- sn = ((sd*cn) - (cd*sn)) + sn;
- cn = aa;}
- else {
- mm +=lim;
- sn = ((float)ml) * dr * rad;
- cn = cos(sn);
- if(isn>0)
- cn = -cn;
- sn = sin(sn);
- }
- }
- return(FINISHED);
- }
|