【问题标题】:Application is hanged after call nested function with Android NDK使用 Android NDK 调用嵌套函数后应用程序被挂起
【发布时间】:2012-07-16 19:03:40
【问题描述】:

我构建了 Android 项目,在其中使用带有 LibXTract 的 Android NDK 来提取音频特征。 LibXTract 使用fftw3 库。项目由运行简单示例形式 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

__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 内没有崩溃或任何外部错误我必须强制它停止工作。

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 我可以看到:

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 链接

命令

nm -Ca libcom_androidnative1_NativeClass.so 

表示包含使用的函数。

应用程序已构建并部署到设备没有任何问题。

我使用标志 --disable-alloca--enable-float 和带有标志 --enable-fft 的 LibXTract 构建 fftw3 和--禁用依赖跟踪

仅在库源代码中添加了 dbgprint 并从 LibXtract 中删除了定义 XTRACT_FFT,因为它无法检测到 fftw 库。

如果有人对我这种奇怪的行为有任何想法,请提供帮助。


这里我把整个项目放在了 github 上,所以也许有人可以帮我处理这个问题。

https://github.com/bl0ndynek/AndroidNative1

【问题讨论】:

    标签: android android-ndk fftw


    【解决方案1】:

    感谢 FFTW3 维护者问题已解决。 解决方案是在 FFTW3 中将优化级别从 FFTW_MEASURE 更改为 FFTW_ESTIMATE(从 1 到 0),
    FFTW 的计划器(在 xtract_init_fft 中)实际上执行并计算不同的可能 FFT 算法,以便为给定的 n 选择最快的计划。然而,为了在尽可能短的时间内完成此操作,计时器必须具有非常高的分辨率,并且要完成此 FFTW3 使用大多数 CPU 上可用但 Android 默认 ARM 配置上不可用的硬件周期计数器。 所以这个算法使用 gettimeofday() 巫婆具有低分辨率,并且在 ARM 上永远占用 xtract_init_fft。

    【讨论】:

    • 值得注意的是,LibXtract 不再使用 FFTW,而是 Android 上的 Ooura,所以这应该不再是问题。
    【解决方案2】:

    在我看来,您的递归函数 X() 中缺少一些终止条件,这会使您陷入无限循环。

    【讨论】:

    • 是的,但它没有修改函数,当我在 gcc 下编译它时它工作正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多