[Android] Better fix for #2480, pause/resume audio
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 326bef6..7559d6c 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 0c85b83..fe66763 100644
--- a/src/audio/android/SDL_androidaudio.c
+++ b/src/audio/android/SDL_androidaudio.c
@@ -32,7 +32,7 @@
#include <android/log.h>
-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 ab49f00..77bb219 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 51d3c4b..2662d1b 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