private static void Butterfly(Complex *inp, Complex *outp, int stageSize, int len) { var w = TwiddleFactors.Factors[stageSize]; var s2 = stageSize / 2; Complex x = new Complex(); for (int n = 0; n < len; n += stageSize) { var lower = &inp[n]; var upper = &inp[n + s2]; var outLower = &outp[n]; var outhigher = &outp[n + s2]; for (int i = 0; i < s2; i++) { outLower[i] = lower[i]; outhigher[i] = lower[i]; } for (int i = 0; i < s2; i++) { Complex.Multiply(ref x, ref upper[i], ref w[i]); Complex.Add(ref outLower[i], ref x); Complex.Subtract(ref outhigher[i], ref x); } } }
public static void FFT(Complex *input, Complex *output, Complex *scratchpad, int len) { if (len == 1) { output[0] = input[0]; return; } else if (len == 2) { output[0] = input[0]; output[1] = input[0]; Complex.Add(ref output[0], ref input[1]); Complex.Subtract(ref output[1], ref input[1]); return; } // we use the output buffer and another buffer called scratchpad to work on the // signals. Input signal never gets modified Complex *A = output; Complex *B = scratchpad; var bitMap = BitReverse.Tables[len]; for (int i = 0; i < len; i++) { A[i] = input[bitMap[i]]; } Butterfly2(A, B, len); Swap(ref A, ref B); Butterfly4(A, B, len); if (len == 4) { goto end; } Swap(ref A, ref B); Butterfly8(A, B, len); int butterflySize = 8; while (true) { butterflySize *= 2; if (butterflySize > len) { break; } Swap(ref A, ref B); Butterfly(A, B, butterflySize, len); } end: // copy output to the correct buffer if (B != output) { for (int i = 0; i < len; i++) { output[i] = B[i]; } } }