FFT DLLの公開

FFT(高速フーリエ変換)の機能を搭載したDLLを公開しています。
卒業研究のお供にご使用ください

1.簡単な使い方
2.理論
3.質問等

ダウンロード

*このソフトウエアは無償で公開されています。サポートについてはこちらをご覧下さい
有償サポートを希望の方は別途こちらからお問い合わせください。

1.簡単な使い方
2.理論
========================================================================
       MICROSOFT FOUNDATION CLASS ライブラリ : CalFFT
========================================================================

1.エクスポート関数定義

下記にC関数としてのエクスポート関数を示します

Long fft1dim( long number,  //データ数
    double dt  //サンプリング間隔
    double* re,  //実数データ
    double* im,  //虚数データ
    long process, //処理分岐フラグ
    long window,  //ウィンドウ関数フラグ
    double LowFrq,  //バンドパス時最低周波数
    double HighFrq  //バンドパス時最高周波数
    )

2.VBによるインポート宣言

下記にVBによる関数のインポート宣言を示します
(VBでの宣言はこのreadme.txtの最後の付録を使用すると便利です)

declare function fft1dim lib "CalFFT.DLL" (  byval data_number as long,
      byval dt as double,
      re as double,
      im as double,
      byval process as long,
      byval window as long,
      byval LowFrq as double,
      byval HighFrq as double
      ) as Long

 第一引数:data_number 全データ数を指定して下さい
 第二引数:dt  サンプリング間隔
 第三引数:re  実数データ配列のポインタ(例:real() )
 第四引数:im  虚数データ配列のポインタ=通常全て0
 第五引数:process 処理分岐フラグ(詳細は3章)
 第六引数:window 窓関数フラグ(詳細は4章)
 第七引数:LowFrq 最低周波数(バンドパス時のみ有効:省略可)
 第八引数:HighFrq 最高周波数(バンドパス時のみ有効:省略可)

 戻り値:処理結果 正常=0、異常=0以外
      異常時の値
      1=計算に必要なメモリ空間を確保できませんでした
      2=FFT演算を行う配列がプログラム空間内に収まって
       いません

3.処理分岐フラグ

下記に処理分岐フラグの詳細を示す

 1=パワースペクトル :実数配列にパワースペクトルを格納して終了します
 2=フェイズ  :実数配列に位相情報を格納して終了します
 3=フーリエ変換 :実数配列と虚数配列に変換データを格納します
 4=バンドパスフィルター:最低周波数から最高周波数までを残します
 5=パワースペクトル :実数配列にパワースペクトルを格納して終了します
     (自動的に移動平均により平滑化を行います)

4.窓関数フラグ

下記に窓関数フラグを示します
※全ての処理分岐で有効となりますが、バンドパスフィルター使用時は、
  0を指定することを推奨します

 0=窓関数なし  :特殊な窓関数を適用しません
 1=ハニングウィンドウ :0.5 - 0.5 * cos(2πft)
 2=ハミングウィンドウ :0.54 - 0.46 * cos(2πft)
 3=ブラックマンハリス :0.42 - 0.5 * cos(2πft) + 0.08 * cos(2*2πft)

  パワースペクトル計算時は”1”を推奨します
 バンドパス計算時は”0”を推奨します

 ※上記以外の数値を指定すると”0”指定とみなします

注意事項

CalFFTの関数呼び出し時には以下の点に注意して下さい

 1.配列数は必ず「2のN乗」の数を確保して下さい。

 例)3000点のデータを処理したい場合
   EXP = Log(3000)/Log(2)
   EXP = 11.550
   整数にならないので、
   EXP = 12
   とします。
   配列は
   DN = 2^12
   DIM XR(DN) AS DOUBLE
   確保して下さい。

   但し、関数に渡す引数は3000を渡して下さい

    Call fft1dim(3000, dt, re(0), im(0), 1, 1, 0, 0)1

 2.本DLLではFFT計算前に平均値を除去します
 
 その為、配列の0番目の値が他のフーリエ変換のプログラム
 の値と異なる場合があります

 3.パワースペクトルの結果

 パワースペクトルの結果は0番目でなく、1番目からN/2番目
 までを参照して下さい

 例)8点の場合
  0,1,2,3,4,5,6,7(配列の添字)
  ↓
  1,2,3,4 を参照して下さい
  1番目が基本周波数の値

付録1

declare function fft1dim lib "CalFFT.DLL" ( byval data_number as long, byval dt as double, re as double, im as double, byval process as Long, byval window as Long, byval LowFrq as double, byval HighFrq as double) as Long

 例)パワースペクトル
  dim re(512) as double
  dim im(512) as double

  '配列にデータを設定します

    fft1dim(512, 0.1, re(0), im(0), 1, 1, 0, 0)
  '配列 re()はパワースペクトルが格納されています

 例)バンドパスフィルター
  dim re(512) as double
  dim im(512) as double

  '配列にデータを設定します

    fft1dim(512, 0.1, re(0), im(0), 4, 0, 100, 500)
  '配列 re()は100Hzから500Hz以外が除去された配列が格納されます

付録2

 FFT演算に必要な配列サイズを取得するエクスポート関数を追加しました。

 __declspec(dllexport) long GetMaxSize(long ldn);
 がその機能に相当します。

 declare function GetMaxSize lib "CalFFT.DLL" (  ByVal ldn As Long ) as Long

 を使用してプロジェクトにインポートして活用して下さい。

付録3
 FFTをかける前のデータに対して、平均値除去を行っております。
 従って、平均値分、出力結果がシフトします。
 
5.転載及び著作権について

 CalFFT.dll はフリーソフトウェアです。商用目的ではない,使用,転載,及
び配布に関しては特に制限は付けません。ただし,転載・配布する場合に,メディ
ア代等以上の手数料を徴収したり,使用に制限を付けることはこれを禁じます。
また,転載・配布時に書庫ファイル及び格納ファイルを改変することも,これを
禁じます。

 転載時には,事後でも構いませんので私まで連絡をお願いします。

 書籍等への収録やソフトへのバンドルなど,商用利用には条件がありますので,
必ず事前に連絡をお願いします。企業等での業務利用や商用利用のソフトでの使
用を前提とした転載もこれに含みます。これらの掲載・収録・バンドル等の場合
は,必要な場合はライブラリがUPされていたネットのライブラリ管理者にも必
ず連絡をお願いします。

6.免責

 これらのプログラムの使用によって生じた損害等については,作者及び原著作
者は何も保証する義務を負わないこととさせていただきます。

 

3.質問等
Q
FFTのdllをもらいました.
ありがとうございました.
それで、マイクから音を入力して、
その音をFFTしました.
そして、それをリアルタイムにスペクトル表示したいのですが
どうしたらよいか分かりません.
時間がなくて困っているので
どうかお願いします.

A
既に、マイクから音を入力してFFTしたと言うのであれば
特に現在ある物で作れると思いますよ。
(マイクから音をリアルタイムに入れるocxについては現在公開しておりません)
順序的には
1.マイクから音を取り込む
2.Waveファイルをテキストファイルへ変換する
3.FFTをかける
4.グラフとして表示する
5.決めた時間間隔で繰り返す

となります。
Q
FFT DLLファイルをダウンロードさせていただきました。
有り難うございます。
ところが、このファイルはどこに置いていいのか?
時時VBはDLL見つけないのmessagebox出てくる。
DLLファイルはコンポーネントに挿入ことが出来ませんが。
宜しくお願いします。

A
Windows\systemフォルダ、若しくはexeファイルの置いてあるフォルダに置いて下
さい
前者が推奨です。dllはWindowsに登録をしないと使えないので、
それでも使えない場合は
現在”みきの道具箱”というソフトを公開しているのですが
そのソフトをインストールしてdllファイルをエクスプローラーで右クリックすると
簡単に登録・解除を行うことが出来ます。

Q
私は今使ってるのPCはWIN2000.
WINNT¥system とWINNT¥system32 二つのフォルダがありますから、とっちに置い
でばいいですか?
あと、この操作することは”登録”と言うことですか?

A
Windows2000の場合は
WINNT¥system32 
に入れて下さい
>あと、この操作することは”登録”と言うことですか?
>宜しくお願い致します。
格納するだけで十分です

Q
あるサンプルデータをFFTして周波数領域にし、
周波数領域のデータに逆FFTをかけ元のサンプルデータ
を再現することはできました。
あとは周波数領域のデータをいじればいいのかと思うんですが
、、、ひとつ疑問がでてきました。
例えば128個のサンプルデータをFFTする場合、周波数データは
64個しか得られないはずです(ナイキスト定理)。
しかし、それでは128個のデータを再現できません。
、、ので、私は128個のデータをFFTし128個の
周波数データを計算させ、それを逆FFTしています。
しかし、それは上記のナイキスト定理に反しますし、
不自然です。
A
定理の内容が違いませんか?
「ナイキスト定理」は簡単に言って、「サンプリング周波数の1/2までしか表現できません」ってことでフーリエ変換後にデータが半分になるって事ではありません。
乱暴にとらえれば、
・サンプリング周波数 0.1[sec]
・サンプリング点数 1000[点]
として計算すれば
・基本周波数=0.01
・解析可能な最大周波数=5
ですから有効なデータ点数は半分の500点しか存在しないようです。
しかし、これはあくまで表現可能な周波数帯域の話で変換後のデータ
はちゃん1000点分存在します。(そうでなければ逆変換なんてできません)
Q
特定の周波数のみを通過させるフィルターのプログラムを
設計する場合、逆FFTを使うのが常なのでしょうか?
例えば800HZ以下のローパスフィルターを作る場合、
音声サンプルをFFTした周波数スペクトルの800HZ
より大きい値はすべて0にして、逆FFT、、という手順
で行なうのでしょうか?

A
正解です。
当方のバンドパスフィルターもそうした手順を踏んでいます

Q
はじめまして。最近フーリエ変換なるものを知った初心者です。
さっそくですが質問させて下さい。FFTのdllの処理分岐フラグについて、
3を設定するとフーリエ変換の結果が出力されるとのことですが、フーリエ変換の
結果はそのまま周波数になるのでしょうか?それと実数値?実数と虚数の絶対値が
周波数??いきなりの質問で申し訳ありませんが周波数とフーリエ変換についてぜ
んぜんわからないのでアドバイスをお願いします。

A
質問の趣旨を、
「分岐フラグ3の場合の出力結果を知りたい」
と解釈して回答します。
基本的な内容はreadme.txtを参照して下さい。

1)配列の意味
  入力としての配列は「サンプリング間隔」毎の信号の値
  となりますが、出力は周波数毎の信号の強さを示します。

  <例>
  配列に以下のような値を入れたものとします。
  これは特定のサンプリング間隔「dt」で測定した信号の
  波形です。(測定時間をTとします)
0、0.5、1、0.5、0、-0.5、-1、-0.5、0...
  
  この配列を使って関数を呼び出すと、
  w0、w1、w2、w3、w4、w5、w6、w7...
  の様に配列の内容が変更されています。
  この時w1が基本周波数にあたります。
  w1から「入力した配列数の半分」までが計算結果です。
  各配列は「基本周波数×n」の周波数に相当します。

2)配列の中身
  配列の中身はFFT後のデータをそのまま格納します。
  パワースペクトルを知りたければ独自に計算を行って下さい。
  もしくは「分岐フラグ」を1もしくは5に設定し、
  演算を行って下さい。

  値の単位や、もっと詳細な情報が必要な場合専門書を参照
  することをお勧めします。

Q
>  <例>
>  配列に以下のような値を入れたものとします。
>  これは特定のサンプリング間隔「dt」で測定した信号の
>  波形です。(測定時間をTとします)
> 0、0.5、1、0.5、0、-0.5、-1、-0.5、0...
>  
>  この配列を使って関数を呼び出すと、
>  w0、w1、w2、w3、w4、w5、w6、w7...
>  の様に配列の内容が変更されています。
>  この時w1が基本周波数にあたります。
>  w1から「入力した配列数の半分」までが計算結果です。
>  各配列は「基本周波数×n」の周波数に相当します。
>
とのことですが。基本周波数とはどのようなことを表しているのでしょうか。
例えば入力データの標本間隔を1/8000秒にした時の基本周波数はどのようになるの
でしょうか。的を外した質問かも知れませんが、、
いろいろ専門書などを見たのですがわかりません。
質問ばかりですみませんがどうかよろしくお願いします。

A
基本周波数(f0)は以下のように表します。
f0=1/T
 f0:基本周波数
 T:サンプリング時間
 (サンプリング時間=サンプリング間隔×サンプリング点数)
 ですから...
T=dt×N
 dt:サンプリング間隔(標本間隔)
 N:サンプリング点数
 として...
f0=1/(dt×N)

以上のように計算前のデータから基本周波数は計算可能です。

■補足
FFT(DFT)はその性質上、基本周波数の整数倍の周波数しか
計算できません。(整数倍といってもデータ点数の半分まで)

ですから基本周波数(とデータ点数)から計算可能な周波数が
決まってしまいます。標本間隔が短く大量のデータを計算した方
が理屈から言えば細かい計算ができるわけですが、当然演算
時間が長くなるというリスクがあります。その上にPC上ではメモリ
の制限上、計算可能なデータ点数にも制限があります。

計算に必要な周波数範囲を特定して間隔と点数を決定すること
をお勧めします。

※本DLLの最大点数は、PCの環境にもよりますが100万点程です。


Q
計測したデータにFFTをかけたらどうなるだろうかと思い
FFTの理論もまったく分かっていないままページを渡り歩
いておりましたらこちらでFFT用のDLLに巡り合いました。

早速使ってみようと思ったのですがさすがにFFTの知識が
全くないだけにどのように利用してよいものやら分かりません。

実際のデータは波形のデータでサンプリング周波数50Hzでと
っており全データ数は約1500点程度ございます。そのデータ
をVBで読み込んでFFTの処理をしたいと考えております。

まず引数なのですが一つ目の引数は全データ数ということで
すので1500、2つ目はサンプリング間隔ということですので
0.02、3つ目は実数データの配列ということですので実際の
データが入っている配列X( )と思っているのですが何か間違
いなどございますでしょうか。

またReadmeには
>  1.配列数は必ず「2のN乗」の数を確保して下さい。
>
> 例)3000点のデータを処理したい場合
>   EXP = Log(3000)/Log(2)
>   EXP = 11.550
>   整数にならないので、
>   EXP = 12
>   とします。
>   配列は
>   DN = 2^12
>   DIM XR(DN) AS DOUBLE
>   確保して下さい。
>
>   但し、関数に渡す引数は3000を渡して下さい
>
>    Call fft1dim(3000, dt, re(0), im(0), 1, 1, 0, 0)1

とあるのですが用意したXR()という配列はどのように利用すれ
ばよいのでしょうか。

A
平滑化はデータ点数によって自動的に平均する点数などのパラメーターを決定していま

グラフを綺麗に見る為の手法だと考えて下さい
これは独自の方法ですので、必要無ければ切ってしまって下さい


2002/10/10 新規公開

直線上に配置