Atlas - SDL_androidaudio.c

Home / ext / SDL2 / src / audio / android Lines: 1 | Size: 6782 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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) || (test_format == AUDIO_S16LSB)) { 61 this->spec.format = test_format; 62 break; 63 } 64 test_format = SDL_NextAudioFormat(); 65 } 66 67 if (test_format == 0) { 68 /* Didn't find a compatible format :( */ 69 return SDL_SetError("No compatible audio format!"); 70 } 71 72 if (this->spec.channels > 1) { 73 this->spec.channels = 2; 74 } else { 75 this->spec.channels = 1; 76 } 77 78 if (this->spec.freq < 8000) { 79 this->spec.freq = 8000; 80 } 81 if (this->spec.freq > 48000) { 82 this->spec.freq = 48000; 83 } 84 85 /* TODO: pass in/return a (Java) device ID */ 86 this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples); 87 88 if (this->spec.samples == 0) { 89 /* Init failed? */ 90 return SDL_SetError("Java-side initialization failed!"); 91 } 92 93 SDL_CalculateAudioSpec(&this->spec); 94 95 return 0; 96} 97 98static void 99ANDROIDAUDIO_PlayDevice(_THIS) 100{ 101 Android_JNI_WriteAudioBuffer(); 102} 103 104static Uint8 * 105ANDROIDAUDIO_GetDeviceBuf(_THIS) 106{ 107 return Android_JNI_GetAudioBuffer(); 108} 109 110static int 111ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) 112{ 113 return Android_JNI_CaptureAudioBuffer(buffer, buflen); 114} 115 116static void 117ANDROIDAUDIO_FlushCapture(_THIS) 118{ 119 Android_JNI_FlushCapturedAudio(); 120} 121 122static void 123ANDROIDAUDIO_CloseDevice(_THIS) 124{ 125 /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread 126 so it's safe to terminate the Java side buffer and AudioTrack 127 */ 128 Android_JNI_CloseAudioDevice(this->iscapture); 129 if (this->iscapture) { 130 SDL_assert(captureDevice == this); 131 captureDevice = NULL; 132 } else { 133 SDL_assert(audioDevice == this); 134 audioDevice = NULL; 135 } 136 SDL_free(this->hidden); 137} 138 139static int 140ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl) 141{ 142 /* Set the function pointers */ 143 impl->OpenDevice = ANDROIDAUDIO_OpenDevice; 144 impl->PlayDevice = ANDROIDAUDIO_PlayDevice; 145 impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf; 146 impl->CloseDevice = ANDROIDAUDIO_CloseDevice; 147 impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice; 148 impl->FlushCapture = ANDROIDAUDIO_FlushCapture; 149 150 /* and the capabilities */ 151 impl->HasCaptureSupport = SDL_TRUE; 152 impl->OnlyHasDefaultOutputDevice = 1; 153 impl->OnlyHasDefaultCaptureDevice = 1; 154 155 return 1; /* this audio target is available. */ 156} 157 158AudioBootStrap ANDROIDAUDIO_bootstrap = { 159 "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0 160}; 161 162/* Pause (block) all non already paused audio devices by taking their mixer lock */ 163void ANDROIDAUDIO_PauseDevices(void) 164{ 165 /* TODO: Handle multiple devices? */ 166 struct SDL_PrivateAudioData *private; 167 if(audioDevice != NULL && audioDevice->hidden != NULL) { 168 private = (struct SDL_PrivateAudioData *) audioDevice->hidden; 169 if (SDL_AtomicGet(&audioDevice->paused)) { 170 /* The device is already paused, leave it alone */ 171 private->resume = SDL_FALSE; 172 } 173 else { 174 SDL_LockMutex(audioDevice->mixer_lock); 175 SDL_AtomicSet(&audioDevice->paused, 1); 176 private->resume = SDL_TRUE; 177 } 178 } 179 180 if(captureDevice != NULL && captureDevice->hidden != NULL) { 181 private = (struct SDL_PrivateAudioData *) captureDevice->hidden; 182 if (SDL_AtomicGet(&captureDevice->paused)) { 183 /* The device is already paused, leave it alone */ 184 private->resume = SDL_FALSE; 185 } 186 else { 187 SDL_LockMutex(captureDevice->mixer_lock); 188 SDL_AtomicSet(&captureDevice->paused, 1); 189 private->resume = SDL_TRUE; 190 } 191 } 192} 193 194/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */ 195void ANDROIDAUDIO_ResumeDevices(void) 196{ 197 /* TODO: Handle multiple devices? */ 198 struct SDL_PrivateAudioData *private; 199 if(audioDevice != NULL && audioDevice->hidden != NULL) { 200 private = (struct SDL_PrivateAudioData *) audioDevice->hidden; 201 if (private->resume) { 202 SDL_AtomicSet(&audioDevice->paused, 0); 203 private->resume = SDL_FALSE; 204 SDL_UnlockMutex(audioDevice->mixer_lock); 205 } 206 } 207 208 if(captureDevice != NULL && captureDevice->hidden != NULL) { 209 private = (struct SDL_PrivateAudioData *) captureDevice->hidden; 210 if (private->resume) { 211 SDL_AtomicSet(&captureDevice->paused, 0); 212 private->resume = SDL_FALSE; 213 SDL_UnlockMutex(captureDevice->mixer_lock); 214 } 215 } 216} 217 218#else 219 220void ANDROIDAUDIO_ResumeDevices(void) {} 221void ANDROIDAUDIO_PauseDevices(void) {} 222 223#endif /* SDL_AUDIO_DRIVER_ANDROID */ 224 225/* vi: set ts=4 sw=4 expandtab: */ 226 227
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.