LoginSignup
1
0

More than 3 years have passed since last update.

Objective-Cでフーリエ変換によるローパスフィルタ

Posted at

iOS向けアプリの開発で、
指定Hz以下の波形をカットするローパスフィルタを作成したかった訳だが
それをする為には
フーリエ変換→周波数カット→逆フーリエ変換
の流れで処理する必要がある。

ググってもObjective-Cによる
これらの処理を一貫してやってくれるもの無かった為、自作した。

コードはこちらで紹介されていた
C言語のものを参考にして書き起こした。

Filter.m
const float pi = 3.14;
const float T = 0.01;

@implementation Filter : NSObject


- (float*)fftLawPassFilter:(float*)srcData dstData:(float*)dstData dataLength:(int)length filterHz:(float)filterHz
{
    // 初期化
    float tmpRefOut;
    float tmpImfOut;
    float imfOut[length];
    int size = length;
    float ReF[size];
    float ImF[size];

    //フーリエ変換
    for(int n=0;n<size;n++){
        float Ref = 0.0f;
        float Imf = 0.0f;

        for(int k=0;k<size;k++) {
            Ref+=srcData[k]*cos(2*pi*k*n/size);
            Imf+=-srcData[k]*sin(2*pi*k*n/size);
        }

        ReF[n]=Ref;
        ImF[n]=Imf;

        if(n%1000==0)printf("%d\n",n);
    }

    // フィルタをかける
    for(int n=0;n<size;n++){
        float hz = (n+1) / (size*T);
        NSLog(@"a: %f", hz);

        if(hz > filterHz){
            ReF[n]=0;
            ImF[n]=0;
        }
    }

    // フーリエ逆変換
    for(int k=0;k<size;k++) {
        tmpRefOut=0.0;
        tmpImfOut=0.0;
        for(int n=0;n<size;n++) {
            tmpRefOut+=(ReF[n]*cos(2*pi*k*n/size)-ImF[n]*sin(2*pi*k*n/size))/size;
            tmpImfOut+=(ReF[n]*sin(2*pi*k*n/size)+ImF[n]*sin(2*pi*k*n/size))/size;
        }

        dstData[k]=tmpRefOut;
        imfOut[k]=tmpImfOut;
        if(k%1000==0)printf("%d\n",k);
    }

    return dstData;
}

引数にフィルタしたいデータの配列、そのサイズ、周波数カット数(Hz)を指定してやれば良い。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0