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);
    }