diff options
Diffstat (limited to 'common/fft.cpp')
-rw-r--r-- | common/fft.cpp | 145 |
1 files changed, 98 insertions, 47 deletions
diff --git a/common/fft.cpp b/common/fft.cpp index b5e3d9a21e..2ed9b97edc 100644 --- a/common/fft.cpp +++ b/common/fft.cpp @@ -29,6 +29,7 @@ #include "common/cosinetables.h" #include "common/fft.h" #include "common/util.h" +#include "common/textconsole.h" namespace Common { @@ -45,6 +46,13 @@ FFT::FFT(int bits, int inverse) : _bits(bits), _inverse(inverse) { for (int i = 0; i < n; i++) _revTab[-splitRadixPermutation(i, n, _inverse) & (n - 1)] = i; + + for (int i = 0; i < ARRAYSIZE(_cosTables); i++) { + if (i+4 <= _bits) + _cosTables[i] = new Common::CosineTable(i+4); + else + _cosTables[i] = 0; + } } FFT::~FFT() { @@ -162,7 +170,7 @@ PASS(pass) #define BUTTERFLIES BUTTERFLIES_BIG PASS(pass_big) -static void fft4(Complex *z) { +void FFT::fft4(Complex *z) { float t1, t2, t3, t4, t5, t6, t7, t8; BF(t3, t1, z[0].re, z[1].re); @@ -175,7 +183,7 @@ static void fft4(Complex *z) { BF(z[2].im, z[0].im, t2, t5); } -static void fft8(Complex *z) { +void FFT::fft8(Complex *z) { float t1, t2, t3, t4, t5, t6, t7, t8; fft4(z); @@ -194,15 +202,15 @@ static void fft8(Complex *z) { TRANSFORM(z[1], z[3], z[5], z[7], sqrthalf, sqrthalf); } -static void fft16(Complex *z) { +void FFT::fft16(Complex *z) { float t1, t2, t3, t4, t5, t6; fft8(z); fft4(z + 8); fft4(z + 12); - Common::CosineTable c(4); - const float * const cosTable = c.getTable(); + assert(_cosTables[0]); + const float * const cosTable = _cosTables[0]->getTable(); TRANSFORM_ZERO(z[0], z[4], z[8], z[12]); TRANSFORM(z[2], z[6], z[10], z[14], sqrthalf, sqrthalf); @@ -210,109 +218,152 @@ static void fft16(Complex *z) { TRANSFORM(z[3], z[7], z[11], z[15], cosTable[3], cosTable[1]); } -static void fft32(Complex *z) { +void FFT::fft32(Complex *z) { fft16(z); fft8(z + 8 * 2); fft8(z + 8 * 3); - Common::CosineTable table(5); - pass(z, table.getTable(), 8 / 2); + assert(_cosTables[1]); + pass(z, _cosTables[1]->getTable(), 8 / 2); } -static void fft64(Complex *z) { +void FFT::fft64(Complex *z) { fft32(z); fft16(z + 16 * 2); fft16(z + 16 * 3); - Common::CosineTable table(6); - pass(z, table.getTable(), 16 / 2); + assert(_cosTables[2]); + pass(z, _cosTables[2]->getTable(), 16 / 2); } -static void fft128(Complex *z) { +void FFT::fft128(Complex *z) { fft64(z); fft32(z + 32 * 2); fft32(z + 32 * 3); - Common::CosineTable table(7); - pass(z, table.getTable(), 32 / 2); + assert(_cosTables[3]); + pass(z, _cosTables[3]->getTable(), 32 / 2); } -static void fft256(Complex *z) { +void FFT::fft256(Complex *z) { fft128(z); fft64(z + 64 * 2); fft64(z + 64 * 3); - Common::CosineTable table(8); - pass(z, table.getTable(), 64 / 2); + assert(_cosTables[4]); + pass(z, _cosTables[4]->getTable(), 64 / 2); } -static void fft512(Complex *z) { +void FFT::fft512(Complex *z) { fft256(z); fft128(z + 128 * 2); fft128(z + 128 * 3); - Common::CosineTable table(9); - pass(z, table.getTable(), 128 / 2); + assert(_cosTables[5]); + pass(z, _cosTables[5]->getTable(), 128 / 2); } -static void fft1024(Complex *z) { +void FFT::fft1024(Complex *z) { fft512(z); fft256(z + 256 * 2); fft256(z + 256 * 3); - Common::CosineTable table(10); - pass_big(z, table.getTable(), 256 / 2); + assert(_cosTables[6]); + pass_big(z, _cosTables[6]->getTable(), 256 / 2); } -static void fft2048(Complex *z) { +void FFT::fft2048(Complex *z) { fft1024(z); fft512(z + 512 * 2); fft512(z + 512 * 3); - Common::CosineTable table(11); - pass_big(z, table.getTable(), 512 / 2); + assert(_cosTables[7]); + pass_big(z, _cosTables[7]->getTable(), 512 / 2); } -static void fft4096(Complex *z) { +void FFT::fft4096(Complex *z) { fft2048(z); fft1024(z + 1024 * 2); fft1024(z + 1024 * 3); - Common::CosineTable table(12); - pass_big(z, table.getTable(), 1024 / 2); + assert(_cosTables[8]); + pass_big(z, _cosTables[8]->getTable(), 1024 / 2); } -static void fft8192(Complex *z) { +void FFT::fft8192(Complex *z) { fft4096(z); fft2048(z + 2048 * 2); fft2048(z + 2048 * 3); - Common::CosineTable table(13); - pass_big(z, table.getTable(), 2048 / 2); + assert(_cosTables[9]); + pass_big(z, _cosTables[9]->getTable(), 2048 / 2); } -static void fft16384(Complex *z) { +void FFT::fft16384(Complex *z) { fft8192(z); fft4096(z + 4096 * 2); fft4096(z + 4096 * 3); - Common::CosineTable table(14); - pass_big(z, table.getTable(), 4096 / 2); + assert(_cosTables[10]); + pass_big(z, _cosTables[10]->getTable(), 4096 / 2); } -static void fft32768(Complex *z) { +void FFT::fft32768(Complex *z) { fft16384(z); fft8192(z + 8192 * 2); fft8192(z + 8192 * 3); - Common::CosineTable table(15); - pass_big(z, table.getTable(), 8192 / 2); + assert(_cosTables[11]); + pass_big(z, _cosTables[11]->getTable(), 8192 / 2); } -static void fft65536(Complex *z) { +void FFT::fft65536(Complex *z) { fft32768(z); fft16384(z + 16384 * 2); fft16384(z + 16384 * 3); - Common::CosineTable table(16); - pass_big(z, table.getTable(), 16384 / 2); + assert(_cosTables[12]); + pass_big(z, _cosTables[12]->getTable(), 16384 / 2); } -static void (* const fft_dispatch[])(Complex *) = { - fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, - fft2048, fft4096, fft8192, fft16384, fft32768, fft65536 -}; - void FFT::calc(Complex *z) { - fft_dispatch[_bits - 2](z); + switch (_bits) { + case 2: + fft4(z); + break; + case 3: + fft8(z); + break; + case 4: + fft16(z); + break; + case 5: + fft32(z); + break; + case 6: + fft64(z); + break; + case 7: + fft128(z); + break; + case 8: + fft256(z); + break; + case 9: + fft512(z); + break; + case 10: + fft1024(z); + break; + case 11: + fft2048(z); + break; + case 12: + fft4096(z); + break; + case 13: + fft8192(z); + break; + case 14: + fft16384(z); + break; + case 15: + fft32768(z); + break; + case 16: + fft65536(z); + break; + default: + error("Should Not Happen!"); + } } } // End of namespace Common |