00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <math.h>
00022 #include "dsputil.h"
00023
00029
00030 DECLARE_ALIGNED_16(FFTSample, ff_sin_16[8]);
00031 DECLARE_ALIGNED_16(FFTSample, ff_sin_32[16]);
00032 DECLARE_ALIGNED_16(FFTSample, ff_sin_64[32]);
00033 DECLARE_ALIGNED_16(FFTSample, ff_sin_128[64]);
00034 DECLARE_ALIGNED_16(FFTSample, ff_sin_256[128]);
00035 DECLARE_ALIGNED_16(FFTSample, ff_sin_512[256]);
00036 DECLARE_ALIGNED_16(FFTSample, ff_sin_1024[512]);
00037 DECLARE_ALIGNED_16(FFTSample, ff_sin_2048[1024]);
00038 DECLARE_ALIGNED_16(FFTSample, ff_sin_4096[2048]);
00039 DECLARE_ALIGNED_16(FFTSample, ff_sin_8192[4096]);
00040 DECLARE_ALIGNED_16(FFTSample, ff_sin_16384[8192]);
00041 DECLARE_ALIGNED_16(FFTSample, ff_sin_32768[16384]);
00042 DECLARE_ALIGNED_16(FFTSample, ff_sin_65536[32768]);
00043 FFTSample *ff_sin_tabs[] = {
00044 ff_sin_16, ff_sin_32, ff_sin_64, ff_sin_128, ff_sin_256, ff_sin_512, ff_sin_1024,
00045 ff_sin_2048, ff_sin_4096, ff_sin_8192, ff_sin_16384, ff_sin_32768, ff_sin_65536,
00046 };
00047
00048 av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans)
00049 {
00050 int n = 1 << nbits;
00051 int i;
00052 const double theta = (trans == RDFT || trans == IRIDFT ? -1 : 1)*2*M_PI/n;
00053
00054 s->nbits = nbits;
00055 s->inverse = trans == IRDFT || trans == IRIDFT;
00056 s->sign_convention = trans == RIDFT || trans == IRIDFT ? 1 : -1;
00057
00058 if (nbits < 4 || nbits > 16)
00059 return -1;
00060
00061 if (ff_fft_init(&s->fft, nbits-1, trans == IRDFT || trans == RIDFT) < 0)
00062 return -1;
00063
00064 s->tcos = ff_cos_tabs[nbits-4];
00065 s->tsin = ff_sin_tabs[nbits-4]+(trans == RDFT || trans == IRIDFT)*(n>>2);
00066 for (i = 0; i < (n>>2); i++) {
00067 s->tcos[i] = cos(i*theta);
00068 s->tsin[i] = sin(i*theta);
00069 }
00070 return 0;
00071 }
00072
00077 void ff_rdft_calc_c(RDFTContext* s, FFTSample* data)
00078 {
00079 int i, i1, i2;
00080 FFTComplex ev, od;
00081 const int n = 1 << s->nbits;
00082 const float k1 = 0.5;
00083 const float k2 = 0.5 - s->inverse;
00084 const FFTSample *tcos = s->tcos;
00085 const FFTSample *tsin = s->tsin;
00086
00087 if (!s->inverse) {
00088 ff_fft_permute(&s->fft, (FFTComplex*)data);
00089 ff_fft_calc(&s->fft, (FFTComplex*)data);
00090 }
00091
00092
00093 ev.re = data[0];
00094 data[0] = ev.re+data[1];
00095 data[1] = ev.re-data[1];
00096 for (i = 1; i < (n>>2); i++) {
00097 i1 = 2*i;
00098 i2 = n-i1;
00099
00100 ev.re = k1*(data[i1 ]+data[i2 ]);
00101 od.im = -k2*(data[i1 ]-data[i2 ]);
00102 ev.im = k1*(data[i1+1]-data[i2+1]);
00103 od.re = k2*(data[i1+1]+data[i2+1]);
00104
00105 data[i1 ] = ev.re + od.re*tcos[i] - od.im*tsin[i];
00106 data[i1+1] = ev.im + od.im*tcos[i] + od.re*tsin[i];
00107 data[i2 ] = ev.re - od.re*tcos[i] + od.im*tsin[i];
00108 data[i2+1] = -ev.im + od.im*tcos[i] + od.re*tsin[i];
00109 }
00110 data[2*i+1]=s->sign_convention*data[2*i+1];
00111 if (s->inverse) {
00112 data[0] *= k1;
00113 data[1] *= k1;
00114 ff_fft_permute(&s->fft, (FFTComplex*)data);
00115 ff_fft_calc(&s->fft, (FFTComplex*)data);
00116 }
00117 }
00118
00119 void ff_rdft_calc(RDFTContext *s, FFTSample *data)
00120 {
00121 ff_rdft_calc_c(s, data);
00122 }
00123
00124 av_cold void ff_rdft_end(RDFTContext *s)
00125 {
00126 ff_fft_end(&s->fft);
00127 }