//-------------------------------------------------------- #include "fft.h" #include //-------------------------------------------------------- /* fft_mode ビット割り当てによるモード制御 bit0 0 内部バッファ(src)をFFTクラスが自己所有とする 1 内部バッファ(src)は外部所有のポインタとして扱う */ FFT::FFT(int Bit, int fft_mode) { FFT_N = pow(2.0, FFT_BIT=Bit); if(!((mode_memo=fft_mode) & 0x01)) { src = new Vec2[FFT_N]; } sin_d = new double[FFT_N/2]; cos_d = new double[FFT_N/2]; Mask_d = new double[FFT_N]; init(); } //-------------------------------------------------------- FFT::~FFT() { if(!(mode_memo & 0x01)) { delete [] src; } delete [] sin_d; delete [] cos_d; delete [] Mask_d; } //-------------------------------------------------------- void FFT::init(void) { int m = FFT_N/2; for(int n=0; n=k) && (k != 0); j= j-k, k=k/2); if(k==0) k=1; j= j + k; } } //-------------------------------------------------------- void FFT::fft_cnv(int fdir) { int i, j, k, p, l, h, g, q; double a, b, sinp, cosp; l= FFT_N; h= 1; for(g= 1 ; g <= FFT_BIT ; g++) { l= l/2; k= 0; for(q= 1; q <= h ; q++) { p= 0; for(i= k ; i <= l+k-1 ; i++) { j= i + l; a= src[i].x - src[j].x; b= src[i].y - src[j].y; src[i].x = src[i].x + src[j].x; src[i].y = src[i].y + src[j].y; if(p== 0) { src[j].x = a; src[j].y= b; } else { cosp= cosf(p); sinp= (fdir>0)? sinf(p) : -sinf(p); src[j].x = a*cosp + b*sinp; src[j].y = b*cosp - a*sinp; } p= p + h; } k= k + l + l; } h= h + h; } bit_rev(); } //---------------------------------------------------- //現在のマスクをかける void FFT::MaskExe(void) { if(Mask != MDoNothing) { for(int i=0; i #include //-------------------------------------------------------- /*実数領域のみを定義してフーリエ変換する  信号は区切りの良い連続波としてあたえスペクトルを知るための検査 窓関数による最終補正も検査する DoNothing,Hummingのみ試験した */ void fft_test01(void) { class FFT f32(5); //32 V2D v2a[32]; for(int n=0; n<32; n++) { v2a[n] = V2D( 1.0 +3.0*cos(2.0*PI*4.0*n/32.0) +0.5*sin(2.0*PI*7.0*n/32.0) +0.75*sin(2.0*PI*16.0*n/32.0) +0.25*cos(2.0*PI*16.0*n/32.0) , 0.0); } //DoNothing for(int n=0; n<32; n++) f32.src[n] = v2a[n]; WriteCSV("fft_test01_src.txt", f32.src, 32); f32.fft_cnv(); WriteCSV("fft_test01_des.txt", f32.src, 32); f32.SpecComp(); //前半分の領域にスペクトルが表現される WriteCSV("fft_test01_spec.txt", f32.src, 17); //参考 http://www.madlabo.com/mad/edat/mathematic/fft/index.htm //真ん中は17個目となる FFT_N/2+1 //Humming窓 for(int n=0; n<32; n++) f32.src[n] = v2a[n]; f32.Humming(); f32.MaskExe(); WriteCSV("fft_test01_specHumming1.txt", f32.src, 32); f32.fft_cnv(); f32.SpecComp(); //前半分の領域にスペクトルが表現される WriteCSV("fft_test01_specHumming2.txt", f32.src, 17); } //-------------------------------------------------------- void fft_test02(void) //FFT、逆FFTの検査 { class FFT f32(5); //32 V2D v2a[32]; for(int n=0; n<32; n++) { v2a[n] = V2D( 1.0 +3.0*cos(2.0*PI*4.0*n/32.0) +0.5*sin(2.0*PI*7.0*n/32.0) +0.75*sin(2.0*PI*16.0*n/32.0) +0.25*cos(2.0*PI*16.0*n/32.0) , 0.0); } v2a[10].x = 10; //印をつけておく //DoNothing for(int n=0; n<32; n++) f32.src[n] = v2a[n]; WriteCSV("fft_test02_src.txt", f32.src, 32); f32.fft_cnv(); f32.fft_cnv(-1); f32.RevComp(); WriteCSV("fft_test02_des.txt", f32.src, 32); } //-------------------------------------------------------- //速度検査 class FFT fsp(16); V2D v2a[65536]; void fft_test03(void) { //Init int Fbit = 20; int FSiz = 65536; for(int n=0; n