「FFTによる直線たたみ込み」に要する時間は?
0. myFFT.cpp内の訂正
CFir::multi_FFT_results( double* src, double*
dest, int number_of_spectrum )
複素数の積は (a+bi)*(c+di)=ac-bd +(ad+bc)i
/*for(i=0;i<2*number_of_spectrum;i++)//これは間違い
dest[i]=src[i]*dest[i];*/
正しくは
for(i=0;i<number_of_spectrum;i++)
{
dest[2*i]
= src[2*i] * dest[2*i]
- src[2*i+1] * dest[2*i+1];
dest[2*i+1] = src[2*i] *
dest[2*i+1] + src[2*i+1] * dest[2*i];
}
スマソ。
1.「FFTによる直線たたみ込み」は、速い!
上図は、
captureData数: 2048 point
フィルタ係数 : 2001 point
FFTポイント数: 8192 point
を、通常のたたみ込みではなくて、「FFTによる直線たたみ込み」を、用いた結果です。 ( Celeron 2.53GHz )
所要時間 約 15ms ! ほんまかいな....
時間の計測には、::timeGettime 関数(winmm.lib)を用いましたが、テストプログラムが間違うてるん、ちゃうかいな...不安。
start = captureData (float)を、doubleに、変換し始める時
続いて、
窓関数による、窓処理 -->8192pointのFFT --> 予め windowed FFTされたフィルタ係数との、積 -->
-->逆FFT --> 逆window
stop = capture_dataの長さ分だけの実数部分を、取りだし終わる時。
今度は FFT point数を倍の 16384 pointにて観測。
スピードは、変わらん。
次は データ数を倍の 4096pointに変更。
変わらん。 16ms。
次は、FFTpoint数を、いっきょに、 131072pointに増やす。
これで、 94ms 掛かった。充分速いと、思います。
capture point数、coef_point数には、あんまし、関係ない模様です。
たまに、計測時間がゼロになったりします....それは、ないやろ...多分、キャッシュが効いてるのでは...ぶつぶつ。
プログラムは、最適化は、していません。無効 (/Od)
2.FFTプログラムと、Fir作成プログラムのクラス化、及び、DLL化
これらは、同時に使う事が多いので、同じDLLに、収めました。クラスも、DLL化できるんや....チュートリアルを読むまで、知らんかったわ....
FFTプログラムは、大浦様の CDFTを使用。
FirFilterの窓関数法による作成は、「ディジタサウンド処理入門 青木直史先生 CQ出版」に、やさしく、詳しく、書いてありました。
この両者を合体したDLLを、作成致しました。
ダイナミックリンクライブラリーの作り方は、以下を、参考にしてください。
上の部分が FFT関係、下が FirFilter作成と、それを操作する関数です。
func_noとは、窓関数の番号です。= number_of_WindowFunc. 作った本人も、すぐ忘れる...何とかならんかいな...(^_^;;
DLL化するには、以下の、2つのファイルが、必要です。
まだ、未完成ですが、hファイル、cppファイル に置いておきます。参考になりましたら、うれしいです。汚いから、笑わんといてや...
これを、テストするプログラムは、まあ、こんな感じです。
これを、PortAudioと、まず、合体せねば...
そうそう、PortAudioのプログラミングは、JI3GABさんのDSsbPプログラムが、大いに参考になりました。御礼申し上げます。
H.18.12.6 (20061206)