private float[] mdct_kernel(float[] x, float[] w, int n, int n2, int n4,
      int n8){
    // step 2

    int xA=n4;
    int xB=0;
    int w2=n4;
    int A=n2;

    for(int i=0; i<n4;){
      float x0=x[xA]-x[xB];
      float x1;
      w[w2+i]=x[xA++]+x[xB++];

      x1=x[xA]-x[xB];
      A-=4;

      w[i++]=x0*trig[A]+x1*trig[A+1];
      w[i]=x1*trig[A]-x0*trig[A+1];

      w[w2+i]=x[xA++]+x[xB++];
      i++;
    }

    // step 3

    {
      for(int i=0; i<log2n-3; i++){
        int k0=n>>>(i+2);
        int k1=1<<(i+3);
        int wbase=n2-2;

        A=0;
        float[] temp;

        for(int r=0; r<(k0>>>2); r++){
          int w1=wbase;
          w2=w1-(k0>>1);
          float AEv=trig[A], wA;
          float AOv=trig[A+1], wB;
          wbase-=2;

          k0++;
          for(int s=0; s<(2<<i); s++){
            wB=w[w1]-w[w2];
            x[w1]=w[w1]+w[w2];

            wA=w[++w1]-w[++w2];
            x[w1]=w[w1]+w[w2];

            x[w2]=wA*AEv-wB*AOv;
            x[w2-1]=wB*AEv+wA*AOv;

            w1-=k0;
            w2-=k0;
          }
          k0--;
          A+=k1;
        }

        temp=w;
        w=x;
        x=temp;
      }
    }

    // step 4, 5, 6, 7
    {
      int C=n;
      int bit=0;
      int x1=0;
      int x2=n2-1;

      for(int i=0; i<n8; i++){
        int t1=bitrev[bit++];
        int t2=bitrev[bit++];

        float wA=w[t1]-w[t2+1];
        float wB=w[t1-1]+w[t2];
        float wC=w[t1]+w[t2+1];
        float wD=w[t1-1]-w[t2];

        float wACE=wA*trig[C];
        float wBCE=wB*trig[C++];
        float wACO=wA*trig[C];
        float wBCO=wB*trig[C++];

        x[x1++]=(wC+wACO+wBCE)*.5f;
        x[x2--]=(-wD+wBCO-wACE)*.5f;
        x[x1++]=(wD+wBCO-wACE)*.5f;
        x[x2--]=(wC-wACO-wBCE)*.5f;
      }
    }
    return (x);
  }