SDL 2.0
SDL_androidaudio.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "../../SDL_internal.h"
22
23#if SDL_AUDIO_DRIVER_ANDROID
24
25/* Output audio to Android */
26
27#include "SDL_assert.h"
28#include "SDL_audio.h"
29#include "../SDL_audio_c.h"
30#include "SDL_androidaudio.h"
31
32#include "../../core/android/SDL_android.h"
33
34#include <android/log.h>
35
36static SDL_AudioDevice* audioDevice = NULL;
37static SDL_AudioDevice* captureDevice = NULL;
38
39static int
40ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
41{
42 SDL_AudioFormat test_format;
43
44 SDL_assert((captureDevice == NULL) || !iscapture);
45 SDL_assert((audioDevice == NULL) || iscapture);
46
47 if (iscapture) {
48 captureDevice = this;
49 } else {
50 audioDevice = this;
51 }
52
53 this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
54 if (this->hidden == NULL) {
55 return SDL_OutOfMemory();
56 }
57
58 test_format = SDL_FirstAudioFormat(this->spec.format);
59 while (test_format != 0) { /* no "UNKNOWN" constant */
60 if ((test_format == AUDIO_U8) ||
61 (test_format == AUDIO_S16) ||
62 (test_format == AUDIO_F32)) {
63 this->spec.format = test_format;
64 break;
65 }
66 test_format = SDL_NextAudioFormat();
67 }
68
69 if (test_format == 0) {
70 /* Didn't find a compatible format :( */
71 return SDL_SetError("No compatible audio format!");
72 }
73
75 return -1;
76 }
77
79
80 return 0;
81}
82
83static void
84ANDROIDAUDIO_PlayDevice(_THIS)
85{
87}
88
89static Uint8 *
90ANDROIDAUDIO_GetDeviceBuf(_THIS)
91{
93}
94
95static int
96ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
97{
99}
100
101static void
102ANDROIDAUDIO_FlushCapture(_THIS)
103{
105}
106
107static void
108ANDROIDAUDIO_CloseDevice(_THIS)
109{
110 /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
111 so it's safe to terminate the Java side buffer and AudioTrack
112 */
113 Android_JNI_CloseAudioDevice(this->iscapture);
114 if (this->iscapture) {
115 SDL_assert(captureDevice == this);
116 captureDevice = NULL;
117 } else {
118 SDL_assert(audioDevice == this);
119 audioDevice = NULL;
120 }
121 SDL_free(this->hidden);
122}
123
124static int
125ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
126{
127 /* Set the function pointers */
128 impl->OpenDevice = ANDROIDAUDIO_OpenDevice;
129 impl->PlayDevice = ANDROIDAUDIO_PlayDevice;
130 impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf;
131 impl->CloseDevice = ANDROIDAUDIO_CloseDevice;
132 impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice;
133 impl->FlushCapture = ANDROIDAUDIO_FlushCapture;
134
135 /* and the capabilities */
139
140 return 1; /* this audio target is available. */
141}
142
144 "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0
145};
146
147/* Pause (block) all non already paused audio devices by taking their mixer lock */
149{
150 /* TODO: Handle multiple devices? */
151 struct SDL_PrivateAudioData *private;
152 if(audioDevice != NULL && audioDevice->hidden != NULL) {
153 private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
154 if (SDL_AtomicGet(&audioDevice->paused)) {
155 /* The device is already paused, leave it alone */
156 private->resume = SDL_FALSE;
157 }
158 else {
159 SDL_LockMutex(audioDevice->mixer_lock);
160 SDL_AtomicSet(&audioDevice->paused, 1);
161 private->resume = SDL_TRUE;
162 }
163 }
164
165 if(captureDevice != NULL && captureDevice->hidden != NULL) {
166 private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
167 if (SDL_AtomicGet(&captureDevice->paused)) {
168 /* The device is already paused, leave it alone */
169 private->resume = SDL_FALSE;
170 }
171 else {
172 SDL_LockMutex(captureDevice->mixer_lock);
173 SDL_AtomicSet(&captureDevice->paused, 1);
174 private->resume = SDL_TRUE;
175 }
176 }
177}
178
179/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */
181{
182 /* TODO: Handle multiple devices? */
183 struct SDL_PrivateAudioData *private;
184 if(audioDevice != NULL && audioDevice->hidden != NULL) {
185 private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
186 if (private->resume) {
187 SDL_AtomicSet(&audioDevice->paused, 0);
188 private->resume = SDL_FALSE;
189 SDL_UnlockMutex(audioDevice->mixer_lock);
190 }
191 }
192
193 if(captureDevice != NULL && captureDevice->hidden != NULL) {
194 private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
195 if (private->resume) {
196 SDL_AtomicSet(&captureDevice->paused, 0);
197 private->resume = SDL_FALSE;
198 SDL_UnlockMutex(captureDevice->mixer_lock);
199 }
200 }
201}
202
203#else
204
207
208#endif /* SDL_AUDIO_DRIVER_ANDROID */
209
210/* vi: set ts=4 sw=4 expandtab: */
211
#define _THIS
int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
void Android_JNI_FlushCapturedAudio(void)
int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
void Android_JNI_CloseAudioDevice(const int iscapture)
void Android_JNI_WriteAudioBuffer(void)
void * Android_JNI_GetAudioBuffer(void)
void ANDROIDAUDIO_PauseDevices(void)
void ANDROIDAUDIO_ResumeDevices(void)
#define SDL_assert(condition)
Definition: SDL_assert.h:169
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1668
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
Definition: SDL_audio.c:1647
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1659
#define AUDIO_F32
Definition: SDL_audio.h:114
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
#define AUDIO_S16
Definition: SDL_audio.h:96
#define AUDIO_U8
Definition: SDL_audio.h:89
#define SDL_AtomicSet
#define SDL_SetError
#define SDL_LockMutex
#define SDL_free
#define SDL_AtomicGet
#define SDL_calloc
#define SDL_UnlockMutex
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define private
Definition: SDL_naclaudio.h:34
GLuint buffer
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint8_t Uint8
Definition: SDL_stdinc.h:179
AudioBootStrap ANDROIDAUDIO_bootstrap
#define NULL
Definition: begin_code.h:167
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
SDL_AudioSpec spec
Definition: loopwave.c:31
SDL_atomic_t paused
Definition: SDL_sysaudio.h:149
struct SDL_PrivateAudioData * hidden
Definition: SDL_sysaudio.h:170
SDL_mutex * mixer_lock
Definition: SDL_sysaudio.h:159
void(* PlayDevice)(_THIS)
Definition: SDL_sysaudio.h:73
void(* CloseDevice)(_THIS)
Definition: SDL_sysaudio.h:78
void(* FlushCapture)(_THIS)
Definition: SDL_sysaudio.h:76
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
Definition: SDL_sysaudio.h:75
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Definition: SDL_sysaudio.h:68
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:74
SDL_AudioFormat format
Definition: SDL_audio.h:181