SDL  2.0
SDL_androidaudio.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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_audio.h"
28 #include "../SDL_audio_c.h"
29 #include "SDL_androidaudio.h"
30 
31 #include "../../core/android/SDL_android.h"
32 
33 #include <android/log.h>
34 
35 static SDL_AudioDevice* audioDevice = NULL;
36 static SDL_AudioDevice* captureDevice = NULL;
37 
38 static int
39 ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
40 {
41  SDL_AudioFormat test_format;
42 
43  SDL_assert((captureDevice == NULL) || !iscapture);
44  SDL_assert((audioDevice == NULL) || iscapture);
45 
46  if (iscapture) {
47  captureDevice = this;
48  } else {
49  audioDevice = this;
50  }
51 
52  this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
53  if (this->hidden == NULL) {
54  return SDL_OutOfMemory();
55  }
56 
57  test_format = SDL_FirstAudioFormat(this->spec.format);
58  while (test_format != 0) { /* no "UNKNOWN" constant */
59  if ((test_format == AUDIO_U8) ||
60  (test_format == AUDIO_S16) ||
61  (test_format == AUDIO_F32)) {
62  this->spec.format = test_format;
63  break;
64  }
65  test_format = SDL_NextAudioFormat();
66  }
67 
68  if (test_format == 0) {
69  /* Didn't find a compatible format :( */
70  return SDL_SetError("No compatible audio format!");
71  }
72 
73  if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
74  return -1;
75  }
76 
78 
79  return 0;
80 }
81 
82 static void
83 ANDROIDAUDIO_PlayDevice(_THIS)
84 {
86 }
87 
88 static Uint8 *
89 ANDROIDAUDIO_GetDeviceBuf(_THIS)
90 {
92 }
93 
94 static int
95 ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
96 {
97  return Android_JNI_CaptureAudioBuffer(buffer, buflen);
98 }
99 
100 static void
101 ANDROIDAUDIO_FlushCapture(_THIS)
102 {
104 }
105 
106 static void
107 ANDROIDAUDIO_CloseDevice(_THIS)
108 {
109  /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
110  so it's safe to terminate the Java side buffer and AudioTrack
111  */
112  Android_JNI_CloseAudioDevice(this->iscapture);
113  if (this->iscapture) {
114  SDL_assert(captureDevice == this);
115  captureDevice = NULL;
116  } else {
117  SDL_assert(audioDevice == this);
118  audioDevice = NULL;
119  }
120  SDL_free(this->hidden);
121 }
122 
123 static int
124 ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
125 {
126  /* Set the function pointers */
127  impl->OpenDevice = ANDROIDAUDIO_OpenDevice;
128  impl->PlayDevice = ANDROIDAUDIO_PlayDevice;
129  impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf;
130  impl->CloseDevice = ANDROIDAUDIO_CloseDevice;
131  impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice;
132  impl->FlushCapture = ANDROIDAUDIO_FlushCapture;
133 
134  /* and the capabilities */
135  impl->HasCaptureSupport = SDL_TRUE;
136  impl->OnlyHasDefaultOutputDevice = 1;
137  impl->OnlyHasDefaultCaptureDevice = 1;
138 
139  return 1; /* this audio target is available. */
140 }
141 
143  "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0
144 };
145 
146 /* Pause (block) all non already paused audio devices by taking their mixer lock */
147 void ANDROIDAUDIO_PauseDevices(void)
148 {
149  /* TODO: Handle multiple devices? */
150  struct SDL_PrivateAudioData *private;
151  if(audioDevice != NULL && audioDevice->hidden != NULL) {
152  private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
153  if (SDL_AtomicGet(&audioDevice->paused)) {
154  /* The device is already paused, leave it alone */
155  private->resume = SDL_FALSE;
156  }
157  else {
158  SDL_LockMutex(audioDevice->mixer_lock);
159  SDL_AtomicSet(&audioDevice->paused, 1);
160  private->resume = SDL_TRUE;
161  }
162  }
163 
164  if(captureDevice != NULL && captureDevice->hidden != NULL) {
165  private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
166  if (SDL_AtomicGet(&captureDevice->paused)) {
167  /* The device is already paused, leave it alone */
168  private->resume = SDL_FALSE;
169  }
170  else {
171  SDL_LockMutex(captureDevice->mixer_lock);
172  SDL_AtomicSet(&captureDevice->paused, 1);
173  private->resume = SDL_TRUE;
174  }
175  }
176 }
177 
178 /* Resume (unblock) all non already paused audio devices by releasing their mixer lock */
180 {
181  /* TODO: Handle multiple devices? */
182  struct SDL_PrivateAudioData *private;
183  if(audioDevice != NULL && audioDevice->hidden != NULL) {
184  private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
185  if (private->resume) {
186  SDL_AtomicSet(&audioDevice->paused, 0);
187  private->resume = SDL_FALSE;
188  SDL_UnlockMutex(audioDevice->mixer_lock);
189  }
190  }
191 
192  if(captureDevice != NULL && captureDevice->hidden != NULL) {
193  private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
194  if (private->resume) {
195  SDL_AtomicSet(&captureDevice->paused, 0);
196  private->resume = SDL_FALSE;
197  SDL_UnlockMutex(captureDevice->mixer_lock);
198  }
199  }
200 }
201 
202 #else
203 
206 
207 #endif /* SDL_AUDIO_DRIVER_ANDROID */
208 
209 /* vi: set ts=4 sw=4 expandtab: */
210 
#define _THIS
int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
void * Android_JNI_GetAudioBuffer(void)
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 ANDROIDAUDIO_PauseDevices(void)
void ANDROIDAUDIO_ResumeDevices(void)
#define SDL_assert(condition)
Definition: SDL_assert.h:171
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1689
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
Definition: SDL_audio.c:1650
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1662
#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:88
#define private
Definition: SDL_naclaudio.h:34
GLuint buffer
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
uint8_t Uint8
Definition: SDL_stdinc.h:185
AudioBootStrap ANDROIDAUDIO_bootstrap
#define NULL
Definition: begin_code.h:163
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
SDL_AudioSpec spec
Definition: loopwave.c:31
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
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
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:74
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
SDL_AudioFormat format
Definition: SDL_audio.h:181