summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/audio/android/SDL_androidaudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/audio/android/SDL_androidaudio.c')
-rw-r--r--source/3rd-party/SDL2/src/audio/android/SDL_androidaudio.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/audio/android/SDL_androidaudio.c b/source/3rd-party/SDL2/src/audio/android/SDL_androidaudio.c
new file mode 100644
index 0000000..77a5f0d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/audio/android/SDL_androidaudio.c
@@ -0,0 +1,211 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_AUDIO_DRIVER_ANDROID
+
+/* Output audio to Android */
+
+#include "SDL_assert.h"
+#include "SDL_audio.h"
+#include "../SDL_audio_c.h"
+#include "SDL_androidaudio.h"
+
+#include "../../core/android/SDL_android.h"
+
+#include <android/log.h>
+
+static SDL_AudioDevice* audioDevice = NULL;
+static SDL_AudioDevice* captureDevice = NULL;
+
+static int
+ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
+{
+ SDL_AudioFormat test_format;
+
+ SDL_assert((captureDevice == NULL) || !iscapture);
+ SDL_assert((audioDevice == NULL) || iscapture);
+
+ if (iscapture) {
+ captureDevice = this;
+ } else {
+ 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 */
+ if ((test_format == AUDIO_U8) ||
+ (test_format == AUDIO_S16) ||
+ (test_format == AUDIO_F32)) {
+ this->spec.format = test_format;
+ break;
+ }
+ test_format = SDL_NextAudioFormat();
+ }
+
+ if (test_format == 0) {
+ /* Didn't find a compatible format :( */
+ return SDL_SetError("No compatible audio format!");
+ }
+
+ if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
+ return -1;
+ }
+
+ SDL_CalculateAudioSpec(&this->spec);
+
+ return 0;
+}
+
+static void
+ANDROIDAUDIO_PlayDevice(_THIS)
+{
+ Android_JNI_WriteAudioBuffer();
+}
+
+static Uint8 *
+ANDROIDAUDIO_GetDeviceBuf(_THIS)
+{
+ return Android_JNI_GetAudioBuffer();
+}
+
+static int
+ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
+{
+ return Android_JNI_CaptureAudioBuffer(buffer, buflen);
+}
+
+static void
+ANDROIDAUDIO_FlushCapture(_THIS)
+{
+ Android_JNI_FlushCapturedAudio();
+}
+
+static void
+ANDROIDAUDIO_CloseDevice(_THIS)
+{
+ /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
+ so it's safe to terminate the Java side buffer and AudioTrack
+ */
+ Android_JNI_CloseAudioDevice(this->iscapture);
+ if (this->iscapture) {
+ SDL_assert(captureDevice == this);
+ captureDevice = NULL;
+ } else {
+ SDL_assert(audioDevice == this);
+ audioDevice = NULL;
+ }
+ SDL_free(this->hidden);
+}
+
+static int
+ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
+{
+ /* Set the function pointers */
+ impl->OpenDevice = ANDROIDAUDIO_OpenDevice;
+ impl->PlayDevice = ANDROIDAUDIO_PlayDevice;
+ impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf;
+ impl->CloseDevice = ANDROIDAUDIO_CloseDevice;
+ impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice;
+ impl->FlushCapture = ANDROIDAUDIO_FlushCapture;
+
+ /* and the capabilities */
+ impl->HasCaptureSupport = SDL_TRUE;
+ impl->OnlyHasDefaultOutputDevice = 1;
+ impl->OnlyHasDefaultCaptureDevice = 1;
+
+ return 1; /* this audio target is available. */
+}
+
+AudioBootStrap ANDROIDAUDIO_bootstrap = {
+ "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0
+};
+
+/* Pause (block) all non already paused audio devices by taking their mixer lock */
+void ANDROIDAUDIO_PauseDevices(void)
+{
+ /* TODO: Handle multiple devices? */
+ struct SDL_PrivateAudioData *private;
+ if(audioDevice != NULL && audioDevice->hidden != NULL) {
+ private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
+ if (SDL_AtomicGet(&audioDevice->paused)) {
+ /* The device is already paused, leave it alone */
+ private->resume = SDL_FALSE;
+ }
+ else {
+ SDL_LockMutex(audioDevice->mixer_lock);
+ SDL_AtomicSet(&audioDevice->paused, 1);
+ private->resume = SDL_TRUE;
+ }
+ }
+
+ if(captureDevice != NULL && captureDevice->hidden != NULL) {
+ private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
+ if (SDL_AtomicGet(&captureDevice->paused)) {
+ /* The device is already paused, leave it alone */
+ private->resume = SDL_FALSE;
+ }
+ else {
+ SDL_LockMutex(captureDevice->mixer_lock);
+ SDL_AtomicSet(&captureDevice->paused, 1);
+ private->resume = SDL_TRUE;
+ }
+ }
+}
+
+/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */
+void ANDROIDAUDIO_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) {
+ SDL_AtomicSet(&audioDevice->paused, 0);
+ private->resume = SDL_FALSE;
+ SDL_UnlockMutex(audioDevice->mixer_lock);
+ }
+ }
+
+ if(captureDevice != NULL && captureDevice->hidden != NULL) {
+ private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
+ if (private->resume) {
+ SDL_AtomicSet(&captureDevice->paused, 0);
+ private->resume = SDL_FALSE;
+ SDL_UnlockMutex(captureDevice->mixer_lock);
+ }
+ }
+}
+
+#else
+
+void ANDROIDAUDIO_ResumeDevices(void) {}
+void ANDROIDAUDIO_PauseDevices(void) {}
+
+#endif /* SDL_AUDIO_DRIVER_ANDROID */
+
+/* vi: set ts=4 sw=4 expandtab: */
+