アプリで非常に奇妙な問題が発生しています。まず第一に、私のアプリは、MatLab によって自動的に生成されたライブラリを使用して生のオーディオ データを操作するための NDK の能力をテストすることです。アルゴリズムは実にシンプルです。
私の C ライブラリは MatLab コードから自動的に生成され、C で動作するように必要な変更を加えました。コードはエミュレーターで問題なく動作しますが、Nexus 4 デバイスでアプリケーションを実行すると、時々クラッシュし、SIGSEGV が発生します。致命的な誤り。
これは私のCコードです:
JNIEXPORT jshortArray JNICALL Java_com_test_audiocapteffect_MainActivity_addeffects
(JNIEnv* env, jobject thiz, const jshortArray input, int32_T SampleRate, int32_T sizeofx) {
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Creating/Getting Array Elements");
jshort* x = (*env)->GetShortArrayElements(env, input, 0);
//int16_T* x = (int16_T*)j_input;
jshortArray output;
output = (jshortArray)((*env)->NewShortArray(env, sizeofx));
jshort* y = (*env)->GetShortArrayElements(env, output, 0);
//int16_T* y = (int16_T*)j_output;
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Creating variables");
emxArray_real_T *temp;
uint32_T b_y;
int32_T i;
int32_T loop_ub;
int16_T iv0[sizeofx];
real_T thresh;
uint32_T delayedindex;
emxInit_real_T(&temp, 1);
b_y = (uint32_T)rt_roundd(0.3 * (real_T)SampleRate);
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Filling y with zeros");
for(i = 0; i<sizeofx; i++) {
y[i] = 0;
}
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 1");
/* add distortion */
/* distortion function */
i = temp->size[0];
temp->size[0] = sizeofx;
emxEnsureCapacity((emxArray__common *)temp, i, (int32_T)sizeof(real_T));
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 2");
// get the absolute values of each element
for (i = 0; i < sizeofx; i++) {
iv0[i] = b_abs(x[i]);
}
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 3");
thresh = 1.2 * mean(iv0, sizeofx);
for (i = 1; i <= sizeofx; i = (int32_T)((uint32_T)i + 1U)) {
if ((real_T)x[(int32_T)(uint32_T)i - 1] > thresh) {
temp->data[(int32_T)(uint32_T)i - 1] = thresh;
} else if ((real_T)x[i - 1] < -thresh) {
temp->data[(int32_T)(uint32_T)i - 1] = -thresh;
} else {
temp->data[(int32_T)(uint32_T)i - 1] = (real_T)x[i - 1];
}
}
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding delay part 1");
/* add delay */
/* delay function */
/* modified by Thomas Horta */
for (i = 1; i <= sizeofx; i = (int32_T)((uint32_T)i + 1U)) {
delayedindex = (uint32_T)i - b_y;
if (1U < delayedindex) {
} else {
delayedindex = 1U;
}
if (i==1) {
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding delay part 2");
}
if ((uint32_T)i - b_y < 1U) {
y[(int32_T)(uint32_T)i - 1] = (int16_T)(temp->data[(int32_T)(uint32_T)i - 1]);
} else {
y[(int32_T)(uint32_T)i - 1] = (int16_T)(temp->data[(int32_T)(uint32_T)i - 1] +
0.3 * temp->data[(int32_T)delayedindex - 1]);
}
}
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Freeing resources");
emxFree_real_T(&temp);
(*env)->ReleaseShortArrayElements(env, input, x, 0);
(*env)->ReleaseShortArrayElements(env, output, y, 0);
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Returning output");
return output; }
関数が「NDK: 遅延の追加パート 2」というメッセージを含むログ出力がある部分、出力配列を満たすループに到達すると、エラーが発生します。
編集: これは emxArray 構造です: (Matlab によっても自動的に生成されました)
typedef struct emxArray_real_T
{
real_T *data;
int32_T *size;
int32_T allocatedSize;
int32_T numDimensions;
boolean_T canFreeData;
} emxArray_real_T;
変数の型には、MatLab の規則によりこれらの奇妙な名前が付いていますが、それらは変数の型の型定義にすぎません。それらは単なるtypedefですが、実際の型がint16_Tに変換されたためにエラーが発生した可能性があると思います(Javaの同等物ではdoubleからshort )
私のLogCatはこれを表示します:
06-06 15:36:12.382: I/AudioCaptEffect(2503): Add effects to the audio
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Creating/Getting Array Elements
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Creating variables
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Filling y with zeros
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Adding distortion part 1
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Adding distortion part 2
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Adding distortion part 3
06-06 15:36:12.392: D/NDK_SimpleCApp(2503): NDK: Adding delay part 1
06-06 15:36:12.392: D/NDK_SimpleCApp(2503): NDK: Adding delay part 2
06-06 15:36:12.392: A/libc(2503): Fatal signal 11 (SIGSEGV) at 0x72905a08 (code=1), thread 2769 (Thread-15238)
なぜこれが起こっているのか誰にも分かりますか?最も奇妙なことは、これがNexus 4(テストする必要があるAndroidデバイスのみ)でのみ発生し、ほとんどの場合(常にではありません)アプリを実行することです。