FFT,IFFTが動かない – プログラミング – Home

通知
すべてクリア

FFT,IFFTが動かない


すみ
 すみ
(@すみ)
ゲスト
結合: 22年前
投稿: 6
Topic starter  

なぜだろう。
波形のデータをスペクトルに(FFT)、
再度スペクトルのデータを波形に(IFFT)すれば、
元に戻るはずなのに、
ぜんぜんでたらめな値。
実際は、下記でいうとdata0のベクトルとdata2のベクトルが
完全にではないにしても、ほぼ、一緒のトレンドでないといけないのに。。。

typedef struct
{
double r;
double i;
}complex;

int N = 512;
int TotalLen = 32000;
int HOver_Wrp = 350;
int i,j;
int ip;
int r;
int p;
int j1,j2;
int k;
int k1;
double a,b;
double c,s;
int bit;
double deg;
double arg;

double *ab;
double *in;

double q;
int flag;
int L;

ab = (double *) malloc(500*512 * sizeof(double));
if (ab == NULL)
{
printf(Sorry! Memory cannot be secured ! \n);
exit(11);
}

in = (double *) malloc(400*512 * sizeof(double));
if (in == NULL)
{
printf(Sorry! Memory cannot be secured ! \n);
exit(11);
}

// FFT

for (L=0;L<(TotalLen/(512-HOvr_Wrp));L++)
{
   r = 0;
ip = N - 1;
while (ip > 0)
{
ip >>= 1;
r++;
}
deg = 2.0*3.1414/N;

j2 = N;
k = 0;
j1 = r - 1;
for (j=0;j<r;j++)
{
j2 = j2/2;
for(;;)
{
for (ip=0;ip<j2;ip++)
{
p = k >> j1;
bit = fft_bitr(p,r);
arg = deg*bit;
c = cos(arg);
s = sin(arg);
k1 = k + j2;
a = data0[L*512+k1].r * c + data0[L*512+k1].i * s;
b = data0[L*512+k1].i * c - data0[L*512+k1].r * s;
data0[L*512+k1].r = data0[L*512+k].r - a;
data0[L*512+k1].i = data0[L*512+k].i - b;
data0[L*512+k].r = data0[L*512+k].r + a;
data0[L*512+k].i = data0[L*512+k].i + b;
k++;
}
k += j2;
if (k >= N)
break;
}
k = 0;
j1--;
}

for (k=0;k<N;k++)
{
bit = fft_bitr(k, r);
if (bit > k)
{
fft_swap(&data0[L*512+k],&data0[L*512+bit]);
}
}

for (ip=0;ip<N;ip++)
{
data1[L*512+ip].r = data0[L*512+ip].r;
data1[L*512+ip].i = data0[L*512+ip].i;

}
}

// IFFT

for (L=0;L<(TotalLen/(512-HOvr_Wrp));L++)
{
r = 0;
i = N - 1;
while (i > 0)
{
i >>= 1;
r++;
}
deg = 2.0*3.1414/N;

j2 = N;
k = 0;
j1 = r - 1;
for (j=0;j<r;j++)
{
j2 = j2/2;
for(;;)
{
for (i=0;i<j2;i++)
{
p = k >> j1;
bit = fft_bitr(p,r);
arg = -deg*bit; // Inverse this polality for IFFT
c = cos(arg);
a = sin(arg);
k1 = k + j2;
a = data1[L*512+k1].r * c + data1[L*512+k1].i * s;
b = data1[L*512+k1].i * c - data1[L*512+k1].r * s;
data1[L*512+k1].r = data1[L*512+k].r - a;
data1[L*512+k1].i = data1[L*512+k].i - b;
data1[L*512+k].r = data1[L*512+k].r + a;
data1[L*512+k].i = data1[L*512+k].i + b;
k++;
}
k += j2;
if (k >= N)
break;
}
k = 0;
j1--;
}

for (k=0;k<N;k++)
{
bit = fft_bitr(k, r);
if (bit > k)
{
fft_swap(&data1[L*512+k],&data1[L*512+bit]);
}
}

for (i=0;i<N;i++)
{
data1[L*512+i].r = (data1[L*512+i].r)/N;
data1[L*512+i].i = (data1[L*512+i].i)/N;
}

for (i=0;i<N;i++)
{
data2[L*512+i].r = data1[L*512+i].r;
data2[L*512+i].i = data1[L*512+i].i;
ab[L*512+i] = pow((pow((data2[L*512+i].r),2)+pow((data2
[L*512+i].i),2)),0.5);
HVec[L*512+i] = ab[L*512+i];

}
}


引用解決済
トピックタグ
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 22年前
投稿: 310
 

オーバーフロー・アンダーフローしている可能性は?
あと念のため開発環境も明示したほうが良いと思います。


返信引用
すみ
 すみ
(@すみ)
ゲスト
結合: 22年前
投稿: 6
Topic starter  

お返事ありがとうございます。
data2[]の乗数を調整したりしてもみたのですが、
アンダーフロー、オーバーフローしていないことも確かめました。

この関数の入れ方としては

int P;
double Data[200*512];
complex Da[200*512];
static int Sp[600*512];
static int SpM[600*512];
static complex Tra[100*512];
int FNoR;
double Vec[200][512];
int St;
static int Ovr_Wrp = 350;
int N;

for (P=0;P<(200*512);P++)
{
Da[P].r = Data[P];
Da[P].i = 0;
}

WAV_SPEC(Tra, Da, Sp, SpM, FNoR, N, Vec, St, Ovr_Wp);
で上記の関数を呼んで、

呼ばれる関数は、
AAANoiseEli(complex HTran[], complex data0[], complex data1[], complex data2
[], int HFrameNo, int N, double *HVec, int HStart, int HOvr_Wrp)
にしており、
入力側では、
Data[]のベクトルが、
入力として入り、
出力のdata2[]が同じようになっていないかどうかを確認しています。

結果は、まったく、入力側のdata[]のトレンドとは
一致しないものに、上下に激しくスイングしている乱数になっていました。
ふつうは、入力側のdata0[]がsinカーブでスイングすれば、
出力側のdata2[]も、ほぼ同じようなsinカーブで、
また、
data0[]が矩形波でスイングすれば、
出力側のdata2[]も、ほぼ同じような矩形波で
スイングするはずなのに。。。

スイングすれば、
環境は、WINDOWS XPでのVC++6です。

ちなみに、
中で使っているサブ関数は、下記です。

fft_bitr (int bit, int r)
{
int i;
int bitr;

bitr = 0;
for (i=0;i<r;i++)
{
bitr <<= 1;
bitr |= (bit&1);
bit >>= 1;
}

return (bitr);
}

fft_swap (complex *data0, complex *data1)
{
double a;

a = data0->r;
data0->r = data1->r;
data1->r = a;
a = data0->i;
data0->i = data1->i;
data1->i = a;

return 0;
}


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

FFTの入力としてたとえばsine-waveを与えたとき、
結果として鋭いピークが得られますか?


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました