Android下Speex库除0错误(SIGFPE)排除

在项目中使用Speex对实时采集到的音频流进行去噪,发现运行一段时间后程序就会崩溃。


首先需要得到程序崩溃时的调用堆栈,在终端输入命令:

adb logcat | ndk-stack -sym ./xxxGame/proj.android/obj/local/armeabi


然后再让程序跑起来等着,出错后得到如下信息:

********** Crash dump: **********
Build fingerprint: 'Lenovo/smarttp/S898tp:4.4.2/KOT49H/VIBEUI_V2.0_1447_7.5.1_ST_S898t+.:user/release-keys'
pid: 12612, tid: 12700, name: Thread-8281  >>> org.cocos2dx.hellocpp <<<
signal 8 (SIGFPE), code -6 (SI_TKILL), fault addr 00003144
Stack frame #00  pc 00028e7c  /system/lib/libc.so (tgkill+12)
Stack frame #01  pc 00017889  /system/lib/libc.so (pthread_kill+88)
Stack frame #02  pc 00017aa3  /system/lib/libc.so (raise+10)
Stack frame #03  pc 000197d0  /data/app-lib/org.cocos2dx.hellocpp-2/libspeex.so (__aeabi_ldiv0+8): Routine __aeabi_idiv0 at /s/ndk-toolchain/src/build/../gcc/gcc-4.8/libgcc/config/arm/lib1funcs.S:1335
Stack frame #04  pc 0000fe2f  /data/app-lib/org.cocos2dx.hellocpp-2/libspeex.so: Routine DIV32_16_Q15 at /Users/yizeng/ChessGame/proj.android/../cocos2d/../../Legend/library/ext/speex/speex-1.2rc1/./libspeex/preprocess.c:144
Stack frame #05  pc 000103a3  /data/app-lib/org.cocos2dx.hellocpp-2/libspeex.so (speex_preprocess_run+494): Routine DIV32_16_Q15 at /Users/yizeng/ChessGame/proj.android/../cocos2d/../../Legend/library/ext/speex/speex-1.2rc1/./libspeex/preprocess.c:124 (discriminator 2)
Stack frame #06  pc 001fa911  /data/app-lib/org.cocos2dx.hellocpp-2/libcocos2dcpp.so (aacEncode::SpeexPrePareAudio(unsigned char*)+12): Routine aacEncode::SpeexPrePareAudio(unsigned char*) at /Users/yizeng/chessgame/proj.android/jni/../../../Legend/library/rtmp/AACEncode.cpp:278
Stack frame #07  pc 001fa9d5  /data/app-lib/org.cocos2dx.hellocpp-2/libcocos2dcpp.so (aacEncode::Encode(unsigned char*, int, unsigned char*&, int&)+76): Routine aacEncode::Encode(unsigned char*, int, unsigned char*&, int&) at /Users/yizeng/chessgame/proj.android/jni/../../../Legend/library/rtmp/AACEncode.cpp:144
Stack frame #08  pc 001f8f83  /data/app-lib/org.cocos2dx.hellocpp-2/libcocos2dcpp.so (ns::CameraFilter::_initAudioData(unsigned char const*, int)+54): Routine ns::CameraFilter::_initAudioData(unsigned char const*, int) at /Users/yizeng/chessgame/proj.android/jni/../../../Legend/library/platform/NsCameraFilter.cpp:463
Stack frame #09  pc 001f9b01  /data/app-lib/org.cocos2dx.hellocpp-2/libcocos2dcpp.so (Java_org_cocos2dx_lib_Cocos2dxHelper_onAudioRecord+68): Routine Java_org_cocos2dx_lib_Cocos2dxHelper_onAudioRecord at /Users/yizeng/chessgame/proj.android/jni/../../../Legend/library/platform/android/NsCameraAndroid.cpp:524
Stack frame #10  pc 0001e74c  /system/lib/libdvm.so (dvmPlatformInvoke+112)
Stack frame #11  pc 0004fb71  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+484)
Stack frame #12  pc 00027b6c  /system/lib/libdvm.so

据此查看源码后确定是DIV32_16_Q15调用的DIV32_16引起的,故修改fixed_generic.h的最后几行:

//fixed by mazi
#define DIV32_16(a,b)  (0==(b) ? 0 : ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b)))))
#define PDIV32_16(a,b) (0==(b) ? 0 : ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b)))))
#define DIV32(a,b)     (0==(b) ? 0 : (((spx_word32_t)(a))/((spx_word32_t)(b))))
#define PDIV32(a,b)    (0==(b) ? 0 : (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b))))

搞定收工!大笑


注: 这里我用的编译选项是FIXED_POINT,因为如果用FLOATING_POINT很多Android手机跑不动。

    另外还有个编译选项是FIXED_POINT_DEBUG,开启后也可以避免除0错误,但是它内部的判断较多,估计会慢一些。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值