Fix Audio Buffer allocation on Android >= 4.2
authorGabriel Jacobo <gabomdq@gmail.com>
Mon, 07 Jan 2013 12:22:26 -0300
changeset 68028a6b8ce97656
parent 6801 f92e3d5f71a2
child 6804 a91717ac8ff1
Fix Audio Buffer allocation on Android >= 4.2
android-project/src/org/libsdl/app/SDLActivity.java
src/core/android/SDL_android.cpp
     1.1 --- a/android-project/src/org/libsdl/app/SDLActivity.java	Sun Jan 06 18:19:30 2013 -0800
     1.2 +++ b/android-project/src/org/libsdl/app/SDLActivity.java	Mon Jan 07 12:22:26 2013 -0300
     1.3 @@ -353,8 +353,6 @@
     1.4      }
     1.5  
     1.6      // Audio
     1.7 -    private static Object buf;
     1.8 -    
     1.9      public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
    1.10          int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
    1.11          int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
    1.12 @@ -373,13 +371,6 @@
    1.13          audioStartThread();
    1.14          
    1.15          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");
    1.16 -        
    1.17 -        if (is16Bit) {
    1.18 -            buf = new short[desiredFrames * (isStereo ? 2 : 1)];
    1.19 -        } else {
    1.20 -            buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; 
    1.21 -        }
    1.22 -        return buf;
    1.23      }
    1.24      
    1.25      public static void audioStartThread() {
     2.1 --- a/src/core/android/SDL_android.cpp	Sun Jan 06 18:19:30 2013 -0800
     2.2 +++ b/src/core/android/SDL_android.cpp	Mon Jan 07 12:22:26 2013 -0300
     2.3 @@ -120,7 +120,7 @@
     2.4      midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass,
     2.5                                  "flipBuffers","()V");
     2.6      midAudioInit = mEnv->GetStaticMethodID(mActivityClass, 
     2.7 -                                "audioInit", "(IZZI)Ljava/lang/Object;");
     2.8 +                                "audioInit", "(IZZI)V");
     2.9      midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass,
    2.10                                  "audioWriteShortBuffer", "([S)V");
    2.11      midAudioWriteByteBuffer = mEnv->GetStaticMethodID(mActivityClass,
    2.12 @@ -433,13 +433,30 @@
    2.13      audioBuffer16Bit = is16Bit;
    2.14      audioBufferStereo = channelCount > 1;
    2.15  
    2.16 -    audioBuffer = env->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
    2.17 +    env->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
    2.18 +
    2.19 +    /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
    2.20 +     * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */
    2.21 +    
    2.22 +    if (is16Bit) {
    2.23 +        jshortArray audioBufferLocal = env->NewShortArray(desiredBufferFrames * (audioBufferStereo ? 2 : 1));
    2.24 +        if (audioBufferLocal) {
    2.25 +            audioBuffer = env->NewGlobalRef(audioBufferLocal);
    2.26 +            env->DeleteLocalRef(audioBufferLocal);
    2.27 +        }
    2.28 +    }
    2.29 +    else {
    2.30 +        jbyteArray audioBufferLocal = env->NewByteArray(desiredBufferFrames * (audioBufferStereo ? 2 : 1));
    2.31 +        if (audioBufferLocal) {
    2.32 +            audioBuffer = env->NewGlobalRef(audioBufferLocal);
    2.33 +            env->DeleteLocalRef(audioBufferLocal);
    2.34 +        }
    2.35 +    }
    2.36  
    2.37      if (audioBuffer == NULL) {
    2.38 -        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
    2.39 +        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!");
    2.40          return 0;
    2.41      }
    2.42 -    audioBuffer = env->NewGlobalRef(audioBuffer);
    2.43  
    2.44      jboolean isCopy = JNI_FALSE;
    2.45      if (audioBuffer16Bit) {