LCOV - code coverage report
Current view: top level - media/libvorbis/lib - vorbis_mdct.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 359 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /********************************************************************
       2             :  *                                                                  *
       3             :  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
       4             :  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
       5             :  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
       6             :  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
       7             :  *                                                                  *
       8             :  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
       9             :  * by the Xiph.Org Foundation http://www.xiph.org/                  *
      10             :  *                                                                  *
      11             :  ********************************************************************
      12             : 
      13             :  function: normalized modified discrete cosine transform
      14             :            power of two length transform only [64 <= n ]
      15             :  last mod: $Id$
      16             : 
      17             :  Original algorithm adapted long ago from _The use of multirate filter
      18             :  banks for coding of high quality digital audio_, by T. Sporer,
      19             :  K. Brandenburg and B. Edler, collection of the European Signal
      20             :  Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
      21             :  211-214
      22             : 
      23             :  The below code implements an algorithm that no longer looks much like
      24             :  that presented in the paper, but the basic structure remains if you
      25             :  dig deep enough to see it.
      26             : 
      27             :  This module DOES NOT INCLUDE code to generate/apply the window
      28             :  function.  Everybody has their own weird favorite including me... I
      29             :  happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
      30             :  vehemently disagree.
      31             : 
      32             :  ********************************************************************/
      33             : 
      34             : /* this can also be run as an integer transform by uncommenting a
      35             :    define in mdct.h; the integerization is a first pass and although
      36             :    it's likely stable for Vorbis, the dynamic range is constrained and
      37             :    roundoff isn't done (so it's noisy).  Consider it functional, but
      38             :    only a starting point.  There's no point on a machine with an FPU */
      39             : 
      40             : #include <stdio.h>
      41             : #include <stdlib.h>
      42             : #include <string.h>
      43             : #include <math.h>
      44             : #include "vorbis/codec.h"
      45             : #include "mdct.h"
      46             : #include "os.h"
      47             : #include "misc.h"
      48             : 
      49             : /* build lookups for trig functions; also pre-figure scaling and
      50             :    some window function algebra. */
      51             : 
      52           0 : void mdct_init(mdct_lookup *lookup,int n){
      53           0 :   int   *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
      54           0 :   DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
      55             : 
      56             :   int i;
      57           0 :   int n2=n>>1;
      58           0 :   int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
      59           0 :   lookup->n=n;
      60           0 :   lookup->trig=T;
      61           0 :   lookup->bitrev=bitrev;
      62             : 
      63             : /* trig lookups... */
      64             : 
      65           0 :   for(i=0;i<n/4;i++){
      66           0 :     T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
      67           0 :     T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
      68           0 :     T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
      69           0 :     T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
      70             :   }
      71           0 :   for(i=0;i<n/8;i++){
      72           0 :     T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
      73           0 :     T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
      74             :   }
      75             : 
      76             :   /* bitreverse lookup... */
      77             : 
      78             :   {
      79           0 :     int mask=(1<<(log2n-1))-1,i,j;
      80           0 :     int msb=1<<(log2n-2);
      81           0 :     for(i=0;i<n/8;i++){
      82           0 :       int acc=0;
      83           0 :       for(j=0;msb>>j;j++)
      84           0 :         if((msb>>j)&i)acc|=1<<j;
      85           0 :       bitrev[i*2]=((~acc)&mask)-1;
      86           0 :       bitrev[i*2+1]=acc;
      87             : 
      88             :     }
      89             :   }
      90           0 :   lookup->scale=FLOAT_CONV(4.f/n);
      91           0 : }
      92             : 
      93             : /* 8 point butterfly (in place, 4 register) */
      94           0 : STIN void mdct_butterfly_8(DATA_TYPE *x){
      95           0 :   REG_TYPE r0   = x[6] + x[2];
      96           0 :   REG_TYPE r1   = x[6] - x[2];
      97           0 :   REG_TYPE r2   = x[4] + x[0];
      98           0 :   REG_TYPE r3   = x[4] - x[0];
      99             : 
     100           0 :            x[6] = r0   + r2;
     101           0 :            x[4] = r0   - r2;
     102             : 
     103           0 :            r0   = x[5] - x[1];
     104           0 :            r2   = x[7] - x[3];
     105           0 :            x[0] = r1   + r0;
     106           0 :            x[2] = r1   - r0;
     107             : 
     108           0 :            r0   = x[5] + x[1];
     109           0 :            r1   = x[7] + x[3];
     110           0 :            x[3] = r2   + r3;
     111           0 :            x[1] = r2   - r3;
     112           0 :            x[7] = r1   + r0;
     113           0 :            x[5] = r1   - r0;
     114             : 
     115           0 : }
     116             : 
     117             : /* 16 point butterfly (in place, 4 register) */
     118           0 : STIN void mdct_butterfly_16(DATA_TYPE *x){
     119           0 :   REG_TYPE r0     = x[1]  - x[9];
     120           0 :   REG_TYPE r1     = x[0]  - x[8];
     121             : 
     122           0 :            x[8]  += x[0];
     123           0 :            x[9]  += x[1];
     124           0 :            x[0]   = MULT_NORM((r0   + r1) * cPI2_8);
     125           0 :            x[1]   = MULT_NORM((r0   - r1) * cPI2_8);
     126             : 
     127           0 :            r0     = x[3]  - x[11];
     128           0 :            r1     = x[10] - x[2];
     129           0 :            x[10] += x[2];
     130           0 :            x[11] += x[3];
     131           0 :            x[2]   = r0;
     132           0 :            x[3]   = r1;
     133             : 
     134           0 :            r0     = x[12] - x[4];
     135           0 :            r1     = x[13] - x[5];
     136           0 :            x[12] += x[4];
     137           0 :            x[13] += x[5];
     138           0 :            x[4]   = MULT_NORM((r0   - r1) * cPI2_8);
     139           0 :            x[5]   = MULT_NORM((r0   + r1) * cPI2_8);
     140             : 
     141           0 :            r0     = x[14] - x[6];
     142           0 :            r1     = x[15] - x[7];
     143           0 :            x[14] += x[6];
     144           0 :            x[15] += x[7];
     145           0 :            x[6]  = r0;
     146           0 :            x[7]  = r1;
     147             : 
     148           0 :            mdct_butterfly_8(x);
     149           0 :            mdct_butterfly_8(x+8);
     150           0 : }
     151             : 
     152             : /* 32 point butterfly (in place, 4 register) */
     153           0 : STIN void mdct_butterfly_32(DATA_TYPE *x){
     154           0 :   REG_TYPE r0     = x[30] - x[14];
     155           0 :   REG_TYPE r1     = x[31] - x[15];
     156             : 
     157           0 :            x[30] +=         x[14];
     158           0 :            x[31] +=         x[15];
     159           0 :            x[14]  =         r0;
     160           0 :            x[15]  =         r1;
     161             : 
     162           0 :            r0     = x[28] - x[12];
     163           0 :            r1     = x[29] - x[13];
     164           0 :            x[28] +=         x[12];
     165           0 :            x[29] +=         x[13];
     166           0 :            x[12]  = MULT_NORM( r0 * cPI1_8  -  r1 * cPI3_8 );
     167           0 :            x[13]  = MULT_NORM( r0 * cPI3_8  +  r1 * cPI1_8 );
     168             : 
     169           0 :            r0     = x[26] - x[10];
     170           0 :            r1     = x[27] - x[11];
     171           0 :            x[26] +=         x[10];
     172           0 :            x[27] +=         x[11];
     173           0 :            x[10]  = MULT_NORM(( r0  - r1 ) * cPI2_8);
     174           0 :            x[11]  = MULT_NORM(( r0  + r1 ) * cPI2_8);
     175             : 
     176           0 :            r0     = x[24] - x[8];
     177           0 :            r1     = x[25] - x[9];
     178           0 :            x[24] += x[8];
     179           0 :            x[25] += x[9];
     180           0 :            x[8]   = MULT_NORM( r0 * cPI3_8  -  r1 * cPI1_8 );
     181           0 :            x[9]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
     182             : 
     183           0 :            r0     = x[22] - x[6];
     184           0 :            r1     = x[7]  - x[23];
     185           0 :            x[22] += x[6];
     186           0 :            x[23] += x[7];
     187           0 :            x[6]   = r1;
     188           0 :            x[7]   = r0;
     189             : 
     190           0 :            r0     = x[4]  - x[20];
     191           0 :            r1     = x[5]  - x[21];
     192           0 :            x[20] += x[4];
     193           0 :            x[21] += x[5];
     194           0 :            x[4]   = MULT_NORM( r1 * cPI1_8  +  r0 * cPI3_8 );
     195           0 :            x[5]   = MULT_NORM( r1 * cPI3_8  -  r0 * cPI1_8 );
     196             : 
     197           0 :            r0     = x[2]  - x[18];
     198           0 :            r1     = x[3]  - x[19];
     199           0 :            x[18] += x[2];
     200           0 :            x[19] += x[3];
     201           0 :            x[2]   = MULT_NORM(( r1  + r0 ) * cPI2_8);
     202           0 :            x[3]   = MULT_NORM(( r1  - r0 ) * cPI2_8);
     203             : 
     204           0 :            r0     = x[0]  - x[16];
     205           0 :            r1     = x[1]  - x[17];
     206           0 :            x[16] += x[0];
     207           0 :            x[17] += x[1];
     208           0 :            x[0]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
     209           0 :            x[1]   = MULT_NORM( r1 * cPI1_8  -  r0 * cPI3_8 );
     210             : 
     211           0 :            mdct_butterfly_16(x);
     212           0 :            mdct_butterfly_16(x+16);
     213             : 
     214           0 : }
     215             : 
     216             : /* N point first stage butterfly (in place, 2 register) */
     217           0 : STIN void mdct_butterfly_first(DATA_TYPE *T,
     218             :                                         DATA_TYPE *x,
     219             :                                         int points){
     220             : 
     221           0 :   DATA_TYPE *x1        = x          + points      - 8;
     222           0 :   DATA_TYPE *x2        = x          + (points>>1) - 8;
     223             :   REG_TYPE   r0;
     224             :   REG_TYPE   r1;
     225             : 
     226             :   do{
     227             : 
     228           0 :                r0      = x1[6]      -  x2[6];
     229           0 :                r1      = x1[7]      -  x2[7];
     230           0 :                x1[6]  += x2[6];
     231           0 :                x1[7]  += x2[7];
     232           0 :                x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
     233           0 :                x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
     234             : 
     235           0 :                r0      = x1[4]      -  x2[4];
     236           0 :                r1      = x1[5]      -  x2[5];
     237           0 :                x1[4]  += x2[4];
     238           0 :                x1[5]  += x2[5];
     239           0 :                x2[4]   = MULT_NORM(r1 * T[5]  +  r0 * T[4]);
     240           0 :                x2[5]   = MULT_NORM(r1 * T[4]  -  r0 * T[5]);
     241             : 
     242           0 :                r0      = x1[2]      -  x2[2];
     243           0 :                r1      = x1[3]      -  x2[3];
     244           0 :                x1[2]  += x2[2];
     245           0 :                x1[3]  += x2[3];
     246           0 :                x2[2]   = MULT_NORM(r1 * T[9]  +  r0 * T[8]);
     247           0 :                x2[3]   = MULT_NORM(r1 * T[8]  -  r0 * T[9]);
     248             : 
     249           0 :                r0      = x1[0]      -  x2[0];
     250           0 :                r1      = x1[1]      -  x2[1];
     251           0 :                x1[0]  += x2[0];
     252           0 :                x1[1]  += x2[1];
     253           0 :                x2[0]   = MULT_NORM(r1 * T[13] +  r0 * T[12]);
     254           0 :                x2[1]   = MULT_NORM(r1 * T[12] -  r0 * T[13]);
     255             : 
     256           0 :     x1-=8;
     257           0 :     x2-=8;
     258           0 :     T+=16;
     259             : 
     260           0 :   }while(x2>=x);
     261           0 : }
     262             : 
     263             : /* N/stage point generic N stage butterfly (in place, 2 register) */
     264           0 : STIN void mdct_butterfly_generic(DATA_TYPE *T,
     265             :                                           DATA_TYPE *x,
     266             :                                           int points,
     267             :                                           int trigint){
     268             : 
     269           0 :   DATA_TYPE *x1        = x          + points      - 8;
     270           0 :   DATA_TYPE *x2        = x          + (points>>1) - 8;
     271             :   REG_TYPE   r0;
     272             :   REG_TYPE   r1;
     273             : 
     274             :   do{
     275             : 
     276           0 :                r0      = x1[6]      -  x2[6];
     277           0 :                r1      = x1[7]      -  x2[7];
     278           0 :                x1[6]  += x2[6];
     279           0 :                x1[7]  += x2[7];
     280           0 :                x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
     281           0 :                x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
     282             : 
     283           0 :                T+=trigint;
     284             : 
     285           0 :                r0      = x1[4]      -  x2[4];
     286           0 :                r1      = x1[5]      -  x2[5];
     287           0 :                x1[4]  += x2[4];
     288           0 :                x1[5]  += x2[5];
     289           0 :                x2[4]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
     290           0 :                x2[5]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
     291             : 
     292           0 :                T+=trigint;
     293             : 
     294           0 :                r0      = x1[2]      -  x2[2];
     295           0 :                r1      = x1[3]      -  x2[3];
     296           0 :                x1[2]  += x2[2];
     297           0 :                x1[3]  += x2[3];
     298           0 :                x2[2]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
     299           0 :                x2[3]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
     300             : 
     301           0 :                T+=trigint;
     302             : 
     303           0 :                r0      = x1[0]      -  x2[0];
     304           0 :                r1      = x1[1]      -  x2[1];
     305           0 :                x1[0]  += x2[0];
     306           0 :                x1[1]  += x2[1];
     307           0 :                x2[0]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
     308           0 :                x2[1]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
     309             : 
     310           0 :                T+=trigint;
     311           0 :     x1-=8;
     312           0 :     x2-=8;
     313             : 
     314           0 :   }while(x2>=x);
     315           0 : }
     316             : 
     317           0 : STIN void mdct_butterflies(mdct_lookup *init,
     318             :                              DATA_TYPE *x,
     319             :                              int points){
     320             : 
     321           0 :   DATA_TYPE *T=init->trig;
     322           0 :   int stages=init->log2n-5;
     323             :   int i,j;
     324             : 
     325           0 :   if(--stages>0){
     326           0 :     mdct_butterfly_first(T,x,points);
     327             :   }
     328             : 
     329           0 :   for(i=1;--stages>0;i++){
     330           0 :     for(j=0;j<(1<<i);j++)
     331           0 :       mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
     332             :   }
     333             : 
     334           0 :   for(j=0;j<points;j+=32)
     335           0 :     mdct_butterfly_32(x+j);
     336             : 
     337           0 : }
     338             : 
     339           0 : void mdct_clear(mdct_lookup *l){
     340           0 :   if(l){
     341           0 :     if(l->trig)_ogg_free(l->trig);
     342           0 :     if(l->bitrev)_ogg_free(l->bitrev);
     343           0 :     memset(l,0,sizeof(*l));
     344             :   }
     345           0 : }
     346             : 
     347           0 : STIN void mdct_bitreverse(mdct_lookup *init,
     348             :                             DATA_TYPE *x){
     349           0 :   int        n       = init->n;
     350           0 :   int       *bit     = init->bitrev;
     351           0 :   DATA_TYPE *w0      = x;
     352           0 :   DATA_TYPE *w1      = x = w0+(n>>1);
     353           0 :   DATA_TYPE *T       = init->trig+n;
     354             : 
     355             :   do{
     356           0 :     DATA_TYPE *x0    = x+bit[0];
     357           0 :     DATA_TYPE *x1    = x+bit[1];
     358             : 
     359           0 :     REG_TYPE  r0     = x0[1]  - x1[1];
     360           0 :     REG_TYPE  r1     = x0[0]  + x1[0];
     361           0 :     REG_TYPE  r2     = MULT_NORM(r1     * T[0]   + r0 * T[1]);
     362           0 :     REG_TYPE  r3     = MULT_NORM(r1     * T[1]   - r0 * T[0]);
     363             : 
     364           0 :               w1    -= 4;
     365             : 
     366           0 :               r0     = HALVE(x0[1] + x1[1]);
     367           0 :               r1     = HALVE(x0[0] - x1[0]);
     368             : 
     369           0 :               w0[0]  = r0     + r2;
     370           0 :               w1[2]  = r0     - r2;
     371           0 :               w0[1]  = r1     + r3;
     372           0 :               w1[3]  = r3     - r1;
     373             : 
     374           0 :               x0     = x+bit[2];
     375           0 :               x1     = x+bit[3];
     376             : 
     377           0 :               r0     = x0[1]  - x1[1];
     378           0 :               r1     = x0[0]  + x1[0];
     379           0 :               r2     = MULT_NORM(r1     * T[2]   + r0 * T[3]);
     380           0 :               r3     = MULT_NORM(r1     * T[3]   - r0 * T[2]);
     381             : 
     382           0 :               r0     = HALVE(x0[1] + x1[1]);
     383           0 :               r1     = HALVE(x0[0] - x1[0]);
     384             : 
     385           0 :               w0[2]  = r0     + r2;
     386           0 :               w1[0]  = r0     - r2;
     387           0 :               w0[3]  = r1     + r3;
     388           0 :               w1[1]  = r3     - r1;
     389             : 
     390           0 :               T     += 4;
     391           0 :               bit   += 4;
     392           0 :               w0    += 4;
     393             : 
     394           0 :   }while(w0<w1);
     395           0 : }
     396             : 
     397           0 : void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
     398           0 :   int n=init->n;
     399           0 :   int n2=n>>1;
     400           0 :   int n4=n>>2;
     401             : 
     402             :   /* rotate */
     403             : 
     404           0 :   DATA_TYPE *iX = in+n2-7;
     405           0 :   DATA_TYPE *oX = out+n2+n4;
     406           0 :   DATA_TYPE *T  = init->trig+n4;
     407             : 
     408             :   do{
     409           0 :     oX         -= 4;
     410           0 :     oX[0]       = MULT_NORM(-iX[2] * T[3] - iX[0]  * T[2]);
     411           0 :     oX[1]       = MULT_NORM (iX[0] * T[3] - iX[2]  * T[2]);
     412           0 :     oX[2]       = MULT_NORM(-iX[6] * T[1] - iX[4]  * T[0]);
     413           0 :     oX[3]       = MULT_NORM (iX[4] * T[1] - iX[6]  * T[0]);
     414           0 :     iX         -= 8;
     415           0 :     T          += 4;
     416           0 :   }while(iX>=in);
     417             : 
     418           0 :   iX            = in+n2-8;
     419           0 :   oX            = out+n2+n4;
     420           0 :   T             = init->trig+n4;
     421             : 
     422             :   do{
     423           0 :     T          -= 4;
     424           0 :     oX[0]       =  MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
     425           0 :     oX[1]       =  MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
     426           0 :     oX[2]       =  MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
     427           0 :     oX[3]       =  MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
     428           0 :     iX         -= 8;
     429           0 :     oX         += 4;
     430           0 :   }while(iX>=in);
     431             : 
     432           0 :   mdct_butterflies(init,out+n2,n2);
     433           0 :   mdct_bitreverse(init,out);
     434             : 
     435             :   /* roatate + window */
     436             : 
     437             :   {
     438           0 :     DATA_TYPE *oX1=out+n2+n4;
     439           0 :     DATA_TYPE *oX2=out+n2+n4;
     440           0 :     DATA_TYPE *iX =out;
     441           0 :     T             =init->trig+n2;
     442             : 
     443             :     do{
     444           0 :       oX1-=4;
     445             : 
     446           0 :       oX1[3]  =  MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
     447           0 :       oX2[0]  = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
     448             : 
     449           0 :       oX1[2]  =  MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
     450           0 :       oX2[1]  = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
     451             : 
     452           0 :       oX1[1]  =  MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
     453           0 :       oX2[2]  = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
     454             : 
     455           0 :       oX1[0]  =  MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
     456           0 :       oX2[3]  = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
     457             : 
     458           0 :       oX2+=4;
     459           0 :       iX    +=   8;
     460           0 :       T     +=   8;
     461           0 :     }while(iX<oX1);
     462             : 
     463           0 :     iX=out+n2+n4;
     464           0 :     oX1=out+n4;
     465           0 :     oX2=oX1;
     466             : 
     467             :     do{
     468           0 :       oX1-=4;
     469           0 :       iX-=4;
     470             : 
     471           0 :       oX2[0] = -(oX1[3] = iX[3]);
     472           0 :       oX2[1] = -(oX1[2] = iX[2]);
     473           0 :       oX2[2] = -(oX1[1] = iX[1]);
     474           0 :       oX2[3] = -(oX1[0] = iX[0]);
     475             : 
     476           0 :       oX2+=4;
     477           0 :     }while(oX2<iX);
     478             : 
     479           0 :     iX=out+n2+n4;
     480           0 :     oX1=out+n2+n4;
     481           0 :     oX2=out+n2;
     482             :     do{
     483           0 :       oX1-=4;
     484           0 :       oX1[0]= iX[3];
     485           0 :       oX1[1]= iX[2];
     486           0 :       oX1[2]= iX[1];
     487           0 :       oX1[3]= iX[0];
     488           0 :       iX+=4;
     489           0 :     }while(oX1>oX2);
     490             :   }
     491           0 : }
     492             : 
     493           0 : void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
     494           0 :   int n=init->n;
     495           0 :   int n2=n>>1;
     496           0 :   int n4=n>>2;
     497           0 :   int n8=n>>3;
     498           0 :   DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
     499           0 :   DATA_TYPE *w2=w+n2;
     500             : 
     501             :   /* rotate */
     502             : 
     503             :   /* window + rotate + step 1 */
     504             : 
     505             :   REG_TYPE r0;
     506             :   REG_TYPE r1;
     507           0 :   DATA_TYPE *x0=in+n2+n4;
     508           0 :   DATA_TYPE *x1=x0+1;
     509           0 :   DATA_TYPE *T=init->trig+n2;
     510             : 
     511           0 :   int i=0;
     512             : 
     513           0 :   for(i=0;i<n8;i+=2){
     514           0 :     x0 -=4;
     515           0 :     T-=2;
     516           0 :     r0= x0[2] + x1[0];
     517           0 :     r1= x0[0] + x1[2];
     518           0 :     w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
     519           0 :     w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
     520           0 :     x1 +=4;
     521             :   }
     522             : 
     523           0 :   x1=in+1;
     524             : 
     525           0 :   for(;i<n2-n8;i+=2){
     526           0 :     T-=2;
     527           0 :     x0 -=4;
     528           0 :     r0= x0[2] - x1[0];
     529           0 :     r1= x0[0] - x1[2];
     530           0 :     w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
     531           0 :     w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
     532           0 :     x1 +=4;
     533             :   }
     534             : 
     535           0 :   x0=in+n;
     536             : 
     537           0 :   for(;i<n2;i+=2){
     538           0 :     T-=2;
     539           0 :     x0 -=4;
     540           0 :     r0= -x0[2] - x1[0];
     541           0 :     r1= -x0[0] - x1[2];
     542           0 :     w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
     543           0 :     w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
     544           0 :     x1 +=4;
     545             :   }
     546             : 
     547             : 
     548           0 :   mdct_butterflies(init,w+n2,n2);
     549           0 :   mdct_bitreverse(init,w);
     550             : 
     551             :   /* roatate + window */
     552             : 
     553           0 :   T=init->trig+n2;
     554           0 :   x0=out+n2;
     555             : 
     556           0 :   for(i=0;i<n4;i++){
     557           0 :     x0--;
     558           0 :     out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
     559           0 :     x0[0]  =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
     560           0 :     w+=2;
     561           0 :     T+=2;
     562             :   }
     563           0 : }

Generated by: LCOV version 1.13