diff src/SDL_android.cpp @ 4996:8d7315668e35

Fixed audio buffer lifecycle and implemented audio shutdown
author Sam Lantinga <slouken@libsdl.org>
date Thu, 13 Jan 2011 12:32:55 -0800
parents 9f9bea41e88f
children a21501393bef
line wrap: on
line diff
--- a/src/SDL_android.cpp	Thu Jan 13 11:14:20 2011 -0800
+++ b/src/SDL_android.cpp	Thu Jan 13 12:32:55 2011 -0800
@@ -55,6 +55,7 @@
 static jmethodID midAudioInit;
 static jmethodID midAudioWriteShortBuffer;
 static jmethodID midAudioWriteByteBuffer;
+static jmethodID midAudioQuit;
 
 // Accelerometer data storage
 float fLastAccelerometer[3];
@@ -83,13 +84,14 @@
     mActivityInstance = cls;
     midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V");
     midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V");
-	midAudioInit = mEnv->GetStaticMethodID(cls, "audioInit", "(IZZI)Ljava/lang/Object;");
-	midAudioWriteShortBuffer = mEnv->GetStaticMethodID(cls, "audioWriteShortBuffer", "([S)V");
-	midAudioWriteByteBuffer = mEnv->GetStaticMethodID(cls, "audioWriteByteBuffer", "([B)V");
+    midAudioInit = mEnv->GetStaticMethodID(cls, "audioInit", "(IZZI)Ljava/lang/Object;");
+    midAudioWriteShortBuffer = mEnv->GetStaticMethodID(cls, "audioWriteShortBuffer", "([S)V");
+    midAudioWriteByteBuffer = mEnv->GetStaticMethodID(cls, "audioWriteByteBuffer", "([B)V");
+    midAudioQuit = mEnv->GetStaticMethodID(cls, "audioQuit", "()V");
 
     if(!midCreateGLContext || !midFlipBuffers || !midAudioInit ||
-       !midAudioWriteShortBuffer || !midAudioWriteByteBuffer) {
-		__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
+       !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit) {
+        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
     }
 }
 
@@ -150,8 +152,8 @@
 extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread(
                                     JNIEnv* env)
 {
-	mVM->AttachCurrentThread(&mAudioEnv, NULL);
-	Android_RunAudioThread();
+    mVM->AttachCurrentThread(&mAudioEnv, NULL);
+    Android_RunAudioThread();
 }
 
 
@@ -171,78 +173,69 @@
 //
 // Audio support
 //
-static jint audioBufferFrames = 0;
-static bool audioBuffer16Bit = false;
-static bool audioBufferStereo = false;
-
-static jobject audioBuffer;
-static void * audioPinnedBuffer;
+static jboolean audioBuffer16Bit = JNI_FALSE;
+static jboolean audioBufferStereo = JNI_FALSE;
+static jobject audioBuffer = NULL;
+static void* audioBufferPinned = NULL;
 
 extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
 {
-	__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
-	audioBuffer16Bit = is16Bit;
-	audioBufferStereo = channelCount > 1;
+    int audioBufferFrames;
+
+    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
+    audioBuffer16Bit = is16Bit;
+    audioBufferStereo = channelCount > 1;
 
-	audioBuffer = mEnv->CallStaticObjectMethod(mActivityInstance, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
-	audioBuffer = mEnv->NewGlobalRef(audioBuffer);
+    audioBuffer = mEnv->CallStaticObjectMethod(mActivityInstance, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
+
+    if (audioBuffer == NULL) {
+        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
+        return 0;
+    }
+    audioBuffer = mEnv->NewGlobalRef(audioBuffer);
 
-	if (audioBuffer == NULL) {
-		__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
-		return 0;
-	}
+    jboolean isCopy = JNI_FALSE;
+    if (audioBuffer16Bit) {
+        audioBufferPinned = mEnv->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
+        audioBufferFrames = mEnv->GetArrayLength((jshortArray)audioBuffer);
+    } else {
+        audioBufferPinned = mEnv->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
+        audioBufferFrames = mEnv->GetArrayLength((jbyteArray)audioBuffer);
+    }
+    if (audioBufferStereo) {
+        audioBufferFrames /= 2;
+    }
 
-	if (audioBufferStereo) {
-		audioBufferFrames = mEnv->GetArrayLength((jshortArray)audioBuffer) / 2;
-	} else {
-		audioBufferFrames = mEnv->GetArrayLength((jbyteArray)audioBuffer);
-	}
-
-	return audioBufferFrames;
+    return audioBufferFrames;
 }
 
-extern "C" void * Android_JNI_PinAudioBuffer()
+extern "C" void * Android_JNI_GetAudioBuffer()
 {
-	jboolean isCopy = JNI_FALSE;
-
-	if (audioPinnedBuffer != NULL) {
-		return audioPinnedBuffer;
-	}
-
-	if (audioBuffer16Bit) {
-		audioPinnedBuffer = mAudioEnv->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
-	} else {
-		audioPinnedBuffer = mAudioEnv->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
-	}
-
-	return audioPinnedBuffer;
+    //jboolean isCopy = JNI_FALSE;
+    //audioBufferPinned = mAudioEnv->GetPrimitiveArrayCritical((jarray)audioBuffer, &isCopy);
+    return audioBufferPinned;
 }
 
-extern "C" void Android_JNI_WriteAudioBufferAndUnpin()
+extern "C" void Android_JNI_WriteAudioBuffer()
 {
-	if (audioPinnedBuffer == NULL) {
-		return;
-	}
+    //mAudioEnv->ReleasePrimitiveArrayCritical((jarray)audioBuffer, audioBufferPinned, 0);
+    if (audioBuffer16Bit) {
+        mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
+        mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
+    } else {
+        mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
+        mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
+    }
 
-	if (audioBuffer16Bit) {
-		mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioPinnedBuffer, JNI_COMMIT);
-		mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
-	} else {
-		mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioPinnedBuffer, JNI_COMMIT);
-		mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
-	}
-
-	audioPinnedBuffer = NULL;
+    /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
 }
 
 extern "C" void Android_JNI_CloseAudioDevice()
 {
-    if (audioBuffer) {
-        mEnv->DeleteGlobalRef(audioBuffer);
-        audioBuffer = NULL;
-    }
+    mEnv->CallStaticVoidMethod(mActivityInstance, midAudioQuit); 
 
-	// TODO: Implement
+    mEnv->DeleteGlobalRef(audioBuffer);
+    audioBuffer = NULL;
 }
 
 /* vi: set ts=4 sw=4 expandtab: */