问题描述
我建立了一个Android项目,其中我将Android NDK与 LibXTract 一起使用以提取音频功能. LibXTract使用 fftw3 库.项目由运行简单示例形式libxtract的按钮组成:
I build Android project where I use Android NDK with LibXTract to extract audio features. LibXTract use fftw3 library. Project is consisted of button which runs simple example form libxtract:
JNIEXPORT void JNICALL Java_com_androidnative1_NativeClass_showText(JNIEnv *env, jclass clazz)
{
float mean = 0, vector[] = {.1, .2, .3, .4, -.5, -.4, -.3, -.2, -.1}, spectrum[10];
int n, N = 9;
float argf[4];
argf[0] = 8000.f;
argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
argf[2] = 0.f;
argf[3] = 0.f;
xtract[XTRACT_MEAN]((void *)&vector, N, 0, (void *)&mean);
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "com_androidnative1_NativeClass.c before");
xtract_init_fft(N, XTRACT_SPECTRUM);
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "com_androidnative1_NativeClass.c after");
// Comment for test purpose
//xtract_init_bark(1, argf[1], 1);
//xtract[XTRACT_SPECTRUM]((void *)&vector, N, &argf[0], (void *)&spectrum[0]);
}
Libxtract函数 xtract_init_fft 位于 jni/libxtract/jni/src/init.c 中,执行位于 jni的fftw3函数 fftwf_plan_r2r_1d /fftw3/jni/api/plan-r2r-1d.c
Libxtract function xtract_init_fft locate in jni/libxtract/jni/src/init.c execute fftw3 function fftwf_plan_r2r_1d located at jni/fftw3/jni/api/plan-r2r-1d.c
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "libxtract/src/init.c before");
fft_plans.spectrum_plan = fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation);
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "libxtract/src/init.c after");
在 fftwf_paln_r2r_1d 内的应用程序挂起,没有崩溃或任何其他错误,我必须强制其停止工作.
Application hang inside fftwf_paln_r2r_1d without crash or any outher error I must force it to stop working.
fftwf_paln_r2r_1d 如下:
X(plan) X(plan_r2r_1d)(int n, R *in, R *out, X(r2r_kind) kind, unsigned flags)
{
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "fftw3/api/plan-r2r-1d.c");
return X(plan_r2r)(1, &n, in, out, &kind, flags);
}
在CatLog中,我可以看到:
From CatLog I can see:
07-16 18:50:09.615: D/AndNat(7313): com_androidnative1_NativeClass.c before
07-16 18:50:09.615: D/AndNat(7313): libxtract/src/init.c before
07-16 18:50:09.615: D/AndNat(7313): fftw3/api/plan-r2r-1d.c
我使用gen.sh脚本为fftw3和libxtract生成config.h,并成功地将其定位在源文件夹中.这两个库都是静态库,并与共享库libcom_androidnative1_NativeClass.so链接
I genereate config.h for fftw3 and libxtract with gen.sh scripts locate in source folder with success. Both librearies are build as static and linked with shared libary libcom_androidnative1_NativeClass.so
命令
nm -Ca libcom_androidnative1_NativeClass.so
显示已使用的功能.
应用程序已构建,并且可以毫无问题地部署到设备上.
Application is built and deploys to device without any problems.
我用标志-disable-alloca ,-enable-float 和LibXTract用标志-enable-fft 和-disable-dependency-tracking
I build fftw3 with flags --disable-alloca, --enable-float and LibXTract with flags --enable-fft and --disable-dependency-tracking
仅库源代码中的ingerention被添加了dbgprint并从LibXtract中删除了定义XTRACT_FFT,因为它无法检测到fftw库.
Only ingerention in library source code was added dbgprint and remove define XTRACT_FFT form LibXtract beacouse it can't detect fftw library.
如果有人对我的这种奇怪行为有任何想法,请提供帮助.
If somebody have any idea about this strange for me behavior please help.
在这里,我将整个项目放在github中,以便也许有人可以帮助我解决这个问题.
Here I put entire project in github so maybe someone can help me handle this.
https://github.com/bl0ndynek/AndroidNative1
推荐答案
感谢FFTW3维护者问题的解决.解决方案是在FFTW3中将优化级别从FFTW_MEASURE更改为FFTW_ESTIMATE(从1更改为0),
FFTW的计划器(在xtract_init_fft中)实际上执行并计时不同的FFT算法,以便为给定的n选择最快的计划.为了在尽可能短的时间内执行此操作,计时器必须具有非常高的分辨率,并且要实现此FFTW3,请使用大多数CPU上可用的硬件周期计数器,但Android默认ARM配置上不可用.因此,该算法使用gettimeofday()的算法分辨率较低,并且在ARM上永远都花在了xtract_init_fft上.
Thanks for FFTW3 maintainer problem is solved.Solution was to change optimization level from FFTW_MEASURE to FFTW_ESTIMATE (from 1 to 0) in FFTW3,
FFTW's planner (in xtract_init_fft) actually executes and times different possible FFT algorithms in order to pick the fastest plan for a given n. In order to do this in as short a time as possible, however, the timer must have a very high resolution, and to accomplish this FFTW3 employ the hardware cycle counters that are available on most CPUs but not on Android default ARM configuration.So this algorithm use gettimeofday() witch have low resolution and on ARM took forever on xtract_init_fft.
这篇关于使用Android NDK调用嵌套函数后挂起了应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!