/ooura-fft-cpp

大浦FFTライブラリ C++移植版

Primary LanguageC++

大浦FFT(一次元DFT/DCT)ライブラリ C++移植版

  • 大浦氏の高速フーリエ変換ライブラリをC++用に移植したものです
    • ポインタ渡しやstd::vectorの参照渡し、std::complexの使用に対応しています
    • 大浦FFTの関数ごとの呼び出しルール(初回のみ配列ipの最初の値に0を入れる、FFT/IFFTでisgnの符号を変える、など)もこのライブラリが請け負うので、開発時の余計な手間が省けます

使用方法

以下のヘッダをインクルードします。

#include <fftsg/fftsg.hpp>

各クラスはfloat型とdouble型に対応しています。

// float型の場合
fftsg::FFTEngine<float> fftEngine(N);
fftsg::RFFTEngine<float> rfftEngine(N);
fftsg::DCTEngine<float> dctEngine(N);

// double型の場合
fftsg::FFTEngine<double> fftEngine(N);
fftsg::RFFTEngine<double> rfftEngine(N);
fftsg::DCTEngine<double> dctEngine(N);

離散フーリエ変換: FFTEngineクラス

// コンストラクタ: フレームサイズ(サンプル数)を指定。Nは2^nの値で指定すること。
fftsg::FFTEngine<float> fftEngine(N);

// FFT
fftEngine.fft(samples);

// IFFT
fftEngine.ifft(samples);

samples には std::vector<std::complex<float>>(要素数N) または std::vector<float>(実部と虚部を交互に並べたもの、要素数2N) を指定します

離散フーリエ変換(実数バージョン): RFFTEngineクラス

// コンストラクタ: フレームサイズ(サンプル数)を指定。Nは2^nの値で指定すること。
fftsg::RFFTEngine<float> rfftEngine(N);

// FFT
rfftEngine.rfft(samples);

// IFFT
rfftEngine.irfft(samples);

samples には std::vector<float>(実部のみ、要素数N) を指定します

離散コサイン変換: DCTEngineクラス

// コンストラクタ: フレームサイズ(サンプル数)を指定。Nは2^nの値で指定すること。
fftsg::DCTEngine<float> dctEngine(N);

// DCT
dctEngine.dct(samples);

// IDCT
dctEngine.idct(samples);

samples には std::vector<float>(実部のみ、要素数N) を指定します

コンパイル方法

CMakeを使用したプロジェクトに使用する場合

CMakeLists.txtに以下の記述を追加してください(your_targetの部分はターゲット名に適宜変更)。
この例ではプロジェクト内にこのリポジトリをthird_party/fftsgディレクトリとして入れている場合を想定しています。

add_subdirectory(third_party/fftsg)
target_link_libraries(your_target fftsg)

CMake不使用のプロジェクトに使用する場合(Windows & Visual Studio)

コマンドプロンプトを開き、このリポジトリのディレクトリに移動した上で以下を実行します。

> mkdir build
> cd build
> cmake ..
> cmake --build . --config Debug
> cmake --build . --config Release

これを実行するとDebug/fftsg.libおよびRelease/fftsg.libが生成されます。

Visual Studio上でプロジェクトのプロパティを開き、以下の2点を設定します。

  • 左上の構成を「すべての構成」に変更した上で以下を行います
    • 「プロパティ」→「C/C++」→「全般」→「追加のインクルードディレクトリ」に、このリポジトリのincludeディレクトリのパスを指定
    • 「プロパティ」→「リンカー」→「入力」→「追加の依存ファイル」に、fftsg.libという行を追加します
  • 左上の構成を「Debug」に変更した上で以下を行います
    • 「プロパティ」→「リンカー」→「全般」→「追加のライブラリディレクトリ」に、このリポジトリのbuild/Debugディレクトリのパスを指定
  • 左上の構成を「Release」に変更した上で以下を行います
    • 「プロパティ」→「リンカー」→「全般」→「追加のライブラリディレクトリ」に、このリポジトリのbuild/Releaseディレクトリのパスを指定

なお、デフォルトでは64bit(x64)のアーキテクチャ向けにビルドされるため、プロジェクトで32bit(x86)用にビルドする必要がある場合はcmake ..の代わりにcmake .. -A Win32を実行してください。

CMake不使用のプロジェクトに使用する場合(Linux/Mac、Windows & MinGW or Cygwin)

$ mkdir build
$ cd build
$ cmake ..
$ cmake --build .

(※MinGWを使用する場合は、cmake ..-G "MinGW Makefiles"または-G "MSYS Makefiles"を環境に応じて指定してください)

これを実行するとlibfftsg.aが生成されるので、使用時にこれをリンクしてください。

GCC/Clangの場合、例えばこのリポジトリをthird_party/fftsgディレクトリとして入れている場合は以下のようにオプションを付ければインクルードおよびリンクできます。

$ g++ ~ -Ithird_party/fftsg/include -Lthird_party/fftsg/build -lfftsg

Cコードの改変部分

fftsg.cのうち、以下の部分を改変しています。

  • (C++の場合)コード全体をfftsg名前空間内に入れるように
    • それに伴い、コード中の#includeは先頭の名前空間外に移動
  • double型をfloat型に置き換えたものを追加(fftsg_float.c)
    • float版は関数名の末尾にfを追加(C言語はオーバーロードできないため)
    • float版は実数値にfのサフィックスを付けてfloat型に
    • float版では数学関数にsinf()などのfloat用関数を使うよう変更(C言語の数学関数はオーバーロードされないため)
    • (C++の場合)オーバーロードでdouble型とfloat型の関数を同じ関数名で使用できるように
  • 内部の計算に使用する関数はstaticを付けて内部リンケージにするように
    • そのままだとリンク時にdouble版とfloat版の関数名が衝突するため
    • それに伴って関数の宣言順などを変更

注意点

  • 離散サイン変換は個人的に利用する機会がなく動作テストできていないので除外しています
  • 各メンバ関数にはconstが付いていません
    • 初回のみsin/cosテーブル構築の副作用が発生するためです
      • TODO: コンストラクタで行うよう変更することで改善する予定
    • そのため、FFTを利用するクラスを作成したい場合はFFTEngineをメンバ変数として持たせるのではなく、クラスの各メンバ関数の引数にFFTEngineの参照を取るなどして外部から渡すことをお勧めします
      • こうすることで、利用クラス側のメンバ関数はconstにできます
      • また、利用クラスの複数のインスタンスで同じFFTEngineを使い回せるようにもなります

ライセンス

  • src/fftsg.cおよびsrc/fftsg_float.cは大浦FFTライブラリのライセンス準拠、それら以外の追加ファイル(cpp, hppファイルなど)のライセンスは「Unlicense」です
  • すなわち、本ライブラリをご利用の際は大浦FFTライブラリのライセンスに従ってください

大浦FFTについて

配布ページ

README原文

ライセンス原文

Copyright Takuya OOURA, 1996-2001

このソースコードはフリーソフトです.商用目的を含め,このコードの使用, コピー,修正及び配布は自由に行って結構です.ただし,このコードの修正を
行った場合は,そのことを明記してください.