private float[] 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++){
                  dtmp1=w[w1];
                  dtmp2=w[w2];
                  wB=dtmp1-dtmp2;
                  x[w1]=dtmp1+dtmp2;
                  dtmp1=w[++w1];
                  dtmp2=w[++w2];
                  wA=dtmp1-dtmp2;
                  x[w1]=dtmp1+dtmp2;
                  x[w2]  =wA*AEv  - wB*AOv;
                  x[w2-1]=wB*AEv  + wA*AOv;

                  /*
                  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)*16383.0f;
            x[x2--]=(-wD+wBCO-wACE)*16383.0f;
            x[x1++]=( wD+wBCO-wACE)*16383.0f;
            x[x2--]=( wC-wACO-wBCE)*16383.0f;
         }
      }
      return x;
   }