Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

Transform4.cc

Go to the documentation of this file.
00001 /*
00002 
00003     DFT, DCT and DST routines
00004     Copyright (C) 1996-1999 Takuya OOURA
00005     Copyright (C) 1999-2003 Jussi Laako
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     Version 1.0 : Converted T.OOURA's functions to C++ class
00022     Version 1.1 : Updated to match T.OOURA's Oct/99 code and all versions
00023     Version 1.2 : Some conversion and precision updates
00024 
00025 */
00026 
00027 
00028 /* This is decimation-in-frequency radix-2/4 transform */
00029 
00030 
00031 /*
00032 Fast Fourier/Cosine/Sine Transform
00033     dimension   :one
00034     data length :power of 2
00035     decimation  :frequency
00036     radix       :4, 2
00037     data        :inplace
00038     table       :use
00039 functions
00040     cdft: Complex Discrete Fourier Transform
00041     rdft: Real Discrete Fourier Transform
00042     ddct: Discrete Cosine Transform
00043     ddst: Discrete Sine Transform
00044     dfct: Cosine Transform of RDFT (Real Symmetric DFT)
00045     dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
00046 function prototypes
00047     void cdft(int, int, double *, int *, double *);
00048     void rdft(int, int, double *, int *, double *);
00049     void ddct(int, int, double *, int *, double *);
00050     void ddst(int, int, double *, int *, double *);
00051     void dfct(int, double *, double *, int *, double *);
00052     void dfst(int, double *, double *, int *, double *);
00053 
00054 
00055 -------- Complex DFT (Discrete Fourier Transform) --------
00056     [definition]
00057         <case1>
00058             X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
00059         <case2>
00060             X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
00061         (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
00062     [usage]
00063         <case1>
00064             ip[0] = 0; // first time only
00065             cdft(2*n, 1, a, ip, w);
00066         <case2>
00067             ip[0] = 0; // first time only
00068             cdft(2*n, -1, a, ip, w);
00069     [parameters]
00070         2*n            :data length (int)
00071                         n >= 1, n = power of 2
00072         a[0...2*n-1]   :input/output data (double *)
00073                         input data
00074                             a[2*j] = Re(x[j]), 
00075                             a[2*j+1] = Im(x[j]), 0<=j<n
00076                         output data
00077                             a[2*k] = Re(X[k]), 
00078                             a[2*k+1] = Im(X[k]), 0<=k<n
00079         ip[0...*]      :work area for bit reversal (int *)
00080                         length of ip >= 2+sqrt(n)
00081                         strictly, 
00082                         length of ip >= 
00083                             2+(1<<(int)(log(n+0.5)/log(2))/2).
00084                         ip[0],ip[1] are pointers of the cos/sin table.
00085         w[0...n/2-1]   :cos/sin table (double *)
00086                         w[],ip[] are initialized if ip[0] == 0.
00087     [remark]
00088         Inverse of 
00089             cdft(2*n, -1, a, ip, w);
00090         is 
00091             cdft(2*n, 1, a, ip, w);
00092             for (j = 0; j <= 2 * n - 1; j++) {
00093                 a[j] *= 1.0 / n;
00094             }
00095         .
00096 
00097 
00098 -------- Real DFT / Inverse of Real DFT --------
00099     [definition]
00100         <case1> RDFT
00101             R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
00102             I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
00103         <case2> IRDFT (excluding scale)
00104             a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + 
00105                    sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + 
00106                    sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
00107     [usage]
00108         <case1>
00109             ip[0] = 0; // first time only
00110             rdft(n, 1, a, ip, w);
00111         <case2>
00112             ip[0] = 0; // first time only
00113             rdft(n, -1, a, ip, w);
00114     [parameters]
00115         n              :data length (int)
00116                         n >= 2, n = power of 2
00117         a[0...n-1]     :input/output data (double *)
00118                         <case1>
00119                             output data
00120                                 a[2*k] = R[k], 0<=k<n/2
00121                                 a[2*k+1] = I[k], 0<k<n/2
00122                                 a[1] = R[n/2]
00123                         <case2>
00124                             input data
00125                                 a[2*j] = R[j], 0<=j<n/2
00126                                 a[2*j+1] = I[j], 0<j<n/2
00127                                 a[1] = R[n/2]
00128         ip[0...*]      :work area for bit reversal (int *)
00129                         length of ip >= 2+sqrt(n/2)
00130                         strictly, 
00131                         length of ip >= 
00132                             2+(1<<(int)(log(n/2+0.5)/log(2))/2).
00133                         ip[0],ip[1] are pointers of the cos/sin table.
00134         w[0...n/2-1]   :cos/sin table (double *)
00135                         w[],ip[] are initialized if ip[0] == 0.
00136     [remark]
00137         Inverse of 
00138             rdft(n, 1, a, ip, w);
00139         is 
00140             rdft(n, -1, a, ip, w);
00141             for (j = 0; j <= n - 1; j++) {
00142                 a[j] *= 2.0 / n;
00143             }
00144         .
00145 
00146 
00147 -------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
00148     [definition]
00149         <case1> IDCT (excluding scale)
00150             C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n
00151         <case2> DCT
00152             C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n
00153     [usage]
00154         <case1>
00155             ip[0] = 0; // first time only
00156             ddct(n, 1, a, ip, w);
00157         <case2>
00158             ip[0] = 0; // first time only
00159             ddct(n, -1, a, ip, w);
00160     [parameters]
00161         n              :data length (int)
00162                         n >= 2, n = power of 2
00163         a[0...n-1]     :input/output data (double *)
00164                         output data
00165                             a[k] = C[k], 0<=k<n
00166         ip[0...*]      :work area for bit reversal (int *)
00167                         length of ip >= 2+sqrt(n/2)
00168                         strictly, 
00169                         length of ip >= 
00170                             2+(1<<(int)(log(n/2+0.5)/log(2))/2).
00171                         ip[0],ip[1] are pointers of the cos/sin table.
00172         w[0...n*5/4-1] :cos/sin table (double *)
00173                         w[],ip[] are initialized if ip[0] == 0.
00174     [remark]
00175         Inverse of 
00176             ddct(n, -1, a, ip, w);
00177         is 
00178             a[0] *= 0.5;
00179             ddct(n, 1, a, ip, w);
00180             for (j = 0; j <= n - 1; j++) {
00181                 a[j] *= 2.0 / n;
00182             }
00183         .
00184 
00185 
00186 -------- DST (Discrete Sine Transform) / Inverse of DST --------
00187     [definition]
00188         <case1> IDST (excluding scale)
00189             S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n
00190         <case2> DST
00191             S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n
00192     [usage]
00193         <case1>
00194             ip[0] = 0; // first time only
00195             ddst(n, 1, a, ip, w);
00196         <case2>
00197             ip[0] = 0; // first time only
00198             ddst(n, -1, a, ip, w);
00199     [parameters]
00200         n              :data length (int)
00201                         n >= 2, n = power of 2
00202         a[0...n-1]     :input/output data (double *)
00203                         <case1>
00204                             input data
00205                                 a[j] = A[j], 0<j<n
00206                                 a[0] = A[n]
00207                             output data
00208                                 a[k] = S[k], 0<=k<n
00209                         <case2>
00210                             output data
00211                                 a[k] = S[k], 0<k<n
00212                                 a[0] = S[n]
00213         ip[0...*]      :work area for bit reversal (int *)
00214                         length of ip >= 2+sqrt(n/2)
00215                         strictly, 
00216                         length of ip >= 
00217                             2+(1<<(int)(log(n/2+0.5)/log(2))/2).
00218                         ip[0],ip[1] are pointers of the cos/sin table.
00219         w[0...n*5/4-1] :cos/sin table (double *)
00220                         w[],ip[] are initialized if ip[0] == 0.
00221     [remark]
00222         Inverse of 
00223             ddst(n, -1, a, ip, w);
00224         is 
00225             a[0] *= 0.5;
00226             ddst(n, 1, a, ip, w);
00227             for (j = 0; j <= n - 1; j++) {
00228                 a[j] *= 2.0 / n;
00229             }
00230         .
00231 
00232 
00233 -------- Cosine Transform of RDFT (Real Symmetric DFT) --------
00234     [definition]
00235         C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n
00236     [usage]
00237         ip[0] = 0; // first time only
00238         dfct(n, a, t, ip, w);
00239     [parameters]
00240         n              :data length - 1 (int)
00241                         n >= 2, n = power of 2
00242         a[0...n]       :input/output data (double *)
00243                         output data
00244                             a[k] = C[k], 0<=k<=n
00245         t[0...n/2]     :work area (double *)
00246         ip[0...*]      :work area for bit reversal (int *)
00247                         length of ip >= 2+sqrt(n/4)
00248                         strictly, 
00249                         length of ip >= 
00250                             2+(1<<(int)(log(n/4+0.5)/log(2))/2).
00251                         ip[0],ip[1] are pointers of the cos/sin table.
00252         w[0...n*5/8-1] :cos/sin table (double *)
00253                         w[],ip[] are initialized if ip[0] == 0.
00254     [remark]
00255         Inverse of 
00256             a[0] *= 0.5;
00257             a[n] *= 0.5;
00258             dfct(n, a, t, ip, w);
00259         is 
00260             a[0] *= 0.5;
00261             a[n] *= 0.5;
00262             dfct(n, a, t, ip, w);
00263             for (j = 0; j <= n; j++) {
00264                 a[j] *= 2.0 / n;
00265             }
00266         .
00267 
00268 
00269 -------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------
00270     [definition]
00271         S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n
00272     [usage]
00273         ip[0] = 0; // first time only
00274         dfst(n, a, t, ip, w);
00275     [parameters]
00276         n              :data length + 1 (int)
00277                         n >= 2, n = power of 2
00278         a[0...n-1]     :input/output data (double *)
00279                         output data
00280                             a[k] = S[k], 0<k<n
00281                         (a[0] is used for work area)
00282         t[0...n/2-1]   :work area (double *)
00283         ip[0...*]      :work area for bit reversal (int *)
00284                         length of ip >= 2+sqrt(n/4)
00285                         strictly, 
00286                         length of ip >= 
00287                             2+(1<<(int)(log(n/4+0.5)/log(2))/2).
00288                         ip[0],ip[1] are pointers of the cos/sin table.
00289         w[0...n*5/8-1] :cos/sin table (double *)
00290                         w[],ip[] are initialized if ip[0] == 0.
00291     [remark]
00292         Inverse of 
00293             dfst(n, a, t, ip, w);
00294         is 
00295             dfst(n, a, t, ip, w);
00296             for (j = 1; j <= n - 1; j++) {
00297                 a[j] *= 2.0 / n;
00298             }
00299         .
00300 
00301 
00302 Appendix :
00303     The cos/sin table is recalculated when the larger table required.
00304     w[] and ip[] are compatible with all routines.
00305 */
00306 
00307 
00308 #ifdef USE_INTEL_MATH
00309     #include <mathimf.h>
00310 #else
00311     #include <math.h>
00312 #endif
00313 #include <float.h>
00314 
00315 #include "dsp/Transform4.hh"
00316 
00317 
00318 void clTransform4::cdft(long n, long isgn, float *a, long *ip, float *w)
00319 {
00320     if (n > (ip[0] << 2)) {
00321         makewt(n >> 2, ip, w);
00322     }
00323     if (n > 4) {
00324         if (isgn >= 0) {
00325             bitrv2(n, ip + 2, a);
00326             cftfsub(n, a, w);
00327         } else {
00328             bitrv2conj(n, ip + 2, a);
00329             cftbsub(n, a, w);
00330         }
00331     } else if (n == 4) {
00332         cftfsub(n, a, w);
00333     }
00334 }
00335 
00336 
00337 void clTransform4::rdft(long n, long isgn, float *a, long *ip, float *w)
00338 {
00339     long nw, nc;
00340     float xi;
00341     
00342     nw = ip[0];
00343     if (n > (nw << 2)) {
00344         nw = n >> 2;
00345         makewt(nw, ip, w);
00346     }
00347     nc = ip[1];
00348     if (n > (nc << 2)) {
00349         nc = n >> 2;
00350         makect(nc, ip, w + nw);
00351     }
00352     if (isgn >= 0) {
00353         if (n > 4) {
00354             bitrv2(n, ip + 2, a);
00355             cftfsub(n, a, w);
00356             rftfsub(n, a, nc, w + nw);
00357         } else if (n == 4) {
00358             cftfsub(n, a, w);
00359         }
00360         xi = a[0] - a[1];
00361         a[0] += a[1];
00362         a[1] = xi;
00363     } else {
00364         a[1] = 0.5f * (a[0] - a[1]);
00365         a[0] -= a[1];
00366         if (n > 4) {
00367             rftbsub(n, a, nc, w + nw);
00368             bitrv2(n, ip + 2, a);
00369             cftbsub(n, a, w);
00370         } else if (n == 4) {
00371             cftfsub(n, a, w);
00372         }
00373     }
00374 }
00375 
00376 
00377 void clTransform4::ddct(long n, long isgn, float *a, long *ip, float *w)
00378 {
00379     long j, nw, nc;
00380     float xr;
00381     
00382     nw = ip[0];
00383     if (n > (nw << 2)) {
00384         nw = n >> 2;
00385         makewt(nw, ip, w);
00386     }
00387     nc = ip[1];
00388     if (n > nc) {
00389         nc = n;
00390         makect(nc, ip, w + nw);
00391     }
00392     if (isgn < 0) {
00393         xr = a[n - 1];
00394         for (j = n - 2; j >= 2; j -= 2) {
00395             a[j + 1] = a[j] - a[j - 1];
00396             a[j] += a[j - 1];
00397         }
00398         a[1] = a[0] - xr;
00399         a[0] += xr;
00400         if (n > 4) {
00401             rftbsub(n, a, nc, w + nw);
00402             bitrv2(n, ip + 2, a);
00403             cftbsub(n, a, w);
00404         } else if (n == 4) {
00405             cftfsub(n, a, w);
00406         }
00407     }
00408     dctsub(n, a, nc, w + nw);
00409     if (isgn >= 0) {
00410         if (n > 4) {
00411             bitrv2(n, ip + 2, a);
00412             cftfsub(n, a, w);
00413             rftfsub(n, a, nc, w + nw);
00414         } else if (n == 4) {
00415             cftfsub(n, a, w);
00416         }
00417         xr = a[0] - a[1];
00418         a[0] += a[1];
00419         for (j = 2; j < n; j += 2) {
00420             a[j - 1] = a[j] - a[j + 1];
00421             a[j] += a[j + 1];
00422         }
00423         a[n - 1] = xr;
00424     }
00425 }
00426 
00427 
00428 void clTransform4::ddst(long n, long isgn, float *a, long *ip, float *w)
00429 {
00430     long j, nw, nc;
00431     float xr;
00432     
00433     nw = ip[0];
00434     if (n > (nw << 2)) {
00435         nw = n >> 2;
00436         makewt(nw, ip, w);
00437     }
00438     nc = ip[1];
00439     if (n > nc) {
00440         nc = n;
00441         makect(nc, ip, w + nw);
00442     }
00443     if (isgn < 0) {
00444         xr = a[n - 1];
00445         for (j = n - 2; j >= 2; j -= 2) {
00446             a[j + 1] = -a[j] - a[j - 1];
00447             a[j] -= a[j - 1];
00448         }
00449         a[1] = a[0] + xr;
00450         a[0] -= xr;
00451         if (n > 4) {
00452             rftbsub(n, a, nc, w + nw);
00453             bitrv2(n, ip + 2, a);
00454             cftbsub(n, a, w);
00455         } else if (n == 4) {
00456             cftfsub(n, a, w);
00457         }
00458     }
00459     dstsub(n, a, nc, w + nw);
00460     if (isgn >= 0) {
00461         if (n > 4) {
00462             bitrv2(n, ip + 2, a);
00463             cftfsub(n, a, w);
00464             rftfsub(n, a, nc, w + nw);
00465         } else if (n == 4) {
00466             cftfsub(n, a, w);
00467         }
00468         xr = a[0] - a[1];
00469         a[0] += a[1];
00470         for (j = 2; j < n; j += 2) {
00471             a[j - 1] = -a[j] - a[j + 1];
00472             a[j] -= a[j + 1];
00473         }
00474         a[n - 1] = -xr;
00475     }
00476 }
00477 
00478 
00479 void clTransform4::dfct(long n, float *a, float *t, long *ip, float *w)
00480 {
00481     long j, k, l, m, mh, nw, nc;
00482     float xr, xi, yr, yi;
00483     
00484     nw = ip[0];
00485     if (n > (nw << 3)) {
00486         nw = n >> 3;
00487         makewt(nw, ip, w);
00488     }
00489     nc = ip[1];
00490     if (n > (nc << 1)) {
00491         nc = n >> 1;
00492         makect(nc, ip, w + nw);
00493     }
00494     m = n >> 1;
00495     yi = a[m];
00496     xi = a[0] + a[n];
00497     a[0] -= a[n];
00498     t[0] = xi - yi;
00499     t[m] = xi + yi;
00500     if (n > 2) {
00501         mh = m >> 1;
00502         for (j = 1; j < mh; j++) {
00503             k = m - j;
00504             xr = a[j] - a[n - j];
00505             xi = a[j] + a[n - j];
00506             yr = a[k] - a[n - k];
00507             yi = a[k] + a[n - k];
00508             a[j] = xr;
00509             a[k] = yr;
00510             t[j] = xi - yi;
00511             t[k] = xi + yi;
00512         }
00513         t[mh] = a[mh] + a[n - mh];
00514         a[mh] -= a[n - mh];
00515         dctsub(m, a, nc, w + nw);
00516         if (m > 4) {
00517             bitrv2(m, ip + 2, a);
00518             cftfsub(m, a, w);
00519             rftfsub(m, a, nc, w + nw);
00520         } else if (m == 4) {
00521             cftfsub(m, a, w);
00522         }
00523         a[n - 1] = a[0] - a[1];
00524         a[1] = a[0] + a[1];
00525         for (j = m - 2; j >= 2; j -= 2) {
00526             a[2 * j + 1] = a[j] + a[j + 1];
00527             a[2 * j - 1] = a[j] - a[j + 1];
00528         }
00529         l = 2;
00530         m = mh;
00531         while (m >= 2) {
00532             dctsub(m, t, nc, w + nw);
00533             if (m > 4) {
00534                 bitrv2(m, ip + 2, t);
00535                 cftfsub(m, t, w);
00536                 rftfsub(m, t, nc, w + nw);
00537             } else if (m == 4) {
00538                 cftfsub(m, t, w);
00539             }
00540             a[n - l] = t[0] - t[1];
00541             a[l] = t[0] + t[1];
00542             k = 0;
00543             for (j = 2; j < m; j += 2) {
00544                 k += l << 2;
00545                 a[k - l] = t[j] - t[j + 1];
00546                 a[k + l] = t[j] + t[j + 1];
00547             }
00548             l <<= 1;
00549             mh = m >> 1;
00550             for (j = 0; j < mh; j++) {
00551                 k = m - j;
00552                 t[j] = t[m + k] - t[m + j];
00553                 t[k] = t[m + k] + t[m + j];
00554             }
00555             t[mh] = t[m + mh];
00556             m = mh;
00557         }
00558         a[l] = t[0];
00559         a[n] = t[2] - t[1];
00560         a[0] = t[2] + t[1];
00561     } else {
00562         a[1] = a[0];
00563         a[2] = t[0];
00564         a[0] = t[1];
00565     }
00566 }
00567 
00568 
00569 void clTransform4::dfst(long n, float *a, float *t, long *ip, float *w)
00570 {
00571     long j, k, l, m, mh, nw, nc;
00572     float xr, xi, yr, yi;
00573     
00574     nw = ip[0];
00575     if (n > (nw << 3)) {
00576         nw = n >> 3;
00577         makewt(nw, ip, w);
00578     }
00579     nc = ip[1];
00580     if (n > (nc << 1)) {
00581         nc = n >> 1;
00582         makect(nc, ip, w + nw);
00583     }
00584     if (n > 2) {
00585         m = n >> 1;
00586         mh = m >> 1;
00587         for (j = 1; j < mh; j++) {
00588             k = m - j;
00589             xr = a[j] + a[n - j];
00590             xi = a[j] - a[n - j];
00591             yr = a[k] + a[n - k];
00592             yi = a[k] - a[n - k];
00593             a[j] = xr;
00594             a[k] = yr;
00595             t[j] = xi + yi;
00596             t[k] = xi - yi;
00597         }
00598         t[0] = a[mh] - a[n - mh];
00599         a[mh] += a[n - mh];
00600         a[0] = a[m];
00601         dstsub(m, a, nc, w + nw);
00602         if (m > 4) {
00603             bitrv2(m, ip + 2, a);
00604             cftfsub(m, a, w);
00605             rftfsub(m, a, nc, w + nw);
00606         } else if (m == 4) {
00607             cftfsub(m, a, w);
00608         }
00609         a[n - 1] = a[1] - a[0];
00610         a[1] = a[0] + a[1];
00611         for (j = m - 2; j >= 2; j -= 2) {
00612             a[2 * j + 1] = a[j] - a[j + 1];
00613             a[2 * j - 1] = -a[j] - a[j + 1];
00614         }
00615         l = 2;
00616         m = mh;
00617         while (m >= 2) {
00618             dstsub(m, t, nc, w + nw);
00619             if (m > 4) {
00620                 bitrv2(m, ip + 2, t);
00621                 cftfsub(m, t, w);
00622                 rftfsub(m, t, nc, w + nw);
00623             } else if (m == 4) {
00624                 cftfsub(m, t, w);
00625             }
00626             a[n - l] = t[1] - t[0];
00627             a[l] = t[0] + t[1];
00628             k = 0;
00629             for (j = 2; j < m; j += 2) {
00630                 k += l << 2;
00631                 a[k - l] = -t[j] - t[j + 1];
00632                 a[k + l] = t[j] - t[j + 1];
00633             }
00634             l <<= 1;
00635             mh = m >> 1;
00636             for (j = 1; j < mh; j++) {
00637                 k = m - j;
00638                 t[j] = t[m + k] + t[m + j];
00639                 t[k] = t[m + k] - t[m + j];
00640             }
00641             t[0] = t[m + mh];
00642             m = mh;
00643         }
00644         a[l] = t[0];
00645     }
00646     a[0] = 0;
00647 }
00648 
00649 
00650 /* -------- initializing routines -------- */
00651 
00652 
00653 void clTransform4::makewt(long nw, long *ip, float *w)
00654 {
00655     long j, nwh;
00656     float delta, x, y;
00657     
00658     ip[0] = nw;
00659     ip[1] = 1;
00660     if (nw > 2) {
00661         nwh = nw >> 1;
00662 #       ifndef TRANSFORM_EXT_PREC
00663         delta = atanf(1.0f) / nwh;
00664 #       else
00665         delta = (float) (atan(1.0) / nwh);
00666 #       endif
00667         w[0] = 1;
00668         w[1] = 0;
00669 #       ifndef TRANSFORM_EXT_PREC
00670         w[nwh] = cosf(delta * nwh);
00671 #       else
00672         w[nwh] = (float) cos(delta * nwh);
00673 #       endif
00674         w[nwh + 1] = w[nwh];
00675         if (nwh > 2) {
00676             for (j = 2; j < nwh; j += 2) {
00677 #               ifndef TRANSFORM_EXT_PREC
00678                 x = cosf(delta * j);
00679                 y = sinf(delta * j);
00680 #               else
00681                 x = (float) cos(delta * j);
00682                 y = (float) sin(delta * j);
00683 #               endif
00684                 w[j] = x;
00685                 w[j + 1] = y;
00686                 w[nw - j] = y;
00687                 w[nw - j + 1] = x;
00688             }
00689             bitrv2(nw, ip + 2, w);
00690         }
00691     }
00692 }
00693 
00694 
00695 void clTransform4::makect(long nc, long *ip, float *c)
00696 {
00697     long j, nch;
00698     float delta;
00699     
00700     ip[1] = nc;
00701     if (nc > 1) {
00702         nch = nc >> 1;
00703 #       ifndef TRANSFORM_EXT_PREC
00704         delta = atanf(1.0f) / nch;
00705         c[0] = cosf(delta * nch);
00706 #       else
00707         delta = (float) (atan(1.0) / nch);
00708         c[0] = (float) cos(delta * nch);
00709 #       endif
00710         c[nch] = 0.5f * c[0];
00711         for (j = 1; j < nch; j++) {
00712 #           ifndef TRANSFORM_EXT_PREC
00713             c[j] = 0.5f * cosf(delta * j);
00714             c[nc - j] = 0.5f * sinf(delta * j);
00715 #           else
00716             c[j] = (float) (0.5 * cos(delta * j));
00717             c[nc - j] = (float) (0.5 * sin(delta * j));
00718 #           endif
00719         }
00720     }
00721 }
00722 
00723 
00724 /* -------- child routines -------- */
00725 
00726 
00727 T4_INLINE void clTransform4::bitrv2(long n, long *ip, float *a)
00728 {
00729     long j, j1, k, k1, l, m, m2;
00730     float xr, xi, yr, yi;
00731     
00732     ip[0] = 0;
00733     l = n;
00734     m = 1;
00735     while ((m << 3) < l) {
00736         l >>= 1;
00737         for (j = 0; j < m; j++) {
00738             ip[m + j] = ip[j] + l;
00739         }
00740         m <<= 1;
00741     }
00742     m2 = 2 * m;
00743     if ((m << 3) == l) {
00744         for (k = 0; k < m; k++) {
00745             for (j = 0; j < k; j++) {
00746                 j1 = 2 * j + ip[k];
00747                 k1 = 2 * k + ip[j];
00748                 xr = a[j1];
00749                 xi = a[j1 + 1];
00750                 yr = a[k1];
00751                 yi = a[k1 + 1];
00752                 a[j1] = yr;
00753                 a[j1 + 1] = yi;
00754                 a[k1] = xr;
00755                 a[k1 + 1] = xi;
00756                 j1 += m2;
00757                 k1 += 2 * m2;
00758                 xr = a[j1];
00759                 xi = a[j1 + 1];
00760                 yr = a[k1];
00761                 yi = a[k1 + 1];
00762                 a[j1] = yr;
00763                 a[j1 + 1] = yi;
00764                 a[k1] = xr;
00765                 a[k1 + 1] = xi;
00766                 j1 += m2;
00767                 k1 -= m2;
00768                 xr = a[j1];
00769                 xi = a[j1 + 1];
00770                 yr = a[k1];
00771                 yi = a[k1 + 1];
00772                 a[j1] = yr;
00773                 a[j1 + 1] = yi;
00774                 a[k1] = xr;
00775                 a[k1 + 1] = xi;
00776                 j1 += m2;
00777                 k1 += 2 * m2;
00778                 xr = a[j1];
00779                 xi = a[j1 + 1];
00780                 yr = a[k1];
00781                 yi = a[k1 + 1];
00782                 a[j1] = yr;
00783                 a[j1 + 1] = yi;
00784                 a[k1] = xr;
00785                 a[k1 + 1] = xi;
00786             }
00787             j1 = 2 * k + m2 + ip[k];
00788             k1 = j1 + m2;
00789             xr = a[j1];
00790             xi = a[j1 + 1];
00791             yr = a[k1];
00792             yi = a[k1 + 1];
00793             a[j1] = yr;
00794             a[j1 + 1] = yi;
00795             a[k1] = xr;
00796             a[k1 + 1] = xi;
00797         }
00798     } else {
00799         for (k = 1; k < m; k++) {
00800             for (j = 0; j < k; j++) {
00801                 j1 = 2 * j + ip[k];
00802                 k1 = 2 * k + ip[j];
00803                 xr = a[j1];
00804                 xi = a[j1 + 1];
00805                 yr = a[k1];
00806                 yi = a[k1 + 1];
00807                 a[j1] = yr;
00808                 a[j1 + 1] = yi;
00809                 a[k1] = xr;
00810                 a[k1 + 1] = xi;
00811                 j1 += m2;
00812                 k1 += m2;
00813                 xr = a[j1];
00814                 xi = a[j1 + 1];
00815                 yr = a[k1];
00816                 yi = a[k1 + 1];
00817                 a[j1] = yr;
00818                 a[j1 + 1] = yi;
00819                 a[k1] = xr;
00820                 a[k1 + 1] = xi;
00821             }
00822         }
00823     }
00824 }
00825 
00826 
00827 T4_INLINE void clTransform4::bitrv2conj(long n, long *ip, float *a)
00828 {
00829     long j, j1, k, k1, l, m, m2;
00830     float xr, xi, yr, yi;
00831     
00832     ip[0] = 0;
00833     l = n;
00834     m = 1;
00835     while ((m << 3) < l) {
00836         l >>= 1;
00837         for (j = 0; j < m; j++) {
00838             ip[m + j] = ip[j] + l;
00839         }
00840         m <<= 1;
00841     }
00842     m2 = 2 * m;
00843     if ((m << 3) == l) {
00844         for (k = 0; k < m; k++) {
00845             for (j = 0; j < k; j++) {
00846                 j1 = 2 * j + ip[k];
00847                 k1 = 2 * k + ip[j];
00848                 xr = a[j1];
00849                 xi = -a[j1 + 1];
00850                 yr = a[k1];
00851                 yi = -a[k1 + 1];
00852                 a[j1] = yr;
00853                 a[j1 + 1] = yi;
00854                 a[k1] = xr;
00855                 a[k1 + 1] = xi;
00856                 j1 += m2;
00857                 k1 += 2 * m2;
00858                 xr = a[j1];
00859                 xi = -a[j1 + 1];
00860                 yr = a[k1];
00861                 yi = -a[k1 + 1];
00862                 a[j1] = yr;
00863                 a[j1 + 1] = yi;
00864                 a[k1] = xr;
00865                 a[k1 + 1] = xi;
00866                 j1 += m2;
00867                 k1 -= m2;
00868                 xr = a[j1];
00869                 xi = -a[j1 + 1];
00870                 yr = a[k1];
00871                 yi = -a[k1 + 1];
00872                 a[j1] = yr;
00873                 a[j1 + 1] = yi;
00874                 a[k1] = xr;
00875                 a[k1 + 1] = xi;
00876                 j1 += m2;
00877                 k1 += 2 * m2;
00878                 xr = a[j1];
00879                 xi = -a[j1 + 1];
00880                 yr = a[k1];
00881                 yi = -a[k1 + 1];
00882                 a[j1] = yr;
00883                 a[j1 + 1] = yi;
00884                 a[k1] = xr;
00885                 a[k1 + 1] = xi;
00886             }
00887             k1 = 2 * k + ip[k];
00888             a[k1 + 1] = -a[k1 + 1];
00889             j1 = k1 + m2;
00890             k1 = j1 + m2;
00891             xr = a[j1];
00892             xi = -a[j1 + 1];
00893             yr = a[k1];
00894             yi = -a[k1 + 1];
00895             a[j1] = yr;
00896             a[j1 + 1] = yi;
00897             a[k1] = xr;
00898             a[k1 + 1] = xi;
00899             k1 += m2;
00900             a[k1 + 1] = -a[k1 + 1];
00901         }
00902     } else {
00903         a[1] = -a[1];
00904         a[m2 + 1] = -a[m2 + 1];
00905         for (k = 1; k < m; k++) {
00906             for (j = 0; j < k; j++) {
00907                 j1 = 2 * j + ip[k];
00908                 k1 = 2 * k + ip[j];
00909                 xr = a[j1];
00910                 xi = -a[j1 + 1];
00911                 yr = a[k1];
00912                 yi = -a[k1 + 1];
00913                 a[j1] = yr;
00914                 a[j1 + 1] = yi;
00915                 a[k1] = xr;
00916                 a[k1 + 1] = xi;
00917                 j1 += m2;
00918                 k1 += m2;
00919                 xr = a[j1];
00920                 xi = -a[j1 + 1];
00921                 yr = a[k1];
00922                 yi = -a[k1 + 1];
00923                 a[j1] = yr;
00924                 a[j1 + 1] = yi;
00925                 a[k1] = xr;
00926                 a[k1 + 1] = xi;
00927             }
00928             k1 = 2 * k + ip[k];
00929             a[k1 + 1] = -a[k1 + 1];
00930             a[k1 + m2 + 1] = -a[k1 + m2 + 1];
00931         }
00932     }
00933 }
00934 
00935 
00936 T4_INLINE void clTransform4::cftfsub(long n, float *a, float *w)
00937 {
00938     long j, j1, j2, j3, l;
00939     float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
00940     
00941     l = 2;
00942     if (n > 8) {
00943         cft1st(n, a, w);
00944         l = 8;
00945         while ((l << 2) < n) {
00946             cftmdl(n, l, a, w);
00947             l <<= 2;
00948         }
00949     }
00950     if ((l << 2) == n) {
00951         for (j = 0; j < l; j += 2) {
00952             j1 = j + l;
00953             j2 = j1 + l;
00954             j3 = j2 + l;
00955             x0r = a[j] + a[j1];
00956             x0i = a[j + 1] + a[j1 + 1];
00957             x1r = a[j] - a[j1];
00958             x1i = a[j + 1] - a[j1 + 1];
00959             x2r = a[j2] + a[j3];
00960             x2i = a[j2 + 1] + a[j3 + 1];
00961             x3r = a[j2] - a[j3];
00962             x3i = a[j2 + 1] - a[j3 + 1];
00963             a[j] = x0r + x2r;
00964             a[j + 1] = x0i + x2i;
00965             a[j2] = x0r - x2r;
00966             a[j2 + 1] = x0i - x2i;
00967             a[j1] = x1r - x3i;
00968             a[j1 + 1] = x1i + x3r;
00969             a[j3] = x1r + x3i;
00970             a[j3 + 1] = x1i - x3r;
00971         }
00972     } else {
00973         for (j = 0; j < l; j += 2) {
00974             j1 = j + l;
00975             x0r = a[j] - a[j1];
00976             x0i = a[j + 1] - a[j1 + 1];
00977             a[j] += a[j1];
00978             a[j + 1] += a[j1 + 1];
00979             a[j1] = x0r;
00980             a[j1 + 1] = x0i;
00981         }
00982     }
00983 }
00984 
00985 
00986 T4_INLINE void clTransform4::cftbsub(long n, float *a, float *w)
00987 {
00988     long j, j1, j2, j3, l;
00989     float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
00990     
00991     l = 2;
00992     if (n > 8) {
00993         cft1st(n, a, w);
00994         l = 8;
00995         while ((l << 2) < n) {
00996             cftmdl(n, l, a, w);
00997             l <<= 2;
00998         }
00999     }
01000     if ((l << 2) == n) {
01001         for (j = 0; j < l; j += 2) {
01002             j1 = j + l;
01003             j2 = j1 + l;
01004             j3 = j2 + l;
01005             x0r = a[j] + a[j1];
01006             x0i = -a[j + 1] - a[j1 + 1];
01007             x1r = a[j] - a[j1];
01008             x1i = -a[j + 1] + a[j1 + 1];
01009             x2r = a[j2] + a[j3];
01010             x2i = a[j2 + 1] + a[j3 + 1];
01011             x3r = a[j2] - a[j3];
01012             x3i = a[j2 + 1] - a[j3 + 1];
01013             a[j] = x0r + x2r;
01014             a[j + 1] = x0i - x2i;
01015             a[j2] = x0r - x2r;
01016             a[j2 + 1] = x0i + x2i;
01017             a[j1] = x1r - x3i;
01018             a[j1 + 1] = x1i - x3r;
01019             a[j3] = x1r + x3i;
01020             a[j3 + 1] = x1i + x3r;
01021         }
01022     } else {
01023         for (j = 0; j < l; j += 2) {
01024             j1 = j + l;
01025             x0r = a[j] - a[j1];
01026             x0i = -a[j + 1] + a[j1 + 1];
01027             a[j] += a[j1];
01028             a[j + 1] = -a[j + 1] - a[j1 + 1];
01029             a[j1] = x0r;
01030             a[j1 + 1] = x0i;
01031         }
01032     }
01033 }
01034 
01035 
01036 T4_INLINE void clTransform4::cft1st(long n, float *a, float *w)
01037 {
01038     long j, k1, k2;
01039     float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
01040     float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
01041     
01042     x0r = a[0] + a[2];
01043     x0i = a[1] + a[3];
01044     x1r = a[0] - a[2];
01045     x1i = a[1] - a[3];
01046     x2r = a[4] + a[6];
01047     x2i = a[5] + a[7];
01048     x3r = a[4] - a[6];
01049     x3i = a[5] - a[7];
01050     a[0] = x0r + x2r;
01051     a[1] = x0i + x2i;
01052     a[4] = x0r - x2r;
01053     a[5] = x0i - x2i;
01054     a[2] = x1r - x3i;
01055     a[3] = x1i + x3r;
01056     a[6] = x1r + x3i;
01057     a[7] = x1i - x3r;
01058     wk1r = w[2];
01059     x0r = a[8] + a[10];
01060     x0i = a[9] + a[11];
01061     x1r = a[8] - a[10];
01062     x1i = a[9] - a[11];
01063     x2r = a[12] + a[14];
01064     x2i = a[13] + a[15];
01065     x3r = a[12] - a[14];
01066     x3i = a[13] - a[15];
01067     a[8] = x0r + x2r;
01068     a[9] = x0i + x2i;
01069     a[12] = x2i - x0i;
01070     a[13] = x0r - x2r;
01071     x0r = x1r - x3i;
01072     x0i = x1i + x3r;
01073     a[10] = wk1r * (x0r - x0i);
01074     a[11] = wk1r * (x0r + x0i);
01075     x0r = x3i + x1r;
01076     x0i = x3r - x1i;
01077     a[14] = wk1r * (x0i - x0r);
01078     a[15] = wk1r * (x0i + x0r);
01079     k1 = 0;
01080     for (j = 16; j < n; j += 16) {
01081         k1 += 2;
01082         k2 = 2 * k1;
01083         wk2r = w[k1];
01084         wk2i = w[k1 + 1];
01085         wk1r = w[k2];
01086         wk1i = w[k2 + 1];
01087         wk3r = wk1r - 2 * wk2i * wk1i;
01088         wk3i = 2 * wk2i * wk1r - wk1i;
01089         x0r = a[j] + a[j + 2];
01090         x0i = a[j + 1] + a[j + 3];
01091         x1r = a[j] - a[j + 2];
01092         x1i = a[j + 1] - a[j + 3];
01093         x2r = a[j + 4] + a[j + 6];
01094         x2i = a[j + 5] + a[j + 7];
01095         x3r = a[j + 4] - a[j + 6];
01096         x3i = a[j + 5] - a[j + 7];
01097         a[j] = x0r + x2r;
01098         a[j + 1] = x0i + x2i;
01099         x0r -= x2r;
01100         x0i -= x2i;
01101         a[j + 4] = wk2r * x0r - wk2i * x0i;
01102         a[j + 5] = wk2r * x0i + wk2i * x0r;
01103         x0r = x1r - x3i;
01104         x0i = x1i + x3r;
01105         a[j + 2] = wk1r * x0r - wk1i * x0i;
01106         a[j + 3] = wk1r * x0i + wk1i * x0r;
01107         x0r = x1r + x3i;
01108         x0i = x1i - x3r;
01109         a[j + 6] = wk3r * x0r - wk3i * x0i;
01110         a[j + 7] = wk3r * x0i + wk3i * x0r;
01111         wk1r = w[k2 + 2];
01112         wk1i = w[k2 + 3];
01113         wk3r = wk1r - 2 * wk2r * wk1i;
01114         wk3i = 2 * wk2r * wk1r - wk1i;
01115         x0r = a[j + 8] + a[j + 10];
01116         x0i = a[j + 9] + a[j + 11];
01117         x1r = a[j + 8] - a[j + 10];
01118         x1i = a[j + 9] - a[j + 11];
01119         x2r = a[j + 12] + a[j + 14];
01120         x2i = a[j + 13] + a[j + 15];
01121         x3r = a[j + 12] - a[j + 14];
01122         x3i = a[j + 13] - a[j + 15];
01123         a[j + 8] = x0r + x2r;
01124         a[j + 9] = x0i + x2i;
01125         x0r -= x2r;
01126         x0i -= x2i;
01127         a[j + 12] = -wk2i * x0r - wk2r * x0i;
01128         a[j + 13] = -wk2i * x0i + wk2r * x0r;
01129         x0r = x1r - x3i;
01130         x0i = x1i + x3r;
01131         a[j + 10] = wk1r * x0r - wk1i * x0i;
01132         a[j + 11] = wk1r * x0i + wk1i * x0r;
01133         x0r = x1r + x3i;
01134         x0i = x1i - x3r;
01135         a[j + 14] = wk3r * x0r - wk3i * x0i;
01136         a[j + 15] = wk3r * x0i + wk3i * x0r;
01137     }
01138 }
01139 
01140 
01141 T4_INLINE void clTransform4::cftmdl(long n, long l, float *a, float *w)
01142 {
01143     long j, j1, j2, j3, k, k1, k2, m, m2;
01144     float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
01145     float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
01146     
01147     m = l << 2;
01148     for (j = 0; j < l; j += 2) {
01149         j1 = j + l;
01150         j2 = j1 + l;
01151         j3 = j2 + l;
01152         x0r = a[j] + a[j1];
01153         x0i = a[j + 1] + a[j1 + 1];
01154         x1r = a[j] - a[j1];
01155         x1i = a[j + 1] - a[j1 + 1];
01156         x2r = a[j2] + a[j3];
01157         x2i = a[j2 + 1] + a[j3 + 1];
01158         x3r = a[j2] - a[j3];
01159         x3i = a[j2 + 1] - a[j3 + 1];
01160         a[j] = x0r + x2r;
01161         a[j + 1] = x0i + x2i;
01162         a[j2] = x0r - x2r;
01163         a[j2 + 1] = x0i - x2i;
01164         a[j1] = x1r - x3i;
01165         a[j1 + 1] = x1i + x3r;
01166         a[j3] = x1r + x3i;
01167         a[j3 + 1] = x1i - x3r;
01168     }
01169     wk1r = w[2];
01170     for (j = m; j < l + m; j += 2) {
01171         j1 = j + l;
01172         j2 = j1 + l;
01173         j3 = j2 + l;
01174         x0r = a[j] + a[j1];
01175         x0i = a[j + 1] + a[j1 + 1];
01176         x1r = a[j] - a[j1];
01177         x1i = a[j + 1] - a[j1 + 1];
01178         x2r = a[j2] + a[j3];
01179         x2i = a[j2 + 1] + a[j3 + 1];
01180         x3r = a[j2] - a[j3];
01181         x3i = a[j2 + 1] - a[j3 + 1];
01182         a[j] = x0r + x2r;
01183         a[j + 1] = x0i + x2i;
01184         a[j2] = x2i - x0i;
01185         a[j2 + 1] = x0r - x2r;
01186         x0r = x1r - x3i;
01187         x0i = x1i + x3r;
01188         a[j1] = wk1r * (x0r - x0i);
01189         a[j1 + 1] = wk1r * (x0r + x0i);
01190         x0r = x3i + x1r;
01191         x0i = x3r - x1i;
01192         a[j3] = wk1r * (x0i - x0r);
01193         a[j3 + 1] = wk1r * (x0i + x0r);
01194     }
01195     k1 = 0;
01196     m2 = 2 * m;
01197     for (k = m2; k < n; k += m2) {
01198         k1 += 2;
01199         k2 = 2 * k1;
01200         wk2r = w[k1];
01201         wk2i = w[k1 + 1];
01202         wk1r = w[k2];
01203         wk1i = w[k2 + 1];
01204         wk3r = wk1r - 2 * wk2i * wk1i;
01205         wk3i = 2 * wk2i * wk1r - wk1i;
01206         for (j = k; j < l + k; j += 2) {
01207             j1 = j + l;
01208             j2 = j1 + l;
01209             j3 = j2 + l;
01210             x0r = a[j] + a[j1];
01211             x0i = a[j + 1] + a[j1 + 1];
01212             x1r = a[j] - a[j1];
01213             x1i = a[j + 1] - a[j1 + 1];
01214             x2r = a[j2] + a[j3];
01215             x2i = a[j2 + 1] + a[j3 + 1];
01216             x3r = a[j2] - a[j3];
01217             x3i = a[j2 + 1] - a[j3 + 1];
01218             a[j] = x0r + x2r;
01219             a[j + 1] = x0i + x2i;
01220             x0r -= x2r;
01221             x0i -= x2i;
01222             a[j2] = wk2r * x0r - wk2i * x0i;
01223             a[j2 + 1] = wk2r * x0i + wk2i * x0r;
01224             x0r = x1r - x3i;
01225             x0i = x1i + x3r;
01226             a[j1] = wk1r * x0r - wk1i * x0i;
01227             a[j1 + 1] = wk1r * x0i + wk1i * x0r;
01228             x0r = x1r + x3i;
01229             x0i = x1i - x3r;
01230             a[j3] = wk3r * x0r - wk3i * x0i;
01231             a[j3 + 1] = wk3r * x0i + wk3i * x0r;
01232         }
01233         wk1r = w[k2 + 2];
01234         wk1i = w[k2 + 3];
01235         wk3r = wk1r - 2 * wk2r * wk1i;
01236         wk3i = 2 * wk2r * wk1r - wk1i;
01237         for (j = k + m; j < l + (k + m); j += 2) {
01238             j1 = j + l;
01239             j2 = j1 + l;
01240             j3 = j2 + l;
01241             x0r = a[j] + a[j1];
01242             x0i = a[j + 1] + a[j1 + 1];
01243             x1r = a[j] - a[j1];
01244             x1i = a[j + 1] - a[j1 + 1];
01245             x2r = a[j2] + a[j3];
01246             x2i = a[j2 + 1] + a[j3 + 1];
01247             x3r = a[j2] - a[j3];
01248             x3i = a[j2 + 1] - a[j3 + 1];
01249             a[j] = x0r + x2r;
01250             a[j + 1] = x0i + x2i;
01251             x0r -= x2r;
01252             x0i -= x2i;
01253             a[j2] = -wk2i * x0r - wk2r * x0i;
01254             a[j2 + 1] = -wk2i * x0i + wk2r * x0r;
01255             x0r = x1r - x3i;
01256             x0i = x1i + x3r;
01257             a[j1] = wk1r * x0r - wk1i * x0i;
01258             a[j1 + 1] = wk1r * x0i + wk1i * x0r;
01259             x0r = x1r + x3i;
01260             x0i = x1i - x3r;
01261             a[j3] = wk3r * x0r - wk3i * x0i;
01262             a[j3 + 1] = wk3r * x0i + wk3i * x0r;
01263         }
01264     }
01265 }
01266 
01267 
01268 T4_INLINE void clTransform4::rftfsub(long n, float *a, long nc, float *c)
01269 {
01270     long j, k, kk, ks, m;
01271     float wkr, wki, xr, xi, yr, yi;
01272     
01273     m = n >> 1;
01274     ks = 2 * nc / m;
01275     kk = 0;
01276     for (j = 2; j < m; j += 2) {
01277         k = n - j;
01278         kk += ks;
01279         wkr = 0.5f - c[nc - kk];
01280         wki = c[kk];
01281         xr = a[j] - a[k];
01282         xi = a[j + 1] + a[k + 1];
01283         yr = wkr * xr - wki * xi;
01284         yi = wkr * xi + wki * xr;
01285         a[j] -= yr;
01286         a[j + 1] -= yi;
01287         a[k] += yr;
01288         a[k + 1] -= yi;
01289     }
01290 }
01291 
01292 
01293 T4_INLINE void clTransform4::rftbsub(long n, float *a, long nc, float *c)
01294 {
01295     long j, k, kk, ks, m;
01296     float wkr, wki, xr, xi, yr, yi;
01297     
01298     a[1] = -a[1];
01299     m = n >> 1;
01300     ks = 2 * nc / m;
01301     kk = 0;
01302     for (j = 2; j < m; j += 2) {
01303         k = n - j;
01304         kk += ks;
01305         wkr = 0.5f - c[nc - kk];
01306         wki = c[kk];
01307         xr = a[j] - a[k];
01308         xi = a[j + 1] + a[k + 1];
01309         yr = wkr * xr + wki * xi;
01310         yi = wkr * xi - wki * xr;
01311         a[j] -= yr;
01312         a[j + 1] = yi - a[j + 1];
01313         a[k] += yr;
01314         a[k + 1] = yi - a[k + 1];
01315     }
01316     a[m + 1] = -a[m + 1];
01317 }
01318 
01319 
01320 T4_INLINE void clTransform4::dctsub(long n, float *a, long nc, float *c)
01321 {
01322     long j, k, kk, ks, m;
01323     float wkr, wki, xr;
01324     
01325     m = n >> 1;
01326     ks = nc / n;
01327     kk = 0;
01328     for (j = 1; j < m; j++) {
01329         k = n - j;
01330         kk += ks;
01331         wkr = c[kk] - c[nc - kk];
01332         wki = c[kk] + c[nc - kk];
01333         xr = wki * a[j] - wkr * a[k];
01334         a[j] = wkr * a[j] + wki * a[k];
01335         a[k] = xr;
01336     }
01337     a[m] *= c[0];
01338 }
01339 
01340 
01341 T4_INLINE void clTransform4::dstsub(long n, float *a, long nc, float *c)
01342 {
01343     long j, k, kk, ks, m;
01344     float wkr, wki, xr;
01345     
01346     m = n >> 1;
01347     ks = nc / n;
01348     kk = 0;
01349     for (j = 1; j < m; j++) {
01350         k = n - j;
01351         kk += ks;
01352         wkr = c[kk] - c[nc - kk];
01353         wki = c[kk] + c[nc - kk];
01354         xr = wki * a[k] - wkr * a[j];
01355         a[k] = wkr * a[k] + wki * a[j];
01356         a[j] = xr;
01357     }
01358     a[m] *= c[0];
01359 }
01360 
01361 
01362 // ----- double versions start here!
01363 
01364 
01365 void clTransform4::cdft(long n, long isgn, double *a, long *ip, double *w)
01366 {
01367     if (n > (ip[0] << 2)) {
01368         makewt(n >> 2, ip, w);
01369     }
01370     if (n > 4) {
01371         if (isgn >= 0) {
01372             bitrv2(n, ip + 2, a);
01373             cftfsub(n, a, w);
01374         } else {
01375             bitrv2conj(n, ip + 2, a);
01376             cftbsub(n, a, w);
01377         }
01378     } else if (n == 4) {
01379         cftfsub(n, a, w);
01380     }
01381 }
01382 
01383 
01384 void clTransform4::rdft(long n, long isgn, double *a, long *ip, double *w)
01385 {
01386     long nw, nc;
01387     double xi;
01388     
01389     nw = ip[0];
01390     if (n > (nw << 2)) {
01391         nw = n >> 2;
01392         makewt(nw, ip, w);
01393     }
01394     nc = ip[1];
01395     if (n > (nc << 2)) {
01396         nc = n >> 2;
01397         makect(nc, ip, w + nw);
01398     }
01399     if (isgn >= 0) {
01400         if (n > 4) {
01401             bitrv2(n, ip + 2, a);
01402             cftfsub(n, a, w);
01403             rftfsub(n, a, nc, w + nw);
01404         } else if (n == 4) {
01405             cftfsub(n, a, w);
01406         }
01407         xi = a[0] - a[1];
01408         a[0] += a[1];
01409         a[1] = xi;
01410     } else {
01411         a[1] = 0.5 * (a[0] - a[1]);
01412         a[0] -= a[1];
01413         if (n > 4) {
01414             rftbsub(n, a, nc, w + nw);
01415             bitrv2(n, ip + 2, a);
01416             cftbsub(n, a, w);
01417         } else if (n == 4) {
01418             cftfsub(n, a, w);
01419         }
01420     }
01421 }
01422 
01423 
01424 void clTransform4::ddct(long n, long isgn, double *a, long *ip, double *w)
01425 {
01426     long j, nw, nc;
01427     double xr;
01428     
01429     nw = ip[0];
01430     if (n > (nw << 2)) {
01431         nw = n >> 2;
01432         makewt(nw, ip, w);
01433     }
01434     nc = ip[1];
01435     if (n > nc) {
01436         nc = n;
01437         makect(nc, ip, w + nw);
01438     }
01439     if (isgn < 0) {
01440         xr = a[n - 1];
01441         for (j = n - 2; j >= 2; j -= 2) {
01442             a[j + 1] = a[j] - a[j - 1];
01443             a[j] += a[j - 1];
01444         }
01445         a[1] = a[0] - xr;
01446         a[0] += xr;
01447         if (n > 4) {
01448             rftbsub(n, a, nc, w + nw);
01449             bitrv2(n, ip + 2, a);
01450             cftbsub(n, a, w);
01451         } else if (n == 4) {
01452             cftfsub(n, a, w);
01453         }
01454     }
01455     dctsub(n, a, nc, w + nw);
01456     if (isgn >= 0) {
01457         if (n > 4) {
01458             bitrv2(n, ip + 2, a);
01459             cftfsub(n, a, w);
01460             rftfsub(n, a, nc, w + nw);
01461         } else if (n == 4) {
01462             cftfsub(n, a, w);
01463         }
01464         xr = a[0] - a[1];
01465         a[0] += a[1];
01466         for (j = 2; j < n; j += 2) {
01467             a[j - 1] = a[j] - a[j + 1];
01468             a[j] += a[j + 1];
01469         }
01470         a[n - 1] = xr;
01471     }
01472 }
01473 
01474 
01475 void clTransform4::ddst(long n, long isgn, double *a, long *ip, double *w)
01476 {
01477     long j, nw, nc;
01478     double xr;
01479     
01480     nw = ip[0];
01481     if (n > (nw << 2)) {
01482         nw = n >> 2;
01483         makewt(nw, ip, w);
01484     }
01485     nc = ip[1];
01486     if (n > nc) {
01487         nc = n;
01488         makect(nc, ip, w + nw);
01489     }
01490     if (isgn < 0) {
01491         xr = a[n - 1];
01492         for (j = n - 2; j >= 2; j -= 2) {
01493             a[j + 1] = -a[j] - a[j - 1];
01494             a[j] -= a[j - 1];
01495         }
01496         a[1] = a[0] + xr;
01497         a[0] -= xr;
01498         if (n > 4) {
01499             rftbsub(n, a, nc, w + nw);
01500             bitrv2(n, ip + 2, a);
01501             cftbsub(n, a, w);
01502         } else if (n == 4) {
01503             cftfsub(n, a, w);
01504         }
01505     }
01506     dstsub(n, a, nc, w + nw);
01507     if (isgn >= 0) {
01508         if (n > 4) {
01509             bitrv2(n, ip + 2, a);
01510             cftfsub(n, a, w);
01511             rftfsub(n, a, nc, w + nw);
01512         } else if (n == 4) {
01513             cftfsub(n, a, w);
01514         }
01515         xr = a[0] - a[1];
01516         a[0] += a[1];
01517         for (j = 2; j < n; j += 2) {
01518             a[j - 1] = -a[j] - a[j + 1];
01519             a[j] -= a[j + 1];
01520         }
01521         a[n - 1] = -xr;
01522     }
01523 }
01524 
01525 
01526 void clTransform4::dfct(long n, double *a, double *t, long *ip, double *w)
01527 {
01528     long j, k, l, m, mh, nw, nc;
01529     double xr, xi, yr, yi;
01530     
01531     nw = ip[0];
01532     if (n > (nw << 3)) {
01533         nw = n >> 3;
01534         makewt(nw, ip, w);
01535     }
01536     nc = ip[1];
01537     if (n > (nc << 1)) {
01538         nc = n >> 1;
01539         makect(nc, ip, w + nw);
01540     }
01541     m = n >> 1;
01542     yi = a[m];
01543     xi = a[0] + a[n];
01544     a[0] -= a[n];
01545     t[0] = xi - yi;
01546     t[m] = xi + yi;
01547     if (n > 2) {
01548         mh = m >> 1;
01549         for (j = 1; j < mh; j++) {
01550             k = m - j;
01551             xr = a[j] - a[n - j];
01552             xi = a[j] + a[n - j];
01553             yr = a[k] - a[n - k];
01554             yi = a[k] + a[n - k];
01555             a[j] = xr;
01556             a[k] = yr;
01557             t[j] = xi - yi;
01558             t[k] = xi + yi;
01559         }
01560         t[mh] = a[mh] + a[n - mh];
01561         a[mh] -= a[n - mh];
01562         dctsub(m, a, nc, w + nw);
01563         if (m > 4) {
01564             bitrv2(m, ip + 2, a);
01565             cftfsub(m, a, w);
01566             rftfsub(m, a, nc, w + nw);
01567         } else if (m == 4) {
01568             cftfsub(m, a, w);
01569         }
01570         a[n - 1] = a[0] - a[1];
01571         a[1] = a[0] + a[1];
01572         for (j = m - 2; j >= 2; j -= 2) {
01573             a[2 * j + 1] = a[j] + a[j + 1];
01574             a[2 * j - 1] = a[j] - a[j + 1];
01575         }
01576         l = 2;
01577         m = mh;
01578         while (m >= 2) {
01579             dctsub(m, t, nc, w + nw);
01580             if (m > 4) {
01581                 bitrv2(m, ip + 2, t);
01582                 cftfsub(m, t, w);
01583                 rftfsub(m, t, nc, w + nw);
01584             } else if (m == 4) {
01585                 cftfsub(m, t, w);
01586             }
01587             a[n - l] = t[0] - t[1];
01588             a[l] = t[0] + t[1];
01589             k = 0;
01590             for (j = 2; j < m; j += 2) {
01591                 k += l << 2;
01592                 a[k - l] = t[j] - t[j + 1];
01593                 a[k + l] = t[j] + t[j + 1];
01594             }
01595             l <<= 1;
01596             mh = m >> 1;
01597             for (j = 0; j < mh; j++) {
01598                 k = m - j;
01599                 t[j] = t[m + k] - t[m + j];
01600                 t[k] = t[m + k] + t[m + j];
01601             }
01602             t[mh] = t[m + mh];
01603             m = mh;
01604         }
01605         a[l] = t[0];
01606         a[n] = t[2] - t[1];
01607         a[0] = t[2] + t[1];
01608     } else {
01609         a[1] = a[0];
01610         a[2] = t[0];
01611         a[0] = t[1];
01612     }
01613 }
01614 
01615 
01616 void clTransform4::dfst(long n, double *a, double *t, long *ip, double *w)
01617 {
01618     long j, k, l, m, mh, nw, nc;
01619     double xr, xi, yr, yi;
01620     
01621     nw = ip[0];
01622     if (n > (nw << 3)) {
01623         nw = n >> 3;
01624         makewt(nw, ip, w);
01625     }
01626     nc = ip[1];
01627     if (n > (nc << 1)) {
01628         nc = n >> 1;
01629         makect(nc, ip, w + nw);
01630     }
01631     if (n > 2) {
01632         m = n >> 1;
01633         mh = m >> 1;
01634         for (j = 1; j < mh; j++) {
01635             k = m - j;
01636             xr = a[j] + a[n - j];
01637             xi = a[j] - a[n - j];
01638             yr = a[k] + a[n - k];
01639             yi = a[k] - a[n - k];
01640             a[j] = xr;
01641             a[k] = yr;
01642             t[j] = xi + yi;
01643             t[k] = xi - yi;
01644         }
01645         t[0] = a[mh] - a[n - mh];
01646         a[mh] += a[n - mh];
01647         a[0] = a[m];
01648         dstsub(m, a, nc, w + nw);
01649         if (m > 4) {
01650             bitrv2(m, ip + 2, a);
01651             cftfsub(m, a, w);
01652             rftfsub(m, a, nc, w + nw);
01653         } else if (m == 4) {
01654             cftfsub(m, a, w);
01655         }
01656         a[n - 1] = a[1] - a[0];
01657         a[1] = a[0] + a[1];
01658         for (j = m - 2; j >= 2; j -= 2) {
01659             a[2 * j + 1] = a[j] - a[j + 1];
01660             a[2 * j - 1] = -a[j] - a[j + 1];
01661         }
01662         l = 2;
01663         m = mh;
01664         while (m >= 2) {
01665             dstsub(m, t, nc, w + nw);
01666             if (m > 4) {
01667                 bitrv2(m, ip + 2, t);
01668                 cftfsub(m, t, w);
01669                 rftfsub(m, t, nc, w + nw);
01670             } else if (m == 4) {
01671                 cftfsub(m, t, w);
01672             }
01673             a[n - l] = t[1] - t[0];
01674             a[l] = t[0] + t[1];
01675             k = 0;
01676             for (j = 2; j < m; j += 2) {
01677                 k += l << 2;
01678                 a[k - l] = -t[j] - t[j + 1];
01679                 a[k + l] = t[j] - t[j + 1];
01680             }
01681             l <<= 1;
01682             mh = m >> 1;
01683             for (j = 1; j < mh; j++) {
01684                 k = m - j;
01685                 t[j] = t[m + k] + t[m + j];
01686                 t[k] = t[m + k] - t[m + j];
01687             }
01688             t[0] = t[m + mh];
01689             m = mh;
01690         }
01691         a[l] = t[0];
01692     }
01693     a[0] = 0;
01694 }
01695 
01696 
01697 /* -------- initializing routines -------- */
01698 
01699 
01700 void clTransform4::makewt(long nw, long *ip, double *w)
01701 {
01702     long j, nwh;
01703     double delta, x, y;
01704     
01705     ip[0] = nw;
01706     ip[1] = 1;
01707     if (nw > 2) {
01708         nwh = nw >> 1;
01709 #       ifndef TRANSFORM_EXT_PREC
01710         delta = atan(1.0) / nwh;
01711 #       else
01712         delta = (double) (atanl(1.0l) / nwh);
01713 #       endif
01714         w[0] = 1;
01715         w[1] = 0;
01716 #       ifndef TRANSFORM_EXT_PREC
01717         w[nwh] = cos(delta * nwh);
01718 #       else
01719         w[nwh] = (double) cosl(delta * nwh);
01720 #       endif
01721         w[nwh + 1] = w[nwh];
01722         if (nwh > 2) {
01723             for (j = 2; j < nwh; j += 2) {
01724 #               ifndef TRANSFORM_EXT_PREC
01725                 x = cos(delta * j);
01726                 y = sin(delta * j);
01727 #               else
01728                 x = (double) cosl(delta * j);
01729                 y = (double) sinl(delta * j);
01730 #               endif
01731                 w[j] = x;
01732                 w[j + 1] = y;
01733                 w[nw - j] = y;
01734                 w[nw - j + 1] = x;
01735             }
01736             bitrv2(nw, ip + 2, w);
01737         }
01738     }
01739 }
01740 
01741 
01742 void clTransform4::makect(long nc, long *ip, double *c)
01743 {
01744     long j, nch;
01745     double delta;
01746     
01747     ip[1] = nc;
01748     if (nc > 1) {
01749         nch = nc >> 1;
01750 #       ifndef TRANSFORM_EXT_PREC
01751         delta = atan(1.0) / nch;
01752         c[0] = cos(delta * nch);
01753 #       else
01754         delta = (double) (atanl(1.0l) / nch);
01755         c[0] = (double) cosl(delta * nch);
01756 #       endif
01757         c[nch] = 0.5 * c[0];
01758         for (j = 1; j < nch; j++) {
01759 #           ifndef TRANSFORM_EXT_PREC
01760             c[j] = 0.5 * cos(delta * j);
01761             c[nc - j] = 0.5 * sin(delta * j);
01762 #           else
01763             c[j] = (double) (0.5l * cosl(delta * j));
01764             c[nc - j] = (double) (0.5l * sin(delta * j));
01765 #           endif
01766         }
01767     }
01768 }
01769 
01770 
01771 /* -------- child routines -------- */
01772 
01773 
01774 T4_INLINE void clTransform4::bitrv2(long n, long *ip, double *a)
01775 {
01776     long j, j1, k, k1, l, m, m2;
01777     double xr, xi, yr, yi;
01778     
01779     ip[0] = 0;
01780     l = n;
01781     m = 1;
01782     while ((m << 3) < l) {
01783         l >>= 1;
01784         for (j = 0; j < m; j++) {
01785             ip[m + j] = ip[j] + l;
01786         }
01787         m <<= 1;
01788     }
01789     m2 = 2 * m;
01790     if ((m << 3) == l) {
01791         for (k = 0; k < m; k++) {
01792             for (j = 0; j < k; j++) {
01793                 j1 = 2 * j + ip[k];
01794                 k1 = 2 * k + ip[j];
01795                 xr = a[j1];
01796                 xi = a[j1 + 1];
01797                 yr = a[k1];
01798                 yi = a[k1 + 1];
01799                 a[j1] = yr;
01800                 a[j1 + 1] = yi;
01801                 a[k1] = xr;
01802                 a[k1 + 1] = xi;
01803                 j1 += m2;
01804                 k1 += 2 * m2;
01805                 xr = a[j1];
01806                 xi = a[j1 + 1];
01807                 yr = a[k1];
01808                 yi = a[k1 + 1];
01809                 a[j1] = yr;
01810                 a[j1 + 1] = yi;
01811                 a[k1] = xr;
01812                 a[k1 + 1] = xi;
01813                 j1 += m2;
01814                 k1 -= m2;
01815                 xr = a[j1];
01816                 xi = a[j1 + 1];
01817                 yr = a[k1];
01818                 yi = a[k1 + 1];
01819                 a[j1] = yr;
01820                 a[j1 + 1] = yi;
01821                 a[k1] = xr;
01822                 a[k1 + 1] = xi;
01823                 j1 += m2;
01824                 k1 += 2 * m2;
01825                 xr = a[j1];
01826                 xi = a[j1 + 1];
01827                 yr = a[k1];
01828                 yi = a[k1 + 1];
01829                 a[j1] = yr;
01830                 a[j1 + 1] = yi;
01831                 a[k1] = xr;
01832                 a[k1 + 1] = xi;
01833             }
01834             j1 = 2 * k + m2 + ip[k];
01835             k1 = j1 + m2;
01836             xr = a[j1];
01837             xi = a[j1 + 1];
01838             yr = a[k1];
01839             yi = a[k1 + 1];
01840             a[j1] = yr;
01841             a[j1 + 1] = yi;
01842             a[k1] = xr;
01843             a[k1 + 1] = xi;
01844         }
01845     } else {
01846         for (k = 1; k < m; k++) {
01847             for (j = 0; j < k; j++) {
01848                 j1 = 2 * j + ip[k];
01849                 k1 = 2 * k + ip[j];
01850                 xr = a[j1];
01851                 xi = a[j1 + 1];
01852                 yr = a[k1];
01853                 yi = a[k1 + 1];
01854                 a[j1] = yr;
01855                 a[j1 + 1] = yi;
01856                 a[k1] = xr;
01857                 a[k1 + 1] = xi;
01858                 j1 += m2;
01859                 k1 += m2;
01860                 xr = a[j1];
01861                 xi = a[j1 + 1];
01862                 yr = a[k1];
01863                 yi = a[k1 + 1];
01864                 a[j1] = yr;
01865                 a[j1 + 1] = yi;
01866                 a[k1] = xr;
01867                 a[k1 + 1] = xi;
01868             }
01869         }
01870     }
01871 }
01872 
01873 
01874 T4_INLINE void clTransform4::bitrv2conj(long n, long *ip, double *a)
01875 {
01876     long j, j1, k, k1, l, m, m2;
01877     double xr, xi, yr, yi;
01878     
01879     ip[0] = 0;
01880     l = n;
01881     m = 1;
01882     while ((m << 3) < l) {
01883         l >>= 1;
01884         for (j = 0; j < m; j++) {
01885             ip[m + j] = ip[j] + l;
01886         }
01887         m <<= 1;
01888     }
01889     m2 = 2 * m;
01890     if ((m << 3) == l) {
01891         for (k = 0; k < m; k++) {
01892             for (j = 0; j < k; j++) {
01893                 j1 = 2 * j + ip[k];
01894                 k1 = 2 * k + ip[j];
01895                 xr = a[j1];
01896                 xi = -a[j1 + 1];
01897                 yr = a[k1];
01898                 yi = -a[k1 + 1];
01899                 a[j1] = yr;
01900                 a[j1 + 1] = yi;
01901                 a[k1] = xr;
01902                 a[k1 + 1] = xi;
01903                 j1 += m2;
01904                 k1 += 2 * m2;
01905                 xr = a[j1];
01906                 xi = -a[j1 + 1];
01907                 yr = a[k1];
01908                 yi = -a[k1 + 1];
01909                 a[j1] = yr;
01910                 a[j1 + 1] = yi;
01911                 a[k1] = xr;
01912                 a[k1 + 1] = xi;
01913                 j1 += m2;
01914                 k1 -= m2;
01915                 xr = a[j1];
01916                 xi = -a[j1 + 1];
01917                 yr = a[k1];
01918                 yi = -a[k1 + 1];
01919                 a[j1] = yr;
01920                 a[j1 + 1] = yi;
01921                 a[k1] = xr;
01922                 a[k1 + 1] = xi;
01923                 j1 += m2;
01924                 k1 += 2 * m2;
01925                 xr = a[j1];
01926                 xi = -a[j1 + 1];
01927                 yr = a[k1];
01928                 yi = -a[k1 + 1];
01929                 a[j1] = yr;
01930                 a[j1 + 1] = yi;
01931                 a[k1] = xr;
01932                 a[k1 + 1] = xi;
01933             }
01934             k1 = 2 * k + ip[k];
01935             a[k1 + 1] = -a[k1 + 1];
01936             j1 = k1 + m2;
01937             k1 = j1 + m2;
01938             xr = a[j1];
01939             xi = -a[j1 + 1];
01940             yr = a[k1];
01941             yi = -a[k1 + 1];
01942             a[j1] = yr;
01943             a[j1 + 1] = yi;
01944             a[k1] = xr;
01945             a[k1 + 1] = xi;
01946             k1 += m2;
01947             a[k1 + 1] = -a[k1 + 1];
01948         }
01949     } else {
01950         a[1] = -a[1];
01951         a[m2 + 1] = -a[m2 + 1];
01952         for (k = 1; k < m; k++) {
01953             for (j = 0; j < k; j++) {
01954                 j1 = 2 * j + ip[k];
01955                 k1 = 2 * k + ip[j];
01956                 xr = a[j1];
01957                 xi = -a[j1 + 1];
01958                 yr = a[k1];
01959                 yi = -a[k1 + 1];
01960                 a[j1] = yr;
01961                 a[j1 + 1] = yi;
01962                 a[k1] = xr;
01963                 a[k1 + 1] = xi;
01964                 j1 += m2;
01965                 k1 += m2;
01966                 xr = a[j1];
01967                 xi = -a[j1 + 1];
01968                 yr = a[k1];
01969                 yi = -a[k1 + 1];
01970                 a[j1] = yr;
01971                 a[j1 + 1] = yi;
01972                 a[k1] = xr;
01973                 a[k1 + 1] = xi;
01974             }
01975             k1 = 2 * k + ip[k];
01976             a[k1 + 1] = -a[k1 + 1];
01977             a[k1 + m2 + 1] = -a[k1 + m2 + 1];
01978         }
01979     }
01980 }
01981 
01982 
01983 T4_INLINE void clTransform4::cftfsub(long n, double *a, double *w)
01984 {
01985     long j, j1, j2, j3, l;
01986     double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
01987     
01988     l = 2;
01989     if (n > 8) {
01990         cft1st(n, a, w);
01991         l = 8;
01992         while ((l << 2) < n) {
01993             cftmdl(n, l, a, w);
01994             l <<= 2;
01995         }
01996     }
01997     if ((l << 2) == n) {
01998         for (j = 0; j < l; j += 2) {
01999             j1 = j + l;
02000             j2 = j1 + l;
02001             j3 = j2 + l;
02002             x0r = a[j] + a[j1];
02003             x0i = a[j + 1] + a[j1 + 1];
02004             x1r = a[j] - a[j1];
02005             x1i = a[j + 1] - a[j1 + 1];
02006             x2r = a[j2] + a[j3];
02007             x2i = a[j2 + 1] + a[j3 + 1];
02008             x3r = a[j2] - a[j3];
02009             x3i = a[j2 + 1] - a[j3 + 1];
02010             a[j] = x0r + x2r;
02011             a[j + 1] = x0i + x2i;
02012             a[j2] = x0r - x2r;
02013             a[j2 + 1] = x0i - x2i;
02014             a[j1] = x1r - x3i;
02015             a[j1 + 1] = x1i + x3r;
02016             a[j3] = x1r + x3i;
02017             a[j3 + 1] = x1i - x3r;
02018         }
02019     } else {
02020         for (j = 0; j < l; j += 2) {
02021             j1 = j + l;
02022             x0r = a[j] - a[j1];
02023             x0i = a[j + 1] - a[j1 + 1];
02024             a[j] += a[j1];
02025             a[j + 1] += a[j1 + 1];
02026             a[j1] = x0r;
02027             a[j1 + 1] = x0i;
02028         }
02029     }
02030 }
02031 
02032 
02033 T4_INLINE void clTransform4::cftbsub(long n, double *a, double *w)
02034 {
02035     long j, j1, j2, j3, l;
02036     double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
02037     
02038     l = 2;
02039     if (n > 8) {
02040         cft1st(n, a, w);
02041         l = 8;
02042         while ((l << 2) < n) {
02043             cftmdl(n, l, a, w);
02044             l <<= 2;
02045         }
02046     }
02047     if ((l << 2) == n) {
02048         for (j = 0; j < l; j += 2) {
02049             j1 = j + l;
02050             j2 = j1 + l;
02051             j3 = j2 + l;
02052             x0r = a[j] + a[j1];
02053             x0i = -a[j + 1] - a[j1 + 1];
02054             x1r = a[j] - a[j1];
02055             x1i = -a[j + 1] + a[j1 + 1];
02056             x2r = a[j2] + a[j3];
02057             x2i = a[j2 + 1] + a[j3 + 1];
02058             x3r = a[j2] - a[j3];
02059             x3i = a[j2 + 1] - a[j3 + 1];
02060             a[j] = x0r + x2r;
02061             a[j + 1] = x0i - x2i;
02062             a[j2] = x0r - x2r;
02063             a[j2 + 1] = x0i + x2i;
02064             a[j1] = x1r - x3i;
02065             a[j1 + 1] = x1i - x3r;
02066             a[j3] = x1r + x3i;
02067             a[j3 + 1] = x1i + x3r;
02068         }
02069     } else {
02070         for (j = 0; j < l; j += 2) {
02071             j1 = j + l;
02072             x0r = a[j] - a[j1];
02073             x0i = -a[j + 1] + a[j1 + 1];
02074             a[j] += a[j1];
02075             a[j + 1] = -a[j + 1] - a[j1 + 1];
02076             a[j1] = x0r;
02077             a[j1 + 1] = x0i;
02078         }
02079     }
02080 }
02081 
02082 
02083 T4_INLINE void clTransform4::cft1st(long n, double *a, double *w)
02084 {
02085     long j, k1, k2;
02086     double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
02087     double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
02088     
02089     x0r = a[0] + a[2];
02090     x0i = a[1] + a[3];
02091     x1r = a[0] - a[2];
02092     x1i = a[1] - a[3];
02093     x2r = a[4] + a[6];
02094     x2i = a[5] + a[7];
02095     x3r = a[4] - a[6];
02096     x3i = a[5] - a[7];
02097     a[0] = x0r + x2r;
02098     a[1] = x0i + x2i;
02099     a[4] = x0r - x2r;
02100     a[5] = x0i - x2i;
02101     a[2] = x1r - x3i;
02102     a[3] = x1i + x3r;
02103     a[6] = x1r + x3i;
02104     a[7] = x1i - x3r;
02105     wk1r = w[2];
02106     x0r = a[8] + a[10];
02107     x0i = a[9] + a[11];
02108     x1r = a[8] - a[10];
02109     x1i = a[9] - a[11];
02110     x2r = a[12] + a[14];
02111     x2i = a[13] + a[15];
02112     x3r = a[12] - a[14];
02113     x3i = a[13] - a[15];
02114     a[8] = x0r + x2r;
02115     a[9] = x0i + x2i;
02116     a[12] = x2i - x0i;
02117     a[13] = x0r - x2r;
02118     x0r = x1r - x3i;
02119     x0i = x1i + x3r;
02120     a[10] = wk1r * (x0r - x0i);
02121     a[11] = wk1r * (x0r + x0i);
02122     x0r = x3i + x1r;
02123     x0i = x3r - x1i;
02124     a[14] = wk1r * (x0i - x0r);
02125     a[15] = wk1r * (x0i + x0r);
02126     k1 = 0;
02127     for (j = 16; j < n; j += 16) {
02128         k1 += 2;
02129         k2 = 2 * k1;
02130         wk2r = w[k1];
02131         wk2i = w[k1 + 1];
02132         wk1r = w[k2];
02133         wk1i = w[k2 + 1];
02134         wk3r = wk1r - 2 * wk2i * wk1i;
02135         wk3i = 2 * wk2i * wk1r - wk1i;
02136         x0r = a[j] + a[j + 2];
02137         x0i = a[j + 1] + a[j + 3];
02138         x1r = a[j] - a[j + 2];
02139         x1i = a[j + 1] - a[j + 3];
02140         x2r = a[j + 4] + a[j + 6];
02141         x2i = a[j + 5] + a[j + 7];
02142         x3r = a[j + 4] - a[j + 6];
02143         x3i = a[j + 5] - a[j + 7];
02144         a[j] = x0r + x2r;
02145         a[j + 1] = x0i + x2i;
02146         x0r -= x2r;
02147         x0i -= x2i;
02148         a[j + 4] = wk2r * x0r - wk2i * x0i;
02149         a[j + 5] = wk2r * x0i + wk2i * x0r;
02150         x0r = x1r - x3i;
02151         x0i = x1i + x3r;
02152         a[j + 2] = wk1r * x0r - wk1i * x0i;
02153         a[j + 3] = wk1r * x0i + wk1i * x0r;
02154         x0r = x1r + x3i;
02155         x0i = x1i - x3r;
02156         a[j + 6] = wk3r * x0r - wk3i * x0i;
02157         a[j + 7] = wk3r * x0i + wk3i * x0r;
02158         wk1r = w[k2 + 2];
02159         wk1i = w[k2 + 3];
02160         wk3r = wk1r - 2 * wk2r * wk1i;
02161         wk3i = 2 * wk2r * wk1r - wk1i;
02162         x0r = a[j + 8] + a[j + 10];
02163         x0i = a[j + 9] + a[j + 11];
02164         x1r = a[j + 8] - a[j + 10];
02165         x1i = a[j + 9] - a[j + 11];
02166         x2r = a[j + 12] + a[j + 14];
02167         x2i = a[j + 13] + a[j + 15];
02168         x3r = a[j + 12] - a[j + 14];
02169         x3i = a[j + 13] - a[j + 15];
02170         a[j + 8] = x0r + x2r;
02171         a[j + 9] = x0i + x2i;
02172         x0r -= x2r;
02173         x0i -= x2i;
02174         a[j + 12] = -wk2i * x0r - wk2r * x0i;
02175         a[j + 13] = -wk2i * x0i + wk2r * x0r;
02176         x0r = x1r - x3i;
02177         x0i = x1i + x3r;
02178         a[j + 10] = wk1r * x0r - wk1i * x0i;
02179         a[j + 11] = wk1r * x0i + wk1i * x0r;
02180         x0r = x1r + x3i;
02181         x0i = x1i - x3r;
02182         a[j + 14] = wk3r * x0r - wk3i * x0i;
02183         a[j + 15] = wk3r * x0i + wk3i * x0r;
02184     }
02185 }
02186 
02187 
02188 T4_INLINE void clTransform4::cftmdl(long n, long l, double *a, double *w)
02189 {
02190     long j, j1, j2, j3, k, k1, k2, m, m2;
02191     double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
02192     double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
02193     
02194     m = l << 2;
02195     for (j = 0; j < l; j += 2) {
02196         j1 = j + l;
02197         j2 = j1 + l;
02198         j3 = j2 + l;
02199         x0r = a[j] + a[j1];
02200         x0i = a[j + 1] + a[j1 + 1];
02201         x1r = a[j] - a[j1];
02202         x1i = a[j + 1] - a[j1 + 1];
02203         x2r = a[j2] + a[j3];
02204         x2i = a[j2 + 1] + a[j3 + 1];
02205         x3r = a[j2] - a[j3];
02206         x3i = a[j2 + 1] - a[j3 + 1];
02207         a[j] = x0r + x2r;
02208         a[j + 1] = x0i + x2i;
02209         a[j2] = x0r - x2r;
02210         a[j2 + 1] = x0i - x2i;
02211         a[j1] = x1r - x3i;
02212         a[j1 + 1] = x1i + x3r;
02213         a[j3] = x1r + x3i;
02214         a[j3 + 1] = x1i - x3r;
02215     }
02216     wk1r = w[2];
02217     for (j = m; j < l + m; j += 2) {
02218         j1 = j + l;
02219         j2 = j1 + l;
02220         j3 = j2 + l;
02221         x0r = a[j] + a[j1];
02222         x0i = a[j + 1] + a[j1 + 1];
02223         x1r = a[j] - a[j1];
02224         x1i = a[j + 1] - a[j1 + 1];
02225         x2r = a[j2] + a[j3];
02226         x2i = a[j2 + 1] + a[j3 + 1];
02227         x3r = a[j2] - a[j3];
02228         x3i = a[j2 + 1] - a[j3 + 1];
02229         a[j] = x0r + x2r;
02230         a[j + 1] = x0i + x2i;
02231         a[j2] = x2i - x0i;
02232         a[j2 + 1] = x0r - x2r;
02233         x0r = x1r - x3i;
02234         x0i = x1i + x3r;
02235         a[j1] = wk1r * (x0r - x0i);
02236         a[j1 + 1] = wk1r * (x0r + x0i);
02237         x0r = x3i + x1r;
02238         x0i = x3r - x1i;
02239         a[j3] = wk1r * (x0i - x0r);
02240         a[j3 + 1] = wk1r * (x0i + x0r);
02241     }
02242     k1 = 0;
02243     m2 = 2 * m;
02244     for (k = m2; k < n; k += m2) {
02245         k1 += 2;
02246         k2 = 2 * k1;
02247         wk2r = w[k1];
02248         wk2i = w[k1 + 1];
02249         wk1r = w[k2];
02250         wk1i = w[k2 + 1];
02251         wk3r = wk1r - 2 * wk2i * wk1i;
02252         wk3i = 2 * wk2i * wk1r - wk1i;
02253         for (j = k; j < l + k; j += 2) {
02254             j1 = j + l;
02255             j2 = j1 + l;
02256             j3 = j2 + l;
02257             x0r = a[j] + a[j1];
02258             x0i = a[j + 1] + a[j1 + 1];
02259             x1r = a[j] - a[j1];
02260             x1i = a[j + 1] - a[j1 + 1];
02261             x2r = a[j2] + a[j3];
02262             x2i = a[j2 + 1] + a[j3 + 1];
02263             x3r = a[j2] - a[j3];
02264             x3i = a[j2 + 1] - a[j3 + 1];
02265             a[j] = x0r + x2r;
02266             a[j + 1] = x0i + x2i;
02267             x0r -= x2r;
02268             x0i -= x2i;
02269             a[j2] = wk2r * x0r - wk2i * x0i;
02270             a[j2 + 1] = wk2r * x0i + wk2i * x0r;
02271             x0r = x1r - x3i;
02272             x0i = x1i + x3r;
02273             a[j1] = wk1r * x0r - wk1i * x0i;
02274             a[j1 + 1] = wk1r * x0i + wk1i * x0r;
02275             x0r = x1r + x3i;
02276             x0i = x1i - x3r;
02277             a[j3] = wk3r * x0r - wk3i * x0i;
02278             a[j3 + 1] = wk3r * x0i + wk3i * x0r;
02279         }
02280         wk1r = w[k2 + 2];
02281         wk1i = w[k2 + 3];
02282         wk3r = wk1r - 2 * wk2r * wk1i;
02283         wk3i = 2 * wk2r * wk1r - wk1i;
02284         for (j = k + m; j < l + (k + m); j += 2) {
02285             j1 = j + l;
02286             j2 = j1 + l;
02287             j3 = j2 + l;
02288             x0r = a[j] + a[j1];
02289             x0i = a[j + 1] + a[j1 + 1];
02290             x1r = a[j] - a[j1];
02291             x1i = a[j + 1] - a[j1 + 1];
02292             x2r = a[j2] + a[j3];
02293             x2i = a[j2 + 1] + a[j3 + 1];
02294             x3r = a[j2] - a[j3];
02295             x3i = a[j2 + 1] - a[j3 + 1];
02296             a[j] = x0r + x2r;
02297             a[j + 1] = x0i + x2i;
02298             x0r -= x2r;
02299             x0i -= x2i;
02300             a[j2] = -wk2i * x0r - wk2r * x0i;
02301             a[j2 + 1] = -wk2i * x0i + wk2r * x0r;
02302             x0r = x1r - x3i;
02303             x0i = x1i + x3r;
02304             a[j1] = wk1r * x0r - wk1i * x0i;
02305             a[j1 + 1] = wk1r * x0i + wk1i * x0r;
02306             x0r = x1r + x3i;
02307             x0i = x1i - x3r;
02308             a[j3] = wk3r * x0r - wk3i * x0i;
02309             a[j3 + 1] = wk3r * x0i + wk3i * x0r;
02310         }
02311     }
02312 }
02313 
02314 
02315 T4_INLINE void clTransform4::rftfsub(long n, double *a, long nc, double *c)
02316 {
02317     long j, k, kk, ks, m;
02318     double wkr, wki, xr, xi, yr, yi;
02319     
02320     m = n >> 1;
02321     ks = 2 * nc / m;
02322     kk = 0;
02323     for (j = 2; j < m; j += 2) {
02324         k = n - j;
02325         kk += ks;
02326         wkr = 0.5 - c[nc - kk];
02327         wki = c[kk];
02328         xr = a[j] - a[k];
02329         xi = a[j + 1] + a[k + 1];
02330         yr = wkr * xr - wki * xi;
02331         yi = wkr * xi + wki * xr;
02332         a[j] -= yr;
02333         a[j + 1] -= yi;
02334         a[k] += yr;
02335         a[k + 1] -= yi;
02336     }
02337 }
02338 
02339 
02340 T4_INLINE void clTransform4::rftbsub(long n, double *a, long nc, double *c)
02341 {
02342     long j, k, kk, ks, m;
02343     double wkr, wki, xr, xi, yr, yi;
02344     
02345     a[1] = -a[1];
02346     m = n >> 1;
02347     ks = 2 * nc / m;
02348     kk = 0;
02349     for (j = 2; j < m; j += 2) {
02350         k = n - j;
02351         kk += ks;
02352         wkr = 0.5 - c[nc - kk];
02353         wki = c[kk];
02354         xr = a[j] - a[k];
02355         xi = a[j + 1] + a[k + 1];
02356         yr = wkr * xr + wki * xi;
02357         yi = wkr * xi - wki * xr;
02358         a[j] -= yr;
02359         a[j + 1] = yi - a[j + 1];
02360         a[k] += yr;
02361         a[k + 1] = yi - a[k + 1];
02362     }
02363     a[m + 1] = -a[m + 1];
02364 }
02365 
02366 
02367 T4_INLINE void clTransform4::dctsub(long n, double *a, long nc, double *c)
02368 {
02369     long j, k, kk, ks, m;
02370     double wkr, wki, xr;
02371     
02372     m = n >> 1;
02373     ks = nc / n;
02374     kk = 0;
02375     for (j = 1; j < m; j++) {
02376         k = n - j;
02377         kk += ks;
02378         wkr = c[kk] - c[nc - kk];
02379         wki = c[kk] + c[nc - kk];
02380         xr = wki * a[j] - wkr * a[k];
02381         a[j] = wkr * a[j] + wki * a[k];
02382         a[k] = xr;
02383     }
02384     a[m] *= c[0];
02385 }
02386 
02387 
02388 T4_INLINE void clTransform4::dstsub(long n, double *a, long nc, double *c)
02389 {
02390     long j, k, kk, ks, m;
02391     double wkr, wki, xr;
02392     
02393     m = n >> 1;
02394     ks = nc / n;
02395     kk = 0;
02396     for (j = 1; j < m; j++) {
02397         k = n - j;
02398         kk += ks;
02399         wkr = c[kk] - c[nc - kk];
02400         wki = c[kk] + c[nc - kk];
02401         xr = wki * a[k] - wkr * a[j];
02402         a[k] = wkr * a[k] + wki * a[j];
02403         a[j] = xr;
02404     }
02405     a[m] *= c[0];
02406 }
02407 

Generated on Tue Mar 2 19:46:45 2004 for libDSP by doxygen 1.3.6