examples/SFExamples/oggvorbiscodec/src/libvorbis/lib/mdct.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: normalized modified discrete cosine transform
00014            power of two length transform only [64 <= n ]
00015  last mod: $Id: mdct.c 7187 2004-07-20 07:24:27Z xiphmont $
00016 
00017  Original algorithm adapted long ago from _The use of multirate filter
00018  banks for coding of high quality digital audio_, by T. Sporer,
00019  K. Brandenburg and B. Edler, collection of the European Signal
00020  Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
00021  211-214
00022 
00023  The below code implements an algorithm that no longer looks much like
00024  that presented in the paper, but the basic structure remains if you
00025  dig deep enough to see it.
00026 
00027  This module DOES NOT INCLUDE code to generate/apply the window
00028  function.  Everybody has their own weird favorite including me... I
00029  happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
00030  vehemently disagree.
00031 
00032  ********************************************************************/
00033 
00034 /* this can also be run as an integer transform by uncommenting a
00035    define in mdct.h; the integerization is a first pass and although
00036    it's likely stable for Vorbis, the dynamic range is constrained and
00037    roundoff isn't done (so it's noisy).  Consider it functional, but
00038    only a starting point.  There's no point on a machine with an FPU */
00039 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <math.h>
00044 #include "vorbis/codec.h"
00045 #include "mdct.h"
00046 #include "os.h"
00047 #include "misc.h"
00048 
00049 /* build lookups for trig functions; also pre-figure scaling and
00050    some window function algebra. */
00051 
00052 void mdct_init(mdct_lookup *lookup,int n){
00053   int   *bitrev=(int*)_ogg_malloc(sizeof(*bitrev)*(n/4));
00054   DATA_TYPE *T=(float*)_ogg_malloc(sizeof(*T)*(n+n/4));
00055   
00056   int i;
00057   int n2=n>>1;
00058   int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
00059   lookup->n=n;
00060   lookup->trig=T;
00061   lookup->bitrev=bitrev;
00062 
00063 /* trig lookups... */
00064 
00065   for(i=0;i<n/4;i++){
00066     T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
00067     T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
00068     T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
00069     T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
00070   }
00071   for(i=0;i<n/8;i++){
00072     T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
00073     T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
00074   }
00075 
00076   /* bitreverse lookup... */
00077 
00078   {
00079     int mask=(1<<(log2n-1))-1,i,j;
00080     int msb=1<<(log2n-2);
00081     for(i=0;i<n/8;i++){
00082       int acc=0;
00083       for(j=0;msb>>j;j++)
00084         if((msb>>j)&i)acc|=1<<j;
00085       bitrev[i*2]=((~acc)&mask)-1;
00086       bitrev[i*2+1]=acc;
00087 
00088     }
00089   }
00090   lookup->scale=FLOAT_CONV(4.f/n);
00091 }
00092 
00093 /* 8 point butterfly (in place, 4 register) */
00094 STIN void mdct_butterfly_8(DATA_TYPE *x){
00095   REG_TYPE r0   = x[6] + x[2];
00096   REG_TYPE r1   = x[6] - x[2];
00097   REG_TYPE r2   = x[4] + x[0];
00098   REG_TYPE r3   = x[4] - x[0];
00099 
00100            x[6] = r0   + r2;
00101            x[4] = r0   - r2;
00102            
00103            r0   = x[5] - x[1];
00104            r2   = x[7] - x[3];
00105            x[0] = r1   + r0;
00106            x[2] = r1   - r0;
00107            
00108            r0   = x[5] + x[1];
00109            r1   = x[7] + x[3];
00110            x[3] = r2   + r3;
00111            x[1] = r2   - r3;
00112            x[7] = r1   + r0;
00113            x[5] = r1   - r0;
00114            
00115 }
00116 
00117 /* 16 point butterfly (in place, 4 register) */
00118 STIN void mdct_butterfly_16(DATA_TYPE *x){
00119   REG_TYPE r0     = x[1]  - x[9];
00120   REG_TYPE r1     = x[0]  - x[8];
00121 
00122            x[8]  += x[0];
00123            x[9]  += x[1];
00124            x[0]   = MULT_NORM((r0   + r1) * cPI2_8);
00125            x[1]   = MULT_NORM((r0   - r1) * cPI2_8);
00126 
00127            r0     = x[3]  - x[11];
00128            r1     = x[10] - x[2];
00129            x[10] += x[2];
00130            x[11] += x[3];
00131            x[2]   = r0;
00132            x[3]   = r1;
00133 
00134            r0     = x[12] - x[4];
00135            r1     = x[13] - x[5];
00136            x[12] += x[4];
00137            x[13] += x[5];
00138            x[4]   = MULT_NORM((r0   - r1) * cPI2_8);
00139            x[5]   = MULT_NORM((r0   + r1) * cPI2_8);
00140 
00141            r0     = x[14] - x[6];
00142            r1     = x[15] - x[7];
00143            x[14] += x[6];
00144            x[15] += x[7];
00145            x[6]  = r0;
00146            x[7]  = r1;
00147 
00148            mdct_butterfly_8(x);
00149            mdct_butterfly_8(x+8);
00150 }
00151 
00152 /* 32 point butterfly (in place, 4 register) */
00153 STIN void mdct_butterfly_32(DATA_TYPE *x){
00154   REG_TYPE r0     = x[30] - x[14];
00155   REG_TYPE r1     = x[31] - x[15];
00156 
00157            x[30] +=         x[14];           
00158            x[31] +=         x[15];
00159            x[14]  =         r0;              
00160            x[15]  =         r1;
00161 
00162            r0     = x[28] - x[12];   
00163            r1     = x[29] - x[13];
00164            x[28] +=         x[12];           
00165            x[29] +=         x[13];
00166            x[12]  = MULT_NORM( r0 * cPI1_8  -  r1 * cPI3_8 );
00167            x[13]  = MULT_NORM( r0 * cPI3_8  +  r1 * cPI1_8 );
00168 
00169            r0     = x[26] - x[10];
00170            r1     = x[27] - x[11];
00171            x[26] +=         x[10];
00172            x[27] +=         x[11];
00173            x[10]  = MULT_NORM(( r0  - r1 ) * cPI2_8);
00174            x[11]  = MULT_NORM(( r0  + r1 ) * cPI2_8);
00175 
00176            r0     = x[24] - x[8];
00177            r1     = x[25] - x[9];
00178            x[24] += x[8];
00179            x[25] += x[9];
00180            x[8]   = MULT_NORM( r0 * cPI3_8  -  r1 * cPI1_8 );
00181            x[9]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
00182 
00183            r0     = x[22] - x[6];
00184            r1     = x[7]  - x[23];
00185            x[22] += x[6];
00186            x[23] += x[7];
00187            x[6]   = r1;
00188            x[7]   = r0;
00189 
00190            r0     = x[4]  - x[20];
00191            r1     = x[5]  - x[21];
00192            x[20] += x[4];
00193            x[21] += x[5];
00194            x[4]   = MULT_NORM( r1 * cPI1_8  +  r0 * cPI3_8 );
00195            x[5]   = MULT_NORM( r1 * cPI3_8  -  r0 * cPI1_8 );
00196 
00197            r0     = x[2]  - x[18];
00198            r1     = x[3]  - x[19];
00199            x[18] += x[2];
00200            x[19] += x[3];
00201            x[2]   = MULT_NORM(( r1  + r0 ) * cPI2_8);
00202            x[3]   = MULT_NORM(( r1  - r0 ) * cPI2_8);
00203 
00204            r0     = x[0]  - x[16];
00205            r1     = x[1]  - x[17];
00206            x[16] += x[0];
00207            x[17] += x[1];
00208            x[0]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
00209            x[1]   = MULT_NORM( r1 * cPI1_8  -  r0 * cPI3_8 );
00210 
00211            mdct_butterfly_16(x);
00212            mdct_butterfly_16(x+16);
00213 
00214 }
00215 
00216 /* N point first stage butterfly (in place, 2 register) */
00217 STIN void mdct_butterfly_first(DATA_TYPE *T,
00218                                         DATA_TYPE *x,
00219                                         int points){
00220   
00221   DATA_TYPE *x1        = x          + points      - 8;
00222   DATA_TYPE *x2        = x          + (points>>1) - 8;
00223   REG_TYPE   r0;
00224   REG_TYPE   r1;
00225 
00226   do{
00227     
00228                r0      = x1[6]      -  x2[6];
00229                r1      = x1[7]      -  x2[7];
00230                x1[6]  += x2[6];
00231                x1[7]  += x2[7];
00232                x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
00233                x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
00234                
00235                r0      = x1[4]      -  x2[4];
00236                r1      = x1[5]      -  x2[5];
00237                x1[4]  += x2[4];
00238                x1[5]  += x2[5];
00239                x2[4]   = MULT_NORM(r1 * T[5]  +  r0 * T[4]);
00240                x2[5]   = MULT_NORM(r1 * T[4]  -  r0 * T[5]);
00241                
00242                r0      = x1[2]      -  x2[2];
00243                r1      = x1[3]      -  x2[3];
00244                x1[2]  += x2[2];
00245                x1[3]  += x2[3];
00246                x2[2]   = MULT_NORM(r1 * T[9]  +  r0 * T[8]);
00247                x2[3]   = MULT_NORM(r1 * T[8]  -  r0 * T[9]);
00248                
00249                r0      = x1[0]      -  x2[0];
00250                r1      = x1[1]      -  x2[1];
00251                x1[0]  += x2[0];
00252                x1[1]  += x2[1];
00253                x2[0]   = MULT_NORM(r1 * T[13] +  r0 * T[12]);
00254                x2[1]   = MULT_NORM(r1 * T[12] -  r0 * T[13]);
00255                
00256     x1-=8;
00257     x2-=8;
00258     T+=16;
00259 
00260   }while(x2>=x);
00261 }
00262 
00263 /* N/stage point generic N stage butterfly (in place, 2 register) */
00264 STIN void mdct_butterfly_generic(DATA_TYPE *T,
00265                                           DATA_TYPE *x,
00266                                           int points,
00267                                           int trigint){
00268   
00269   DATA_TYPE *x1        = x          + points      - 8;
00270   DATA_TYPE *x2        = x          + (points>>1) - 8;
00271   REG_TYPE   r0;
00272   REG_TYPE   r1;
00273 
00274   do{
00275     
00276                r0      = x1[6]      -  x2[6];
00277                r1      = x1[7]      -  x2[7];
00278                x1[6]  += x2[6];
00279                x1[7]  += x2[7];
00280                x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
00281                x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
00282                
00283                T+=trigint;
00284                
00285                r0      = x1[4]      -  x2[4];
00286                r1      = x1[5]      -  x2[5];
00287                x1[4]  += x2[4];
00288                x1[5]  += x2[5];
00289                x2[4]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
00290                x2[5]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
00291                
00292                T+=trigint;
00293                
00294                r0      = x1[2]      -  x2[2];
00295                r1      = x1[3]      -  x2[3];
00296                x1[2]  += x2[2];
00297                x1[3]  += x2[3];
00298                x2[2]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
00299                x2[3]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
00300                
00301                T+=trigint;
00302                
00303                r0      = x1[0]      -  x2[0];
00304                r1      = x1[1]      -  x2[1];
00305                x1[0]  += x2[0];
00306                x1[1]  += x2[1];
00307                x2[0]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
00308                x2[1]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
00309 
00310                T+=trigint;
00311     x1-=8;
00312     x2-=8;
00313 
00314   }while(x2>=x);
00315 }
00316 
00317 STIN void mdct_butterflies(mdct_lookup *init,
00318                              DATA_TYPE *x,
00319                              int points){
00320   
00321   DATA_TYPE *T=init->trig;
00322   int stages=init->log2n-5;
00323   int i,j;
00324   
00325   if(--stages>0){
00326     mdct_butterfly_first(T,x,points);
00327   }
00328 
00329   for(i=1;--stages>0;i++){
00330     for(j=0;j<(1<<i);j++)
00331       mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
00332   }
00333 
00334   for(j=0;j<points;j+=32)
00335     mdct_butterfly_32(x+j);
00336 
00337 }
00338 
00339 void mdct_clear(mdct_lookup *l){
00340   if(l){
00341     if(l->trig)_ogg_free(l->trig);
00342     if(l->bitrev)_ogg_free(l->bitrev);
00343     memset(l,0,sizeof(*l));
00344   }
00345 }
00346 
00347 STIN void mdct_bitreverse(mdct_lookup *init, 
00348                             DATA_TYPE *x){
00349   int        n       = init->n;
00350   int       *bit     = init->bitrev;
00351   DATA_TYPE *w0      = x;
00352   DATA_TYPE *w1      = x = w0+(n>>1);
00353   DATA_TYPE *T       = init->trig+n;
00354 
00355   do{
00356     DATA_TYPE *x0    = x+bit[0];
00357     DATA_TYPE *x1    = x+bit[1];
00358 
00359     REG_TYPE  r0     = x0[1]  - x1[1];
00360     REG_TYPE  r1     = x0[0]  + x1[0];
00361     REG_TYPE  r2     = MULT_NORM(r1     * T[0]   + r0 * T[1]);
00362     REG_TYPE  r3     = MULT_NORM(r1     * T[1]   - r0 * T[0]);
00363 
00364               w1    -= 4;
00365 
00366               r0     = HALVE(x0[1] + x1[1]);
00367               r1     = HALVE(x0[0] - x1[0]);
00368       
00369               w0[0]  = r0     + r2;
00370               w1[2]  = r0     - r2;
00371               w0[1]  = r1     + r3;
00372               w1[3]  = r3     - r1;
00373 
00374               x0     = x+bit[2];
00375               x1     = x+bit[3];
00376 
00377               r0     = x0[1]  - x1[1];
00378               r1     = x0[0]  + x1[0];
00379               r2     = MULT_NORM(r1     * T[2]   + r0 * T[3]);
00380               r3     = MULT_NORM(r1     * T[3]   - r0 * T[2]);
00381 
00382               r0     = HALVE(x0[1] + x1[1]);
00383               r1     = HALVE(x0[0] - x1[0]);
00384       
00385               w0[2]  = r0     + r2;
00386               w1[0]  = r0     - r2;
00387               w0[3]  = r1     + r3;
00388               w1[1]  = r3     - r1;
00389 
00390               T     += 4;
00391               bit   += 4;
00392               w0    += 4;
00393 
00394   }while(w0<w1);
00395 }
00396 
00397 void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
00398   int n=init->n;
00399   int n2=n>>1;
00400   int n4=n>>2;
00401 
00402   /* rotate */
00403 
00404   DATA_TYPE *iX = in+n2-7;
00405   DATA_TYPE *oX = out+n2+n4;
00406   DATA_TYPE *T  = init->trig+n4;
00407 
00408   do{
00409     oX         -= 4;
00410     oX[0]       = MULT_NORM(-iX[2] * T[3] - iX[0]  * T[2]);
00411     oX[1]       = MULT_NORM (iX[0] * T[3] - iX[2]  * T[2]);
00412     oX[2]       = MULT_NORM(-iX[6] * T[1] - iX[4]  * T[0]);
00413     oX[3]       = MULT_NORM (iX[4] * T[1] - iX[6]  * T[0]);
00414     iX         -= 8;
00415     T          += 4;
00416   }while(iX>=in);
00417 
00418   iX            = in+n2-8;
00419   oX            = out+n2+n4;
00420   T             = init->trig+n4;
00421 
00422   do{
00423     T          -= 4;
00424     oX[0]       =  MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
00425     oX[1]       =  MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
00426     oX[2]       =  MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
00427     oX[3]       =  MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
00428     iX         -= 8;
00429     oX         += 4;
00430   }while(iX>=in);
00431 
00432   mdct_butterflies(init,out+n2,n2);
00433   mdct_bitreverse(init,out);
00434 
00435   /* roatate + window */
00436 
00437   {
00438     DATA_TYPE *oX1=out+n2+n4;
00439     DATA_TYPE *oX2=out+n2+n4;
00440     DATA_TYPE *iX =out;
00441     T             =init->trig+n2;
00442     
00443     do{
00444       oX1-=4;
00445 
00446       oX1[3]  =  MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
00447       oX2[0]  = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
00448 
00449       oX1[2]  =  MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
00450       oX2[1]  = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
00451 
00452       oX1[1]  =  MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
00453       oX2[2]  = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
00454 
00455       oX1[0]  =  MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
00456       oX2[3]  = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
00457 
00458       oX2+=4;
00459       iX    +=   8;
00460       T     +=   8;
00461     }while(iX<oX1);
00462 
00463     iX=out+n2+n4;
00464     oX1=out+n4;
00465     oX2=oX1;
00466 
00467     do{
00468       oX1-=4;
00469       iX-=4;
00470 
00471       oX2[0] = -(oX1[3] = iX[3]);
00472       oX2[1] = -(oX1[2] = iX[2]);
00473       oX2[2] = -(oX1[1] = iX[1]);
00474       oX2[3] = -(oX1[0] = iX[0]);
00475 
00476       oX2+=4;
00477     }while(oX2<iX);
00478 
00479     iX=out+n2+n4;
00480     oX1=out+n2+n4;
00481     oX2=out+n2;
00482     do{
00483       oX1-=4;
00484       oX1[0]= iX[3];
00485       oX1[1]= iX[2];
00486       oX1[2]= iX[1];
00487       oX1[3]= iX[0];
00488       iX+=4;
00489     }while(oX1>oX2);
00490   }
00491 }
00492 
00493 void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
00494   int n=init->n;
00495   int n2=n>>1;
00496   int n4=n>>2;
00497   int n8=n>>3;
00498   //DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
00499   DATA_TYPE *w=(DATA_TYPE*)_ogg_malloc(n*sizeof(*w)); /* forward needs working space */ //patch
00500   DATA_TYPE *w_cpy = w; //patch
00501   DATA_TYPE *w2=w+n2;
00502 
00503   /* rotate */
00504 
00505   /* window + rotate + step 1 */
00506   
00507   REG_TYPE r0;
00508   REG_TYPE r1;
00509   DATA_TYPE *x0=in+n2+n4;
00510   DATA_TYPE *x1=x0+1;
00511   DATA_TYPE *T=init->trig+n2;
00512   
00513   int i=0;
00514   
00515   for(i=0;i<n8;i+=2){
00516     x0 -=4;
00517     T-=2;
00518     r0= x0[2] + x1[0];
00519     r1= x0[0] + x1[2];       
00520     w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
00521     w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
00522     x1 +=4;
00523   }
00524 
00525   x1=in+1;
00526   
00527   for(;i<n2-n8;i+=2){
00528     T-=2;
00529     x0 -=4;
00530     r0= x0[2] - x1[0];
00531     r1= x0[0] - x1[2];       
00532     w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
00533     w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
00534     x1 +=4;
00535   }
00536     
00537   x0=in+n;
00538 
00539   for(;i<n2;i+=2){
00540     T-=2;
00541     x0 -=4;
00542     r0= -x0[2] - x1[0];
00543     r1= -x0[0] - x1[2];       
00544     w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
00545     w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
00546     x1 +=4;
00547   }
00548 
00549 
00550   mdct_butterflies(init,w+n2,n2);
00551   mdct_bitreverse(init,w);
00552 
00553   /* roatate + window */
00554 
00555   T=init->trig+n2;
00556   x0=out+n2;
00557 
00558   for(i=0;i<n4;i++){
00559     x0--;
00560     out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
00561     x0[0]  =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
00562     w+=2;
00563     T+=2;
00564   }
00565   free(w_cpy); //patch  
00566 }
00567 

Generated by  doxygen 1.6.2