aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordhewg2011-02-26 18:44:17 +0100
committerdhewg2011-02-27 09:04:37 +0100
commit0e869a5cf0e455f7cd5ce5c39192f3433b931e97 (patch)
tree992bc587994ce7fd3bf9048438b1881dcf3b94be
parentbea57f695064c6f084ff26405d91b812848fee33 (diff)
downloadscummvm-rg350-0e869a5cf0e455f7cd5ce5c39192f3433b931e97.tar.gz
scummvm-rg350-0e869a5cf0e455f7cd5ce5c39192f3433b931e97.tar.bz2
scummvm-rg350-0e869a5cf0e455f7cd5ce5c39192f3433b931e97.zip
ANDROID: Pause the AudioTrack when possible
Only works in situations without any registered channels (or all paused) at the mixer (like on the launcher or GMM). CPU usage before (Galaxy Tab): ~5% scummvm ~15% mediaserver After: ~2% scummvm 0% mediaserver ;)
-rw-r--r--backends/platform/android/android.cpp53
-rw-r--r--backends/platform/android/jni.cpp11
-rw-r--r--backends/platform/android/jni.h1
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;