在Objective-C中执行信号的FFT,并将结果与​​MATLAB进行比较

时间:2014-11-13 14:16:00

标签: ios xcode matlab fft vdsp

我正在尝试在Objective-C中执行信号的FFT。 信号由180个样本组成。信号如下:

float testFFT [180] = { 0.0000000000, 0.0000432091, 0.0001739833, 0.0003786624, 0.0006653523, 0.0010579729, 0.0015538626, 0.0022084275, 0.0029233105, 0.0037457265, 0.0048239902, 0.0061722184, 0.0074678478, 0.0019116795, -0.0216427371, -0.0583566576, -0.0879606530, -0.0966484919, -0.0844414756, -0.0587274097, -0.0275895316, 0.0020122994, 0.0238022581, 0.0301328432, 0.0223602522, 0.0108049158, 0.0026056657, 0.0015842463, 0.0078394171, 0.0178532675, 0.0289764665, 0.0387034491, 0.0457277447, 0.0503653251, 0.0511394553, 0.0495931208, 0.0491546877, 0.0486858748, 0.0486131087, 0.0533984452, 0.0587649047, 0.0659925416, 0.0777209774, 0.0856716558, 0.0555341654, -0.1010383219, -0.3626580238, -0.5730977058, -0.6356759071, -0.5587731600, -0.4057232738, -0.2299835384, -0.0666809455, 0.0577908531, 0.1170516908, 0.1059532985, 0.0634752810, 0.0284998771, 0.0149525786, 0.0262031760, 0.0470281616, 0.0667090788, 0.0911477804, 0.1096955463, 0.1211226359, 0.1271539181, 0.1249239892, 0.1236920506, 0.1237676740, 0.1250490546, 0.1243178397, 0.1247144639, 0.1260439157, 0.1231973395, 0.1264088154, 0.1277698576, -0.0030977963, -0.3769126236, -0.8328822851, -1.1014552116, -1.0855975151, -0.8706340790, -0.5911422372, -0.3257140219, -0.0960753635, 0.0647964701, 0.1323186159, 0.1257916987, 0.0897259787, 0.0630174652, 0.0530946776, 0.0599082038, 0.0814570710, 0.1065363511, 0.1312004477, 0.1502322406, 0.1570600569, 0.1507443786, 0.1410262287, 0.1309887618, 0.1199141294, 0.1154099405, 0.1160193905, 0.1228033155, 0.1373534203, 0.1516684294, 0.1679655612, 0.1372354180, -0.1066413969, -0.5384752750, -0.8941160440, -0.9979212284, -0.8646196723, -0.6145014763, -0.3477802575, -0.1164548695, 0.0449491963, 0.1089080572, 0.0893236622, 0.0330192894, -0.0108435927, -0.0175555795, 0.0047061597, 0.0339520164, 0.0558914244, 0.0686639696, 0.0742127448, 0.0779310316, 0.0802902952, 0.0771160051, 0.0714451671, 0.0660981461, 0.0637993589, 0.0645155609, 0.0667568296, 0.0722958520, 0.0757482499, 0.0236506276, -0.1267153770, -0.3023732007, -0.3952195346, -0.3767756522, -0.2849329114, -0.1723687500, -0.0716818050, 0.0028261179, 0.0375415571, 0.0343864709, 0.0144051891, -0.0021018211, -0.0056255818, 0.0027398649, 0.0138968918, 0.0204720702, 0.0226374995, 0.0215674732, 0.0184285343, 0.0154026123, 0.0144131510, 0.0145750465, 0.0143866902, 0.0138069429, 0.0127558541, 0.0114914598, 0.0105097489, 0.0059011118, -0.0082570817, -0.0260418169, -0.0354200974, -0.0332562923, -0.0243141986, -0.0146232471, -0.0073889960, -0.0028967261, -0.0005872814, 0.0001664309, 0.0001607906, 0.0000362319, 0.0000018391, 0.0000000001};

在我的项目中,我导入了Accelerate Framework,我用来执行FFT的代码如下:

// -- Number of Sample
int numSamples = 256; // i use 256 because if i use 128 i don't considered 52 values

// -- Init FFT
// - Setup the length
vDSP_Length log2n = log2f(numSamples);

FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);

int nOver2 = numSamples/2;

// - Define complex buffer
COMPLEX_SPLIT A;
A.realp = (float *) malloc(nOver2*sizeof(float));
A.imagp = (float *) malloc(nOver2*sizeof(float));

// - Pack samples:
vDSP_ctoz((COMPLEX*)testFFT, 2, &A, 1, numSamples/2);


// -- Run FFT
vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);

// -- Convert COMPLEX_SPLIT A result to magnitudes
float amp[256];
amp[0] = A.realp[0]/(numSamples*2);

for(int i=1; i<numSamples; i++) {
    amp[i]=sqrt(A.realp[i]*A.realp[i]+A.imagp[i]*A.imagp[i]);
}

然后我的输出幅度向量是:

gainFFTTest = [ -0.022274, 8.984702, 4.144551, 0.809363, 0.941445, 2.347171, 7.364040, 16.668034, 23.730299, 21.198763, 11.301848, 3.042607, 1.467086, 2.339780, 4.816690, 10.835640, 17.146097, 17.648199, 11.441965, 4.918188, 2.744555, 2.347548, 3.812189, 7.538163, 12.398130, 14.082799, 10.534361, 5.591731, 3.525628, 2.503175, 2.460673, 3.326554, 5.311335, 6.440503, 5.227306, 2.916733, 1.815048, 1.607442, 1.587724, 1.587670, 2.045040, 2.519320, 2.300229, 1.566618, 0.928839, 0.690373, 0.905959, 1.130702, 1.337159, 1.626698, 1.553285, 1.114764, 0.753150, 0.591139, 0.653807, 0.852154, 0.836321, 0.835025, 0.851975, 0.664267, 0.443333, 0.324886, 0.312793, 0.420463, 0.429140, 0.355254, 0.340838, 0.290471, 0.214697, 0.174454, 0.153486, 0.190136, 0.208401, 0.164705, 0.138394, 0.115397, 0.075669, 0.065181, 0.077329, 0.110584, 0.143098, 0.131150, 0.086918, 0.063639, 0.051252, 0.064340, 0.077155, 0.072525, 0.080241, 0.088438, 0.070221, 0.051208, 0.040207, 0.028501, 0.025500, 0.029908, 0.042129, 0.045339, 0.033957, 0.019551, 0.015710, 0.025570, 0.028711, 0.017500, 0.006169, 0.013390, 0.013368, 0.007762, 0.005007, 0.008410, 0.010856, 0.009631, 0.012508, 0.018056, 0.019384, 0.014050, 0.006475, 0.005373, 0.006383, 0.006624, 0.006779, 0.006790, 0.005996, 0.004189, 0.002242, 0.001977, 0.002130, 0.001396, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000];

我经常获得NAN i INF值为什么??? 然后我把它放在MATLAB中(检查结果)并执行:    情节(gainFFTTest)

并且,在我放大了之后,我看到了这个情节:

enter image description here

之后我用这个命令将testFFT数组放在MATLAB中:

testFFT = [ 0.0000000000, 0.0000432091, 0.0001739833, 0.0003786624, 0.0006653523, 0.0010579729, 0.0015538626, 0.0022084275, 0.0029233105, 0.0037457265, 0.0048239902, 0.0061722184, 0.0074678478, 0.0019116795, -0.0216427371, -0.0583566576, -0.0879606530, -0.0966484919, -0.0844414756, -0.0587274097, -0.0275895316, 0.0020122994, 0.0238022581, 0.0301328432, 0.0223602522, 0.0108049158, 0.0026056657, 0.0015842463, 0.0078394171, 0.0178532675, 0.0289764665, 0.0387034491, 0.0457277447, 0.0503653251, 0.0511394553, 0.0495931208, 0.0491546877, 0.0486858748, 0.0486131087, 0.0533984452, 0.0587649047, 0.0659925416, 0.0777209774, 0.0856716558, 0.0555341654, -0.1010383219, -0.3626580238, -0.5730977058, -0.6356759071, -0.5587731600, -0.4057232738, -0.2299835384, -0.0666809455, 0.0577908531, 0.1170516908, 0.1059532985, 0.0634752810, 0.0284998771, 0.0149525786, 0.0262031760, 0.0470281616, 0.0667090788, 0.0911477804, 0.1096955463, 0.1211226359, 0.1271539181, 0.1249239892, 0.1236920506, 0.1237676740, 0.1250490546, 0.1243178397, 0.1247144639, 0.1260439157, 0.1231973395, 0.1264088154, 0.1277698576, -0.0030977963, -0.3769126236, -0.8328822851, -1.1014552116, -1.0855975151, -0.8706340790, -0.5911422372, -0.3257140219, -0.0960753635, 0.0647964701, 0.1323186159, 0.1257916987, 0.0897259787, 0.0630174652, 0.0530946776, 0.0599082038, 0.0814570710, 0.1065363511, 0.1312004477, 0.1502322406, 0.1570600569, 0.1507443786, 0.1410262287, 0.1309887618, 0.1199141294, 0.1154099405, 0.1160193905, 0.1228033155, 0.1373534203, 0.1516684294, 0.1679655612, 0.1372354180, -0.1066413969, -0.5384752750, -0.8941160440, -0.9979212284, -0.8646196723, -0.6145014763, -0.3477802575, -0.1164548695, 0.0449491963, 0.1089080572, 0.0893236622, 0.0330192894, -0.0108435927, -0.0175555795, 0.0047061597, 0.0339520164, 0.0558914244, 0.0686639696, 0.0742127448, 0.0779310316, 0.0802902952, 0.0771160051, 0.0714451671, 0.0660981461, 0.0637993589, 0.0645155609, 0.0667568296, 0.0722958520, 0.0757482499, 0.0236506276, -0.1267153770, -0.3023732007, -0.3952195346, -0.3767756522, -0.2849329114, -0.1723687500, -0.0716818050, 0.0028261179, 0.0375415571, 0.0343864709, 0.0144051891, -0.0021018211, -0.0056255818, 0.0027398649, 0.0138968918, 0.0204720702, 0.0226374995, 0.0215674732, 0.0184285343, 0.0154026123, 0.0144131510, 0.0145750465, 0.0143866902, 0.0138069429, 0.0127558541, 0.0114914598, 0.0105097489, 0.0059011118, -0.0082570817, -0.0260418169, -0.0354200974, -0.0332562923, -0.0243141986, -0.0146232471, -0.0073889960, -0.0028967261, -0.0005872814, 0.0001664309, 0.0001607906, 0.0000362319, 0.0000018391, 0.0000000001];

然后我执行FFT并绘制增益:

gain = abs(fft(testFFT));
plot(gain)

现在的情节是正确的:

enter image description here

  •   

    我哪里错了?如何在Objective-C中获得相同的结果?

请帮帮我。

2 个答案:

答案 0 :(得分:0)

您的Objective-C代码与Matlab代码不匹配:

  1. matlab代码中没有窗口。此外,您提供的测试数据似乎已经乘以窗口函数。

  2. 您似乎在Objective-C代码中使用Radix2实现。如果信号的长度与2的幂不匹配,则Matlab不使用Radix2。参考http://mathworks.com/help/matlab/ref/fft.html,&#34;算法&#34;详情。

  3. 你的Objective-C代码看起来很奇怪。 Radix2未定义为2个信号的非功率。提供的样本数(180)与numSamples不匹配。这有什么影响?算法是否用零(零填充)填充信号的剩余部分,还是只读取数组后面的内存?

答案 1 :(得分:0)

我通过将NAN和INF值设置为零并使用256个样本而不是180来解决此问题。