本文介绍了与Android NDK调用嵌套函数后,应用程序挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我构建Android项目中,我使用的Andr​​oid 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 consist of button witch run 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 的执行fftw3功能的 fftwf_plan_r2r_1d 位于 JNI /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 没有崩溃或任何outher错误,我必须迫使它停止工作。

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);
}

这是我目录下载可以看到:

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

我genereate的config.h的fftw3和libxtract与gen.sh脚本中找到成功的源文件夹中。这两个librearies是建立静态和共享libary 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 

显示,使用功能的inclueded。

shows that used function are inclueded.

Aplication构建和部署设备没有任何问题。

Aplication build and deploy to device without any problems.

我建立fftw3用旗的 - 禁用-的alloca - 使浮球的和LibXTract用旗的 - 使-FFT 的和 - 禁用依赖性跟踪

I build fftw3 with flags --disable-alloca, --enable-float and LibXTract with flags --enable-fft and --disable-dependency-tracking

只有ingerention在库源$ C ​​$ C加入dbgprint并删除定义XTRACT_FFT形式LibXtract beacouse不能检测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维护者问题就解决了​​。的解决方案是从FFTW_MEASURE改变优化级别到FFTW_ESTIMATE(​​从1到0)在FFTW3文,
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调用嵌套函数后,应用程序挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-15 20:25