Merged with tip
authorAndreas Schiffler <aschiffler@ferzkopp.net>
Mon, 07 Jan 2013 07:39:46 -0800
changeset 6804 a91717ac8ff1
parent 6803 fbe83a6d10fa (current diff)
parent 6802 8a6b8ce97656 (diff)
child 6805 ef2ef554b662
Merged with tip
--- a/android-project/src/org/libsdl/app/SDLActivity.java	Mon Jan 07 07:39:15 2013 -0800
+++ b/android-project/src/org/libsdl/app/SDLActivity.java	Mon Jan 07 07:39:46 2013 -0800
@@ -353,8 +353,6 @@
     }
 
     // Audio
-    private static Object buf;
-    
     public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
         int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
         int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
@@ -373,13 +371,6 @@
         audioStartThread();
         
         Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
-        
-        if (is16Bit) {
-            buf = new short[desiredFrames * (isStereo ? 2 : 1)];
-        } else {
-            buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; 
-        }
-        return buf;
     }
     
     public static void audioStartThread() {
--- a/src/core/android/SDL_android.cpp	Mon Jan 07 07:39:15 2013 -0800
+++ b/src/core/android/SDL_android.cpp	Mon Jan 07 07:39:46 2013 -0800
@@ -120,7 +120,7 @@
     midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass,
                                 "flipBuffers","()V");
     midAudioInit = mEnv->GetStaticMethodID(mActivityClass, 
-                                "audioInit", "(IZZI)Ljava/lang/Object;");
+                                "audioInit", "(IZZI)V");
     midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass,
                                 "audioWriteShortBuffer", "([S)V");
     midAudioWriteByteBuffer = mEnv->GetStaticMethodID(mActivityClass,
@@ -433,13 +433,30 @@
     audioBuffer16Bit = is16Bit;
     audioBufferStereo = channelCount > 1;
 
-    audioBuffer = env->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
+    env->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
+
+    /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
+     * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */
+    
+    if (is16Bit) {
+        jshortArray audioBufferLocal = env->NewShortArray(desiredBufferFrames * (audioBufferStereo ? 2 : 1));
+        if (audioBufferLocal) {
+            audioBuffer = env->NewGlobalRef(audioBufferLocal);
+            env->DeleteLocalRef(audioBufferLocal);
+        }
+    }
+    else {
+        jbyteArray audioBufferLocal = env->NewByteArray(desiredBufferFrames * (audioBufferStereo ? 2 : 1));
+        if (audioBufferLocal) {
+            audioBuffer = env->NewGlobalRef(audioBufferLocal);
+            env->DeleteLocalRef(audioBufferLocal);
+        }
+    }
 
     if (audioBuffer == NULL) {
-        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
+        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!");
         return 0;
     }
-    audioBuffer = env->NewGlobalRef(audioBuffer);
 
     jboolean isCopy = JNI_FALSE;
     if (audioBuffer16Bit) {