diff --git a/modules/juce_audio_devices/native/juce_android_Audio.cpp b/modules/juce_audio_devices/native/juce_android_Audio.cpp index 66634137f0..42f6fdd98e 100644 --- a/modules/juce_audio_devices/native/juce_android_Audio.cpp +++ b/modules/juce_audio_devices/native/juce_android_Audio.cpp @@ -33,7 +33,6 @@ namespace juce METHOD (release, "release", "()V") \ METHOD (flush, "flush", "()V") \ METHOD (write, "write", "([SII)I") \ - METHOD (getUnderrunCount, "getUnderrunCount", "()I") \ DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack"); #undef JNI_CLASS_MEMBERS @@ -51,6 +50,13 @@ DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack"); DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord"); #undef JNI_CLASS_MEMBERS +//============================================================================== +#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ + STATICFIELD (SDK_INT, "SDK_INT", "I") \ + + DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION"); +#undef JNI_CLASS_MEMBERS + //============================================================================== enum { @@ -196,6 +202,9 @@ public: STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, (jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast (sizeof (int16))), MODE_STREAM)); + const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); + getUnderrunCount = supportsUnderrunCount ? env->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0; + int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState); if (outputDeviceState > 0) { @@ -284,8 +293,8 @@ public: int getXRunCount() const noexcept override { - if (outputDevice != nullptr) - return getEnv()->CallIntMethod (outputDevice, AudioTrack.getUnderrunCount); + if (outputDevice != nullptr && getUnderrunCount != 0) + return getEnv()->CallIntMethod (outputDevice, getUnderrunCount); return -1; } @@ -415,6 +424,7 @@ private: BigInteger activeOutputChans, activeInputChans; GlobalRef outputDevice, inputDevice; AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; + jmethodID getUnderrunCount = 0; void closeDevices() { diff --git a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp index 9da627fe0d..48cd2fe918 100644 --- a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp +++ b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp @@ -23,12 +23,6 @@ namespace juce { -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ -STATICFIELD (SDK_INT, "SDK_INT", "I") \ - -DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION"); -#undef JNI_CLASS_MEMBERS - //============================================================================== #ifndef SL_ANDROID_DATAFORMAT_PCM_EX #define SL_ANDROID_DATAFORMAT_PCM_EX ((SLuint32) 0x00000004) @@ -306,15 +300,22 @@ public: if (runner == nullptr) return false; - // may return nullptr on some platforms - that's ok - config = SlRef::cast (runner); - if (config != nullptr) - { - jobject audioRoutingJni; - auto status = (*config)->AcquireJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING, &audioRoutingJni); + const bool supportsJavaProxy = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); - if (status == SL_RESULT_SUCCESS && audioRoutingJni != 0) - javaProxy = GlobalRef (audioRoutingJni); + if (supportsJavaProxy) + { + // may return nullptr on some platforms - that's ok + config = SlRef::cast (runner); + + if (config != nullptr) + { + jobject audioRoutingJni; + auto status = (*config)->AcquireJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING, + &audioRoutingJni); + + if (status == SL_RESULT_SUCCESS && audioRoutingJni != 0) + javaProxy = GlobalRef (audioRoutingJni); + } } queue = SlRef::cast (runner); @@ -634,6 +635,9 @@ public: player = nullptr; return; } + + const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); + getUnderrunCount = supportsUnderrunCount ? getEnv()->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0; } } } @@ -698,8 +702,8 @@ public: int getXRunCount() const noexcept override { - if (player != nullptr && player->javaProxy != nullptr) - return getEnv()->CallIntMethod (player->javaProxy, AudioTrack.getUnderrunCount); + if (player != nullptr && player->javaProxy != nullptr && getUnderrunCount != 0) + return getEnv()->CallIntMethod (player->javaProxy, getUnderrunCount); return -1; } @@ -754,6 +758,7 @@ public: ScopedPointer > player; ScopedPointer > recorder; Atomic guard; + jmethodID getUnderrunCount = 0; }; //==============================================================================