From 476580576efadf6601e3bd9ece8f55476caea161 Mon Sep 17 00:00:00 2001 From: Gabriel Jacobo Date: Thu, 18 Sep 2014 11:03:34 -0300 Subject: [PATCH] [Android] Better fix for #2480, pause/resume audio --- src/audio/SDL_audio.c | 17 +++------- src/audio/android/SDL_androidaudio.c | 46 ++++++++++++++++++++++++++- src/audio/android/SDL_androidaudio.h | 2 ++ src/video/android/SDL_androidevents.c | 9 ++++-- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 326bef63c259e..7559d6ca46e80 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -1348,26 +1348,17 @@ void SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) { SDL_AudioDevice *device = get_audio_device(devid); - if (device && device->paused != pause_on) { - if (pause_on) { - current_audio.impl.LockDevice(device); - } + if (device) { + current_audio.impl.LockDevice(device); device->paused = pause_on; - if (!pause_on) { - current_audio.impl.UnlockDevice(device); - } + current_audio.impl.UnlockDevice(device); } } void SDL_PauseAudio(int pause_on) { - int id; - for (id = 0; id < SDL_arraysize(open_devices); id++) { - if (open_devices[id] != NULL) { - SDL_PauseAudioDevice(id+1, pause_on); - } - } + SDL_PauseAudioDevice(1, pause_on); } diff --git a/src/audio/android/SDL_androidaudio.c b/src/audio/android/SDL_androidaudio.c index 0c85b83cbf8d1..fe66763b8ced9 100644 --- a/src/audio/android/SDL_androidaudio.c +++ b/src/audio/android/SDL_androidaudio.c @@ -32,7 +32,7 @@ #include -static void * audioDevice; +static SDL_AudioDevice* audioDevice = NULL; static int AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture) @@ -49,6 +49,11 @@ AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture) } audioDevice = this; + + this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden)); + if (this->hidden == NULL) { + return SDL_OutOfMemory(); + } test_format = SDL_FirstAudioFormat(this->spec.format); while (test_format != 0) { /* no "UNKNOWN" constant */ @@ -110,6 +115,10 @@ AndroidAUD_CloseDevice(_THIS) Android_JNI_CloseAudioDevice(); if (audioDevice == this) { + if (audioDevice->hidden != NULL) { + SDL_free(this->hidden); + this->hidden = NULL; + } audioDevice = NULL; } } @@ -135,6 +144,41 @@ AudioBootStrap ANDROIDAUD_bootstrap = { "android", "SDL Android audio driver", AndroidAUD_Init, 0 }; +/* Pause (block) all non already paused audio devices by taking their mixer lock */ +void AndroidAUD_PauseDevices(void) +{ + /* TODO: Handle multiple devices? */ + struct SDL_PrivateAudioData *private; + if(audioDevice != NULL && audioDevice->hidden != NULL) { + private = (struct SDL_PrivateAudioData *) audioDevice->hidden; + if (audioDevice->paused) { + /* The device is already paused, leave it alone */ + private->resume = SDL_FALSE; + } + else { + SDL_LockMutex(audioDevice->mixer_lock); + audioDevice->paused = SDL_TRUE; + private->resume = SDL_TRUE; + } + } +} + +/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */ +void AndroidAUD_ResumeDevices(void) +{ + /* TODO: Handle multiple devices? */ + struct SDL_PrivateAudioData *private; + if(audioDevice != NULL && audioDevice->hidden != NULL) { + private = (struct SDL_PrivateAudioData *) audioDevice->hidden; + if (private->resume) { + audioDevice->paused = SDL_FALSE; + private->resume = SDL_FALSE; + SDL_UnlockMutex(audioDevice->mixer_lock); + } + } +} + + #endif /* SDL_AUDIO_DRIVER_ANDROID */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/android/SDL_androidaudio.h b/src/audio/android/SDL_androidaudio.h index ab49f000f9c0b..77bb219da26a7 100644 --- a/src/audio/android/SDL_androidaudio.h +++ b/src/audio/android/SDL_androidaudio.h @@ -30,6 +30,8 @@ struct SDL_PrivateAudioData { + /* Resume device if it was paused automatically */ + int resume; }; static void AndroidAUD_CloseDevice(_THIS); diff --git a/src/video/android/SDL_androidevents.c b/src/video/android/SDL_androidevents.c index 51d3c4bd140f2..2662d1b3dd5f6 100644 --- a/src/video/android/SDL_androidevents.c +++ b/src/video/android/SDL_androidevents.c @@ -29,8 +29,11 @@ #include "SDL_events.h" #include "SDL_androidwindow.h" + void android_egl_context_backup(); void android_egl_context_restore(); +void AndroidAUD_ResumeDevices(void); +void AndroidAUD_PauseDevices(void); void android_egl_context_restore() @@ -74,14 +77,14 @@ Android_PumpEvents(_THIS) if (isPaused && !isPausing) { /* Make sure this is the last thing we do before pausing */ android_egl_context_backup(); - SDL_PauseAudio(1); + AndroidAUD_PauseDevices(); if(SDL_SemWait(Android_ResumeSem) == 0) { #else if (isPaused) { if(SDL_SemTryWait(Android_ResumeSem) == 0) { #endif isPaused = 0; - SDL_PauseAudio(0); + AndroidAUD_ResumeDevices(); /* Restore the GL Context from here, as this operation is thread dependent */ if (!SDL_HasEvent(SDL_QUIT)) { android_egl_context_restore(); @@ -104,7 +107,7 @@ Android_PumpEvents(_THIS) #else if(SDL_SemTryWait(Android_PauseSem) == 0) { android_egl_context_backup(); - SDL_PauseAudio(1); + AndroidAUD_PauseDevices(); isPaused = 1; } #endif