diff options
-rw-r--r-- | backends/platform/android/android.cpp | 53 | ||||
-rw-r--r-- | backends/platform/android/jni.cpp | 11 | ||||
-rw-r--r-- | backends/platform/android/jni.h | 1 |
3 files changed, 57 insertions, 8 deletions
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp index 08b957999e..860ff1f7ee 100644 --- a/backends/platform/android/android.cpp +++ b/backends/platform/android/android.cpp @@ -163,8 +163,6 @@ void *OSystem_Android::timerThreadFunc(void *arg) { void *OSystem_Android::audioThreadFunc(void *arg) { JNI::attachThread(); - JNI::setAudioPlay(); - OSystem_Android *system = (OSystem_Android *)arg; Audio::MixerImpl *mixer = system->_mixer; @@ -174,21 +172,60 @@ void *OSystem_Android::audioThreadFunc(void *arg) { jbyteArray bufa = env->NewByteArray(buf_size); + bool paused = true; + byte *buf; int offset, left, written; + int samples; - struct timespec tv; - tv.tv_sec = 0; - tv.tv_nsec = 20 * 1000 * 1000; + struct timespec tv_delay; + tv_delay.tv_sec = 0; + tv_delay.tv_nsec = 20 * 1000 * 1000; + + uint msecs_full = buf_size * 1000 / (mixer->getOutputRate() * 2 * 2); + + struct timespec tv_full; + tv_full.tv_sec = 0; + tv_full.tv_nsec = msecs_full * 1000 * 1000; + + uint silence_count = 0; while (!system->_audio_thread_exit) { buf = (byte *)env->GetPrimitiveArrayCritical(bufa, 0); assert(buf); - mixer->mixCallback(buf, buf_size); + samples = mixer->mixCallback(buf, buf_size); env->ReleasePrimitiveArrayCritical(bufa, buf, 0); + if (samples < 1) { + if (!paused) + silence_count++; + + // only pause after a while to prevent toggle mania + if (silence_count > 32) { + if (!paused) { + LOGD("AudioTrack pause"); + + JNI::setAudioPause(); + paused = true; + } + + nanosleep(&tv_full, 0); + + continue; + } + } + + if (paused) { + LOGD("AudioTrack play"); + + JNI::setAudioPlay(); + paused = false; + + silence_count = 0; + } + offset = 0; left = buf_size; written = 0; @@ -203,7 +240,7 @@ void *OSystem_Android::audioThreadFunc(void *arg) { // buffer full if (written < left) - nanosleep(&tv, 0); + nanosleep(&tv_delay, 0); offset += written; left -= written; @@ -214,7 +251,7 @@ void *OSystem_Android::audioThreadFunc(void *arg) { // sleep a little, prepare the next buffer, and run into the // blocking AudioTrack.write - nanosleep(&tv, 0); + nanosleep(&tv_delay, 0); } JNI::setAudioStop(); diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp index 5e11203db8..8964fe63d8 100644 --- a/backends/platform/android/jni.cpp +++ b/backends/platform/android/jni.cpp @@ -64,6 +64,7 @@ jmethodID JNI::_MID_setupScummVMSurface = 0; jmethodID JNI::_MID_destroyScummVMSurface = 0; jmethodID JNI::_MID_swapBuffers = 0; +jmethodID JNI::_MID_AudioTrack_flush = 0; jmethodID JNI::_MID_AudioTrack_pause = 0; jmethodID JNI::_MID_AudioTrack_play = 0; jmethodID JNI::_MID_AudioTrack_stop = 0; @@ -332,6 +333,15 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { void JNI::setAudioPause() { JNIEnv *env = JNI::getEnv(); + env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_flush); + + if (env->ExceptionCheck()) { + warning("Error flushing AudioTrack"); + + env->ExceptionDescribe(); + env->ExceptionClear(); + } + env->CallVoidMethod(_jobj_audio_track, _MID_AudioTrack_pause); if (env->ExceptionCheck()) { @@ -417,6 +427,7 @@ void JNI::create(JNIEnv *env, jobject self, jobject am, jobject at, return; \ } while (0) + FIND_METHOD(flush, "()V"); FIND_METHOD(pause, "()V"); FIND_METHOD(play, "()V"); FIND_METHOD(stop, "()V"); diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h index a1fc3df67e..0bc64980e2 100644 --- a/backends/platform/android/jni.h +++ b/backends/platform/android/jni.h @@ -95,6 +95,7 @@ private: static jmethodID _MID_destroyScummVMSurface; static jmethodID _MID_swapBuffers; + static jmethodID _MID_AudioTrack_flush; static jmethodID _MID_AudioTrack_pause; static jmethodID _MID_AudioTrack_play; static jmethodID _MID_AudioTrack_stop; |