プロジェクトに OpenSL を使用する必要があります (Soundpool を試しましたが、まったくうまくいきません)。ただし、サウンドを複数回再生した後(連続35回程度)、アプリがシャットダウンします(おそらくオーバーフローのためだと思います)。
問題を解決するためにバッファ/メモリを解放しようとしました(そして、神のために、このOpenSLを使用して行う方法がわかりません)。そのため、ファイルの再生が終了したら解放することにしました。OpenSL ES は、RegisterCallback
役立つ機能を提供してくれます。私の場合(URIファイルを使用)、新しい問題が発生し、RegisterCallback
アプリが再びクラッシュしました。行き詰まっています。
これが私のコードです。助けてください。の直後にクラッシュしました//register callback for uri
。
static short fdBuffer[SAWTOOTH_FRAMES];
// create URI audio player
jboolean Java_jp_mobigame_ayakashi_CardGameActivity_createUriAudioPlayer(JNIEnv* env, jclass clazz,
jstring uri)
{
__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri \n");
SLresult result;
// convert Java string to UTF-8
const jbyte *utf8 = (*env)->GetStringUTFChars(env, uri, NULL);
assert(NULL != utf8);
// configure audio source
// (requires the INTERNET permission depending on the uri parameter)
SLDataLocator_URI loc_uri = {SL_DATALOCATOR_URI, (SLchar *) utf8};
SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
SLDataSource audioSrc = {&loc_uri, &format_mime};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_MUTESOLO /*SL_IID_BUFFERQUEUE*/, SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &uriPlayerObject, &audioSrc,
&audioSnk, 3, ids, req);
// note that an invalid URI is not detected here, but during prepare/prefetch on Android,
// or possibly during Realize on other platforms
assert(SL_RESULT_SUCCESS == result);
// release the Java string and UTF-8
(*env)->ReleaseStringUTFChars(env, uri, utf8);
// realize the player
result = (*uriPlayerObject)->Realize(uriPlayerObject, SL_BOOLEAN_FALSE);
// this will always succeed on Android, but we check result for portability to other platforms
if (SL_RESULT_SUCCESS != result) {
(*uriPlayerObject)->Destroy(uriPlayerObject);
uriPlayerObject = NULL;
return JNI_FALSE;
}
// get the play interface
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_PLAY, &uriPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
// get the seek interface
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_SEEK, &uriPlayerSeek);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 1\n");
//get the buffer queue interface
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &uriPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 2\n");
//register callback for uri
result = (*uriPlayerBufferQueue)->RegisterCallback(uriPlayerBufferQueue, bqUriPlayerCallback, NULL);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 4\n");
//Enqueue
__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "\n createUri 3\n");
result = (*uriPlayerBufferQueue)->Enqueue(uriPlayerBufferQueue, fdBuffer, sizeof(fdBuffer));
// get the mute/solo interface
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_MUTESOLO, &uriPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
// get the volume interface
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_VOLUME, &uriPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
return JNI_TRUE;
}