我必须在我的android项目中使用DFFT。我找到了kissfft库并决定使用它。
我已经按如下方式编写了JNI函数:
#import ...
...
kiss_fft_cfg cfg; // kiss_fft config
int nfft; // chunk size
// allocating config for fft
extern "C"
void
Java_xxx_yyy_zzz_MyActivity_allocFFT(JNIEnv *env,jobject /* this */,jint chunkSize){
cfg = kiss_fft_alloc(chunkSize,false,0,0);
nfft = chunkSize;
}
// calculate fft
extern "C"
jdoubleArray
Java_xxx_yyy_zzz_MyActivity_doFFT(JNIEnv *env,jobject /* this */,jshortArray data) {
kiss_fft_cpx *cx_in, *cx_out;
cx_in = new kiss_fft_cpx[nfft];
cx_out = new kiss_fft_cpx[nfft];
jshort *body = env->GetShortArrayElements(data, 0);
int chunksCnt = ceil(env->GetArrayLength(data)/nfft);
double *amps = new double[chunksCnt*nfft/2];
for(int iter=0; iter<chunksCnt; ++iter) {
// fill cx_in
for (int oter = 0; oter < nfft; ++oter) {
cx_in[oter].r = body[iter*nfft + oter];
cx_in[oter].i = 0.0;
}
// do FFT
kiss_fft(cfg, cx_in, cx_out);
// find amplitudes and save it
for (int oter = 0; oter < nfft / 2; ++oter)
amps[iter * nfft / 2 + oter] =
sqrt(pow(cx_out[oter].r, 2) + pow(cx_out[oter].i, 2)) / nfft;
}
jdoubleArray amplitudes = env->NewDoubleArray(chunksCnt*nfft/2);
env->SetDoubleArrayRegion(amplitudes,0,chunksCnt*nfft/2,&s[0]);
delete[] cx_in;
delete[] cx_out;
delete[] amps;
env->ReleaseShortArrayElements(data, body, JNI_ABORT);
return amplitudes;
}
// freeing resources
extern "C"
void
Java_xxx_yyy_zzz_MyActivity_freeFFT(JNIEnv *env,jobject /* this */){
free(cfg);
}
然后在MyActivity类中,我确实如下:
allocFFT(2048);
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
short[] data = new short[2048];
for(short iter=0; iter<2048; ++iter)
data[iter] = iter;
Long lastTime = System.currentTimeMillis();
doFFT(data);
Log.i("fft",String.valueOf(System.currentTimeMillis()-lastTime));
handler.postDelayed(runnable,10);
}
};
handler.postDelayed(runnable,1000);
得到这样的输出:
01-09 17:48:03.310 21976-21976/? I/fft: 4
01-09 17:48:03.370 21976-21976/? I/fft: 52
01-09 17:48:03.385 21976-21976/? I/fft: 2
01-09 17:48:03.400 21976-21976/? I/fft: 2
01-09 17:48:03.410 21976-21976/? I/fft: 1
01-09 17:48:03.425 21976-21976/? I/fft: 1
01-09 17:48:03.435 21976-21976/? I/fft: 2
01-09 17:48:03.450 21976-21976/? I/fft: 1
01-09 17:48:03.460 21976-21976/? I/fft: 1
01-09 17:48:03.475 21976-21976/? I/fft: 2
01-09 17:48:03.485 21976-21976/? I/fft: 2
01-09 17:48:03.495 21976-21976/? I/fft: 1
01-09 17:48:03.510 21976-21976/? I/fft: 1
01-09 17:48:03.520 21976-21976/? I/fft: 5
01-09 17:48:03.535 21976-21976/? I/fft: 4
01-09 17:48:03.555 21976-21976/? I/fft: 4
01-09 17:48:03.570 21976-21976/? I/fft: 5
01-09 17:48:03.585 21976-21976/? I/fft: 4
01-09 17:48:03.600 21976-21976/? I/fft: 4
01-09 17:48:03.615 21976-21976/? I/fft: 5
01-09 17:48:03.630 21976-21976/? I/fft: 4
01-09 17:48:03.645 21976-21976/? I/fft: 5
01-09 17:48:03.660 21976-21976/? I/fft: 4
01-09 17:48:03.675 21976-21976/? I/fft: 5
01-09 17:48:03.690 21976-21976/? I/fft: 4
01-09 17:48:03.705 21976-21976/? I/fft: 4
01-09 17:48:03.720 21976-21976/? I/fft: 5
01-09 17:48:03.785 21976-21976/? I/fft: 52
01-09 17:48:03.800 21976-21976/? I/fft: 5
01-09 17:48:03.815 21976-21976/? I/fft: 5
01-09 17:48:03.830 21976-21976/? I/fft: 4
01-09 17:48:03.850 21976-21976/? I/fft: 5
正如你所看到的,fft计算的时间有时看起来很奇怪 - 它是否比平均值大10倍。
我尝试在纯C中使用相同的库进行相同的测试,并且没有这样的结果 - 所有计算时间大致相等。
因此,假设问题出现在我的本机代码中是合乎逻辑的,可能我忘了做重要的事情,我不知道。请帮帮我。