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)を指定してやれば良い。