Help us understand the problem. What is going on with this article?

iOSで高速フーリエ変換を使う

More than 5 years have passed since last update.

画像処理や音声処理でお世話になるFFT(高速フーリエ変換)ですが、iOSの場合、AppleよりFFTを計算するライブラリが用意されています。
その使い方について。

準備

プロジェクトにAccelerate.frameworkを追加してください。
そして、FFTを用いたいソースコードに以下を追記してください。
例:

FFTSample.m
#import <Accelerate/Accelerate.h>

FFTを計算する

以下が実際の計算になります。

FFTSample.m
// data: 入力
// length: 入力のうち利用する要素数
- (void)calcFFT:(float*)data dataLength:(int)length
{
    // データ長を2のn乗の大きさにする
    unsigned int sizeLog2 = (int)(log(length)/log(2));
    unsigned int size = 1 << sizeLog2;

    // fftのセットアップ
    FFTSetup fftSetUp = vDSP_create_fftsetup(sizeLog2 + 1, FFT_RADIX2);

    // 窓関数の用意
    float* window = calloc(size, sizeof(float));
    float* windowedInput = calloc(size, sizeof(float));
    vDSP_hann_window(window, size, 0);

    // 窓関数を入力値に適用し、windewedInputへ
    vDSP_vmul(data, 1, window, 1, windowedInput, 1, size);

    // 入力を複素数にする
    DSPSplitComplex splitComplex;
    splitComplex.realp = calloc(size, sizeof(float));
    splitComplex.imagp = calloc(size, sizeof(float));

    for (int i = 0; i < size; i++) {
        splitComplex.realp[i] = windowedInput[i];
        splitComplex.imagp[i] = 0.0f;
    }

    // FFTを計算する
    vDSP_fft_zrip(fftSetUp, &splitComplex, 1, sizeLog2 + 1, FFT_FORWARD);

    // 結果を表示する
    // FFTの性質から半分のデータのみ利用する
    for (int i = 0; i <= size/2; i++) {
        float real = splitComplex.realp[i];
        float imag = splitComplex.imagp[i];
        float distance = sqrt(real*real + imag*imag);
        NSLog(@"[%d] %.2f", i, distance);
    }

    // メモリを開放する
    free(splitComplex.realp);
    free(splitComplex.imagp);
    free(window);
    free(windowedInput);
    vDSP_destroy_fftsetup(fftSetUp);

}

あとは実行してみましょう。
元になるデータですが、例えばsin波などをつかってみてください。

FFTSample.m
- (void)execute
{
    int dataLength = 512;
    float* data = calloc(dataLength, sizeof(float));
    for(int i = 0; i < dataLength; i++) {
        // dataLength中で30回振動させる
        data[i] = sin(i * 30.0f / (float)dataLength * 2.0f * M_PI);
    }
    [self calcFFT:data dataLength:dataLength];
}

恐らく以下のような出力を得られるかと思います。
30付近のみ掲載します。あとは0なので。

[28] 0.00
[29] 128.00
[30] 256.00
[31] 128.00
[32] 0.00

参考

Appleの公式ドキュメント
http://developer.apple.com/library/ios/#documentation/Performance/Conceptual/vDSP_Programming_Guide/UsingFourierTransforms/UsingFourierTransforms.html

vDSPを使う(高速フーリエ変換編 その6):なんてこったいブログ
http://nantekottai.com/2010/10/04/fft-with-vdsp-6/

y_matsuwitter
DMM.com CTO。正座してる人。
http://medium.com/@y_matsuwitter/
dmmcom
総合エンタテイメントサイト「DMM.com」を運営。会員数は2,900万人を突破。動画配信、FX、英会話、ゲーム、太陽光発電、3Dプリンタなど40以上のサービスを展開。沖縄での水族館事業参入、ベルギーでのサッカークラブ経営など、様々な事業を手掛ける。また2018年より若手起業家の支援を強化、「DMM VENTURES」による出資や、M&Aなどを積極的に展開している。
https://dmm-corp.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした