Blame lib/mdct.c

Packit 06404a
/********************************************************************
Packit 06404a
 *                                                                  *
Packit 06404a
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
Packit 06404a
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
Packit 06404a
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Packit 06404a
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
Packit 06404a
 *                                                                  *
Packit 06404a
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
Packit 06404a
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
Packit 06404a
 *                                                                  *
Packit 06404a
 ********************************************************************
Packit 06404a
Packit 06404a
 function: normalized modified discrete cosine transform
Packit 06404a
           power of two length transform only [64 <= n ]
Packit 06404a
 last mod: $Id: mdct.c 16227 2009-07-08 06:58:46Z xiphmont $
Packit 06404a
Packit 06404a
 Original algorithm adapted long ago from _The use of multirate filter
Packit 06404a
 banks for coding of high quality digital audio_, by T. Sporer,
Packit 06404a
 K. Brandenburg and B. Edler, collection of the European Signal
Packit 06404a
 Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
Packit 06404a
 211-214
Packit 06404a
Packit 06404a
 The below code implements an algorithm that no longer looks much like
Packit 06404a
 that presented in the paper, but the basic structure remains if you
Packit 06404a
 dig deep enough to see it.
Packit 06404a
Packit 06404a
 This module DOES NOT INCLUDE code to generate/apply the window
Packit 06404a
 function.  Everybody has their own weird favorite including me... I
Packit 06404a
 happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
Packit 06404a
 vehemently disagree.
Packit 06404a
Packit 06404a
 ********************************************************************/
Packit 06404a
Packit 06404a
/* this can also be run as an integer transform by uncommenting a
Packit 06404a
   define in mdct.h; the integerization is a first pass and although
Packit 06404a
   it's likely stable for Vorbis, the dynamic range is constrained and
Packit 06404a
   roundoff isn't done (so it's noisy).  Consider it functional, but
Packit 06404a
   only a starting point.  There's no point on a machine with an FPU */
Packit 06404a
Packit 06404a
#include <stdio.h>
Packit 06404a
#include <stdlib.h>
Packit 06404a
#include <string.h>
Packit 06404a
#include <math.h>
Packit 06404a
#include "vorbis/codec.h"
Packit 06404a
#include "mdct.h"
Packit 06404a
#include "os.h"
Packit 06404a
#include "misc.h"
Packit 06404a
Packit 06404a
/* build lookups for trig functions; also pre-figure scaling and
Packit 06404a
   some window function algebra. */
Packit 06404a
Packit 06404a
void mdct_init(mdct_lookup *lookup,int n){
Packit 06404a
  int   *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
Packit 06404a
  DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
Packit 06404a
Packit 06404a
  int i;
Packit 06404a
  int n2=n>>1;
Packit 06404a
  int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
Packit 06404a
  lookup->n=n;
Packit 06404a
  lookup->trig=T;
Packit 06404a
  lookup->bitrev=bitrev;
Packit 06404a
Packit 06404a
/* trig lookups... */
Packit 06404a
Packit 06404a
  for(i=0;i
Packit 06404a
    T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
Packit 06404a
    T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
Packit 06404a
    T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
Packit 06404a
    T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
Packit 06404a
  }
Packit 06404a
  for(i=0;i
Packit 06404a
    T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
Packit 06404a
    T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
Packit 06404a
  }
Packit 06404a
Packit 06404a
  /* bitreverse lookup... */
Packit 06404a
Packit 06404a
  {
Packit 06404a
    int mask=(1<<(log2n-1))-1,i,j;
Packit 06404a
    int msb=1<<(log2n-2);
Packit 06404a
    for(i=0;i
Packit 06404a
      int acc=0;
Packit 06404a
      for(j=0;msb>>j;j++)
Packit 06404a
        if((msb>>j)&i)acc|=1<
Packit 06404a
      bitrev[i*2]=((~acc)&mask)-1;
Packit 06404a
      bitrev[i*2+1]=acc;
Packit 06404a
Packit 06404a
    }
Packit 06404a
  }
Packit 06404a
  lookup->scale=FLOAT_CONV(4.f/n);
Packit 06404a
}
Packit 06404a
Packit 06404a
/* 8 point butterfly (in place, 4 register) */
Packit 06404a
STIN void mdct_butterfly_8(DATA_TYPE *x){
Packit 06404a
  REG_TYPE r0   = x[6] + x[2];
Packit 06404a
  REG_TYPE r1   = x[6] - x[2];
Packit 06404a
  REG_TYPE r2   = x[4] + x[0];
Packit 06404a
  REG_TYPE r3   = x[4] - x[0];
Packit 06404a
Packit 06404a
           x[6] = r0   + r2;
Packit 06404a
           x[4] = r0   - r2;
Packit 06404a
Packit 06404a
           r0   = x[5] - x[1];
Packit 06404a
           r2   = x[7] - x[3];
Packit 06404a
           x[0] = r1   + r0;
Packit 06404a
           x[2] = r1   - r0;
Packit 06404a
Packit 06404a
           r0   = x[5] + x[1];
Packit 06404a
           r1   = x[7] + x[3];
Packit 06404a
           x[3] = r2   + r3;
Packit 06404a
           x[1] = r2   - r3;
Packit 06404a
           x[7] = r1   + r0;
Packit 06404a
           x[5] = r1   - r0;
Packit 06404a
Packit 06404a
}
Packit 06404a
Packit 06404a
/* 16 point butterfly (in place, 4 register) */
Packit 06404a
STIN void mdct_butterfly_16(DATA_TYPE *x){
Packit 06404a
  REG_TYPE r0     = x[1]  - x[9];
Packit 06404a
  REG_TYPE r1     = x[0]  - x[8];
Packit 06404a
Packit 06404a
           x[8]  += x[0];
Packit 06404a
           x[9]  += x[1];
Packit 06404a
           x[0]   = MULT_NORM((r0   + r1) * cPI2_8);
Packit 06404a
           x[1]   = MULT_NORM((r0   - r1) * cPI2_8);
Packit 06404a
Packit 06404a
           r0     = x[3]  - x[11];
Packit 06404a
           r1     = x[10] - x[2];
Packit 06404a
           x[10] += x[2];
Packit 06404a
           x[11] += x[3];
Packit 06404a
           x[2]   = r0;
Packit 06404a
           x[3]   = r1;
Packit 06404a
Packit 06404a
           r0     = x[12] - x[4];
Packit 06404a
           r1     = x[13] - x[5];
Packit 06404a
           x[12] += x[4];
Packit 06404a
           x[13] += x[5];
Packit 06404a
           x[4]   = MULT_NORM((r0   - r1) * cPI2_8);
Packit 06404a
           x[5]   = MULT_NORM((r0   + r1) * cPI2_8);
Packit 06404a
Packit 06404a
           r0     = x[14] - x[6];
Packit 06404a
           r1     = x[15] - x[7];
Packit 06404a
           x[14] += x[6];
Packit 06404a
           x[15] += x[7];
Packit 06404a
           x[6]  = r0;
Packit 06404a
           x[7]  = r1;
Packit 06404a
Packit 06404a
           mdct_butterfly_8(x);
Packit 06404a
           mdct_butterfly_8(x+8);
Packit 06404a
}
Packit 06404a
Packit 06404a
/* 32 point butterfly (in place, 4 register) */
Packit 06404a
STIN void mdct_butterfly_32(DATA_TYPE *x){
Packit 06404a
  REG_TYPE r0     = x[30] - x[14];
Packit 06404a
  REG_TYPE r1     = x[31] - x[15];
Packit 06404a
Packit 06404a
           x[30] +=         x[14];
Packit 06404a
           x[31] +=         x[15];
Packit 06404a
           x[14]  =         r0;
Packit 06404a
           x[15]  =         r1;
Packit 06404a
Packit 06404a
           r0     = x[28] - x[12];
Packit 06404a
           r1     = x[29] - x[13];
Packit 06404a
           x[28] +=         x[12];
Packit 06404a
           x[29] +=         x[13];
Packit 06404a
           x[12]  = MULT_NORM( r0 * cPI1_8  -  r1 * cPI3_8 );
Packit 06404a
           x[13]  = MULT_NORM( r0 * cPI3_8  +  r1 * cPI1_8 );
Packit 06404a
Packit 06404a
           r0     = x[26] - x[10];
Packit 06404a
           r1     = x[27] - x[11];
Packit 06404a
           x[26] +=         x[10];
Packit 06404a
           x[27] +=         x[11];
Packit 06404a
           x[10]  = MULT_NORM(( r0  - r1 ) * cPI2_8);
Packit 06404a
           x[11]  = MULT_NORM(( r0  + r1 ) * cPI2_8);
Packit 06404a
Packit 06404a
           r0     = x[24] - x[8];
Packit 06404a
           r1     = x[25] - x[9];
Packit 06404a
           x[24] += x[8];
Packit 06404a
           x[25] += x[9];
Packit 06404a
           x[8]   = MULT_NORM( r0 * cPI3_8  -  r1 * cPI1_8 );
Packit 06404a
           x[9]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
Packit 06404a
Packit 06404a
           r0     = x[22] - x[6];
Packit 06404a
           r1     = x[7]  - x[23];
Packit 06404a
           x[22] += x[6];
Packit 06404a
           x[23] += x[7];
Packit 06404a
           x[6]   = r1;
Packit 06404a
           x[7]   = r0;
Packit 06404a
Packit 06404a
           r0     = x[4]  - x[20];
Packit 06404a
           r1     = x[5]  - x[21];
Packit 06404a
           x[20] += x[4];
Packit 06404a
           x[21] += x[5];
Packit 06404a
           x[4]   = MULT_NORM( r1 * cPI1_8  +  r0 * cPI3_8 );
Packit 06404a
           x[5]   = MULT_NORM( r1 * cPI3_8  -  r0 * cPI1_8 );
Packit 06404a
Packit 06404a
           r0     = x[2]  - x[18];
Packit 06404a
           r1     = x[3]  - x[19];
Packit 06404a
           x[18] += x[2];
Packit 06404a
           x[19] += x[3];
Packit 06404a
           x[2]   = MULT_NORM(( r1  + r0 ) * cPI2_8);
Packit 06404a
           x[3]   = MULT_NORM(( r1  - r0 ) * cPI2_8);
Packit 06404a
Packit 06404a
           r0     = x[0]  - x[16];
Packit 06404a
           r1     = x[1]  - x[17];
Packit 06404a
           x[16] += x[0];
Packit 06404a
           x[17] += x[1];
Packit 06404a
           x[0]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
Packit 06404a
           x[1]   = MULT_NORM( r1 * cPI1_8  -  r0 * cPI3_8 );
Packit 06404a
Packit 06404a
           mdct_butterfly_16(x);
Packit 06404a
           mdct_butterfly_16(x+16);
Packit 06404a
Packit 06404a
}
Packit 06404a
Packit 06404a
/* N point first stage butterfly (in place, 2 register) */
Packit 06404a
STIN void mdct_butterfly_first(DATA_TYPE *T,
Packit 06404a
                                        DATA_TYPE *x,
Packit 06404a
                                        int points){
Packit 06404a
Packit 06404a
  DATA_TYPE *x1        = x          + points      - 8;
Packit 06404a
  DATA_TYPE *x2        = x          + (points>>1) - 8;
Packit 06404a
  REG_TYPE   r0;
Packit 06404a
  REG_TYPE   r1;
Packit 06404a
Packit 06404a
  do{
Packit 06404a
Packit 06404a
               r0      = x1[6]      -  x2[6];
Packit 06404a
               r1      = x1[7]      -  x2[7];
Packit 06404a
               x1[6]  += x2[6];
Packit 06404a
               x1[7]  += x2[7];
Packit 06404a
               x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
Packit 06404a
               x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
Packit 06404a
Packit 06404a
               r0      = x1[4]      -  x2[4];
Packit 06404a
               r1      = x1[5]      -  x2[5];
Packit 06404a
               x1[4]  += x2[4];
Packit 06404a
               x1[5]  += x2[5];
Packit 06404a
               x2[4]   = MULT_NORM(r1 * T[5]  +  r0 * T[4]);
Packit 06404a
               x2[5]   = MULT_NORM(r1 * T[4]  -  r0 * T[5]);
Packit 06404a
Packit 06404a
               r0      = x1[2]      -  x2[2];
Packit 06404a
               r1      = x1[3]      -  x2[3];
Packit 06404a
               x1[2]  += x2[2];
Packit 06404a
               x1[3]  += x2[3];
Packit 06404a
               x2[2]   = MULT_NORM(r1 * T[9]  +  r0 * T[8]);
Packit 06404a
               x2[3]   = MULT_NORM(r1 * T[8]  -  r0 * T[9]);
Packit 06404a
Packit 06404a
               r0      = x1[0]      -  x2[0];
Packit 06404a
               r1      = x1[1]      -  x2[1];
Packit 06404a
               x1[0]  += x2[0];
Packit 06404a
               x1[1]  += x2[1];
Packit 06404a
               x2[0]   = MULT_NORM(r1 * T[13] +  r0 * T[12]);
Packit 06404a
               x2[1]   = MULT_NORM(r1 * T[12] -  r0 * T[13]);
Packit 06404a
Packit 06404a
    x1-=8;
Packit 06404a
    x2-=8;
Packit 06404a
    T+=16;
Packit 06404a
Packit 06404a
  }while(x2>=x);
Packit 06404a
}
Packit 06404a
Packit 06404a
/* N/stage point generic N stage butterfly (in place, 2 register) */
Packit 06404a
STIN void mdct_butterfly_generic(DATA_TYPE *T,
Packit 06404a
                                          DATA_TYPE *x,
Packit 06404a
                                          int points,
Packit 06404a
                                          int trigint){
Packit 06404a
Packit 06404a
  DATA_TYPE *x1        = x          + points      - 8;
Packit 06404a
  DATA_TYPE *x2        = x          + (points>>1) - 8;
Packit 06404a
  REG_TYPE   r0;
Packit 06404a
  REG_TYPE   r1;
Packit 06404a
Packit 06404a
  do{
Packit 06404a
Packit 06404a
               r0      = x1[6]      -  x2[6];
Packit 06404a
               r1      = x1[7]      -  x2[7];
Packit 06404a
               x1[6]  += x2[6];
Packit 06404a
               x1[7]  += x2[7];
Packit 06404a
               x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
Packit 06404a
               x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
Packit 06404a
Packit 06404a
               T+=trigint;
Packit 06404a
Packit 06404a
               r0      = x1[4]      -  x2[4];
Packit 06404a
               r1      = x1[5]      -  x2[5];
Packit 06404a
               x1[4]  += x2[4];
Packit 06404a
               x1[5]  += x2[5];
Packit 06404a
               x2[4]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
Packit 06404a
               x2[5]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
Packit 06404a
Packit 06404a
               T+=trigint;
Packit 06404a
Packit 06404a
               r0      = x1[2]      -  x2[2];
Packit 06404a
               r1      = x1[3]      -  x2[3];
Packit 06404a
               x1[2]  += x2[2];
Packit 06404a
               x1[3]  += x2[3];
Packit 06404a
               x2[2]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
Packit 06404a
               x2[3]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
Packit 06404a
Packit 06404a
               T+=trigint;
Packit 06404a
Packit 06404a
               r0      = x1[0]      -  x2[0];
Packit 06404a
               r1      = x1[1]      -  x2[1];
Packit 06404a
               x1[0]  += x2[0];
Packit 06404a
               x1[1]  += x2[1];
Packit 06404a
               x2[0]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
Packit 06404a
               x2[1]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
Packit 06404a
Packit 06404a
               T+=trigint;
Packit 06404a
    x1-=8;
Packit 06404a
    x2-=8;
Packit 06404a
Packit 06404a
  }while(x2>=x);
Packit 06404a
}
Packit 06404a
Packit 06404a
STIN void mdct_butterflies(mdct_lookup *init,
Packit 06404a
                             DATA_TYPE *x,
Packit 06404a
                             int points){
Packit 06404a
Packit 06404a
  DATA_TYPE *T=init->trig;
Packit 06404a
  int stages=init->log2n-5;
Packit 06404a
  int i,j;
Packit 06404a
Packit 06404a
  if(--stages>0){
Packit 06404a
    mdct_butterfly_first(T,x,points);
Packit 06404a
  }
Packit 06404a
Packit 06404a
  for(i=1;--stages>0;i++){
Packit 06404a
    for(j=0;j<(1<
Packit 06404a
      mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<
Packit 06404a
  }
Packit 06404a
Packit 06404a
  for(j=0;j
Packit 06404a
    mdct_butterfly_32(x+j);
Packit 06404a
Packit 06404a
}
Packit 06404a
Packit 06404a
void mdct_clear(mdct_lookup *l){
Packit 06404a
  if(l){
Packit 06404a
    if(l->trig)_ogg_free(l->trig);
Packit 06404a
    if(l->bitrev)_ogg_free(l->bitrev);
Packit 06404a
    memset(l,0,sizeof(*l));
Packit 06404a
  }
Packit 06404a
}
Packit 06404a
Packit 06404a
STIN void mdct_bitreverse(mdct_lookup *init,
Packit 06404a
                            DATA_TYPE *x){
Packit 06404a
  int        n       = init->n;
Packit 06404a
  int       *bit     = init->bitrev;
Packit 06404a
  DATA_TYPE *w0      = x;
Packit 06404a
  DATA_TYPE *w1      = x = w0+(n>>1);
Packit 06404a
  DATA_TYPE *T       = init->trig+n;
Packit 06404a
Packit 06404a
  do{
Packit 06404a
    DATA_TYPE *x0    = x+bit[0];
Packit 06404a
    DATA_TYPE *x1    = x+bit[1];
Packit 06404a
Packit 06404a
    REG_TYPE  r0     = x0[1]  - x1[1];
Packit 06404a
    REG_TYPE  r1     = x0[0]  + x1[0];
Packit 06404a
    REG_TYPE  r2     = MULT_NORM(r1     * T[0]   + r0 * T[1]);
Packit 06404a
    REG_TYPE  r3     = MULT_NORM(r1     * T[1]   - r0 * T[0]);
Packit 06404a
Packit 06404a
              w1    -= 4;
Packit 06404a
Packit 06404a
              r0     = HALVE(x0[1] + x1[1]);
Packit 06404a
              r1     = HALVE(x0[0] - x1[0]);
Packit 06404a
Packit 06404a
              w0[0]  = r0     + r2;
Packit 06404a
              w1[2]  = r0     - r2;
Packit 06404a
              w0[1]  = r1     + r3;
Packit 06404a
              w1[3]  = r3     - r1;
Packit 06404a
Packit 06404a
              x0     = x+bit[2];
Packit 06404a
              x1     = x+bit[3];
Packit 06404a
Packit 06404a
              r0     = x0[1]  - x1[1];
Packit 06404a
              r1     = x0[0]  + x1[0];
Packit 06404a
              r2     = MULT_NORM(r1     * T[2]   + r0 * T[3]);
Packit 06404a
              r3     = MULT_NORM(r1     * T[3]   - r0 * T[2]);
Packit 06404a
Packit 06404a
              r0     = HALVE(x0[1] + x1[1]);
Packit 06404a
              r1     = HALVE(x0[0] - x1[0]);
Packit 06404a
Packit 06404a
              w0[2]  = r0     + r2;
Packit 06404a
              w1[0]  = r0     - r2;
Packit 06404a
              w0[3]  = r1     + r3;
Packit 06404a
              w1[1]  = r3     - r1;
Packit 06404a
Packit 06404a
              T     += 4;
Packit 06404a
              bit   += 4;
Packit 06404a
              w0    += 4;
Packit 06404a
Packit 06404a
  }while(w0
Packit 06404a
}
Packit 06404a
Packit 06404a
void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
Packit 06404a
  int n=init->n;
Packit 06404a
  int n2=n>>1;
Packit 06404a
  int n4=n>>2;
Packit 06404a
Packit 06404a
  /* rotate */
Packit 06404a
Packit 06404a
  DATA_TYPE *iX = in+n2-7;
Packit 06404a
  DATA_TYPE *oX = out+n2+n4;
Packit 06404a
  DATA_TYPE *T  = init->trig+n4;
Packit 06404a
Packit 06404a
  do{
Packit 06404a
    oX         -= 4;
Packit 06404a
    oX[0]       = MULT_NORM(-iX[2] * T[3] - iX[0]  * T[2]);
Packit 06404a
    oX[1]       = MULT_NORM (iX[0] * T[3] - iX[2]  * T[2]);
Packit 06404a
    oX[2]       = MULT_NORM(-iX[6] * T[1] - iX[4]  * T[0]);
Packit 06404a
    oX[3]       = MULT_NORM (iX[4] * T[1] - iX[6]  * T[0]);
Packit 06404a
    iX         -= 8;
Packit 06404a
    T          += 4;
Packit 06404a
  }while(iX>=in);
Packit 06404a
Packit 06404a
  iX            = in+n2-8;
Packit 06404a
  oX            = out+n2+n4;
Packit 06404a
  T             = init->trig+n4;
Packit 06404a
Packit 06404a
  do{
Packit 06404a
    T          -= 4;
Packit 06404a
    oX[0]       =  MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
Packit 06404a
    oX[1]       =  MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
Packit 06404a
    oX[2]       =  MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
Packit 06404a
    oX[3]       =  MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
Packit 06404a
    iX         -= 8;
Packit 06404a
    oX         += 4;
Packit 06404a
  }while(iX>=in);
Packit 06404a
Packit 06404a
  mdct_butterflies(init,out+n2,n2);
Packit 06404a
  mdct_bitreverse(init,out);
Packit 06404a
Packit 06404a
  /* roatate + window */
Packit 06404a
Packit 06404a
  {
Packit 06404a
    DATA_TYPE *oX1=out+n2+n4;
Packit 06404a
    DATA_TYPE *oX2=out+n2+n4;
Packit 06404a
    DATA_TYPE *iX =out;
Packit 06404a
    T             =init->trig+n2;
Packit 06404a
Packit 06404a
    do{
Packit 06404a
      oX1-=4;
Packit 06404a
Packit 06404a
      oX1[3]  =  MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
Packit 06404a
      oX2[0]  = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
Packit 06404a
Packit 06404a
      oX1[2]  =  MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
Packit 06404a
      oX2[1]  = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
Packit 06404a
Packit 06404a
      oX1[1]  =  MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
Packit 06404a
      oX2[2]  = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
Packit 06404a
Packit 06404a
      oX1[0]  =  MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
Packit 06404a
      oX2[3]  = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
Packit 06404a
Packit 06404a
      oX2+=4;
Packit 06404a
      iX    +=   8;
Packit 06404a
      T     +=   8;
Packit 06404a
    }while(iX
Packit 06404a
Packit 06404a
    iX=out+n2+n4;
Packit 06404a
    oX1=out+n4;
Packit 06404a
    oX2=oX1;
Packit 06404a
Packit 06404a
    do{
Packit 06404a
      oX1-=4;
Packit 06404a
      iX-=4;
Packit 06404a
Packit 06404a
      oX2[0] = -(oX1[3] = iX[3]);
Packit 06404a
      oX2[1] = -(oX1[2] = iX[2]);
Packit 06404a
      oX2[2] = -(oX1[1] = iX[1]);
Packit 06404a
      oX2[3] = -(oX1[0] = iX[0]);
Packit 06404a
Packit 06404a
      oX2+=4;
Packit 06404a
    }while(oX2
Packit 06404a
Packit 06404a
    iX=out+n2+n4;
Packit 06404a
    oX1=out+n2+n4;
Packit 06404a
    oX2=out+n2;
Packit 06404a
    do{
Packit 06404a
      oX1-=4;
Packit 06404a
      oX1[0]= iX[3];
Packit 06404a
      oX1[1]= iX[2];
Packit 06404a
      oX1[2]= iX[1];
Packit 06404a
      oX1[3]= iX[0];
Packit 06404a
      iX+=4;
Packit 06404a
    }while(oX1>oX2);
Packit 06404a
  }
Packit 06404a
}
Packit 06404a
Packit 06404a
void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
Packit 06404a
  int n=init->n;
Packit 06404a
  int n2=n>>1;
Packit 06404a
  int n4=n>>2;
Packit 06404a
  int n8=n>>3;
Packit 06404a
  DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
Packit 06404a
  DATA_TYPE *w2=w+n2;
Packit 06404a
Packit 06404a
  /* rotate */
Packit 06404a
Packit 06404a
  /* window + rotate + step 1 */
Packit 06404a
Packit 06404a
  REG_TYPE r0;
Packit 06404a
  REG_TYPE r1;
Packit 06404a
  DATA_TYPE *x0=in+n2+n4;
Packit 06404a
  DATA_TYPE *x1=x0+1;
Packit 06404a
  DATA_TYPE *T=init->trig+n2;
Packit 06404a
Packit 06404a
  int i=0;
Packit 06404a
Packit 06404a
  for(i=0;i
Packit 06404a
    x0 -=4;
Packit 06404a
    T-=2;
Packit 06404a
    r0= x0[2] + x1[0];
Packit 06404a
    r1= x0[0] + x1[2];
Packit 06404a
    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
Packit 06404a
    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
Packit 06404a
    x1 +=4;
Packit 06404a
  }
Packit 06404a
Packit 06404a
  x1=in+1;
Packit 06404a
Packit 06404a
  for(;i
Packit 06404a
    T-=2;
Packit 06404a
    x0 -=4;
Packit 06404a
    r0= x0[2] - x1[0];
Packit 06404a
    r1= x0[0] - x1[2];
Packit 06404a
    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
Packit 06404a
    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
Packit 06404a
    x1 +=4;
Packit 06404a
  }
Packit 06404a
Packit 06404a
  x0=in+n;
Packit 06404a
Packit 06404a
  for(;i
Packit 06404a
    T-=2;
Packit 06404a
    x0 -=4;
Packit 06404a
    r0= -x0[2] - x1[0];
Packit 06404a
    r1= -x0[0] - x1[2];
Packit 06404a
    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
Packit 06404a
    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
Packit 06404a
    x1 +=4;
Packit 06404a
  }
Packit 06404a
Packit 06404a
Packit 06404a
  mdct_butterflies(init,w+n2,n2);
Packit 06404a
  mdct_bitreverse(init,w);
Packit 06404a
Packit 06404a
  /* roatate + window */
Packit 06404a
Packit 06404a
  T=init->trig+n2;
Packit 06404a
  x0=out+n2;
Packit 06404a
Packit 06404a
  for(i=0;i
Packit 06404a
    x0--;
Packit 06404a
    out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
Packit 06404a
    x0[0]  =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
Packit 06404a
    w+=2;
Packit 06404a
    T+=2;
Packit 06404a
  }
Packit 06404a
}