diff options
Diffstat (limited to '3rdparty/SDL2')
-rw-r--r-- | 3rdparty/SDL2/src/audio/android/SDL_androidaudio.c | 44 | ||||
-rw-r--r-- | 3rdparty/SDL2/src/audio/android/opensl_io.c | 557 | ||||
-rw-r--r-- | 3rdparty/SDL2/src/audio/android/opensl_io.h | 129 |
3 files changed, 718 insertions, 12 deletions
diff --git a/3rdparty/SDL2/src/audio/android/SDL_androidaudio.c b/3rdparty/SDL2/src/audio/android/SDL_androidaudio.c index 96f6d631ad6..0e60fb0c6f2 100644 --- a/3rdparty/SDL2/src/audio/android/SDL_androidaudio.c +++ b/3rdparty/SDL2/src/audio/android/SDL_androidaudio.c @@ -31,10 +31,13 @@ #include "../../core/android/SDL_android.h" +#include "opensl_io.h" + #include <android/log.h> static SDL_AudioDevice* audioDevice = NULL; static SDL_AudioDevice* captureDevice = NULL; +static OPENSL_STREAM *sl = NULL; static int ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) @@ -57,7 +60,8 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) test_format = SDL_FirstAudioFormat(this->spec.format); while (test_format != 0) { /* no "UNKNOWN" constant */ - if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) { +// if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) { + if (test_format == AUDIO_S16MSB) { this->spec.format = test_format; break; } @@ -75,20 +79,32 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->spec.channels = 1; } + #if 0 if (this->spec.freq < 8000) { this->spec.freq = 8000; } if (this->spec.freq > 48000) { this->spec.freq = 48000; } - + #endif /* TODO: pass in/return a (Java) device ID */ - this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples); - - if (this->spec.samples == 0) { - /* Init failed? */ - return SDL_SetError("Java-side initialization failed!"); - } + //this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples); + if (!sl & !iscapture) + { + if (this->spec.size != 0) + { +// this->spec.samples = this->spec.size / this->spec.channels / 2; + } else { + this->spec.samples = 400; + this->spec.size = this->spec.channels * this->spec.samples; + } + sl = android_OpenAudioDevice(this->spec.freq, this->spec.channels, this->spec.channels, this->spec.samples); + __android_log_print(ANDROID_LOG_INFO, "SDL", "android_OpenAudioDevice: %x, freq=%d, channels=%d, %d samples", (int)sl, this->spec.freq, this->spec.channels, this->spec.samples); + if (!sl) { + /* Init failed? */ + return SDL_SetError("Java-side initialization failed!"); + } + } SDL_CalculateAudioSpec(&this->spec); @@ -98,13 +114,17 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) static void ANDROIDAUDIO_PlayDevice(_THIS) { - Android_JNI_WriteAudioBuffer(); + //Android_JNI_WriteAudioBuffer(); + android_AudioOut2(sl); } static Uint8 * ANDROIDAUDIO_GetDeviceBuf(_THIS) { - return Android_JNI_GetAudioBuffer(); + //return Android_JNI_GetAudioBuffer(); + Uint8 *buf = android_GetDeviceBuffer(sl); +// __android_log_print(ANDROID_LOG_INFO, "SDL", "GetDeviceBuf: %x", (int) buf); + return buf; } static int @@ -148,9 +168,9 @@ ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl) impl->FlushCapture = ANDROIDAUDIO_FlushCapture; /* and the capabilities */ - impl->HasCaptureSupport = SDL_TRUE; + impl->HasCaptureSupport = SDL_FALSE; impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; + impl->OnlyHasDefaultCaptureDevice = 0; return 1; /* this audio target is available. */ } diff --git a/3rdparty/SDL2/src/audio/android/opensl_io.c b/3rdparty/SDL2/src/audio/android/opensl_io.c new file mode 100644 index 00000000000..5e295706b57 --- /dev/null +++ b/3rdparty/SDL2/src/audio/android/opensl_io.c @@ -0,0 +1,557 @@ +/* +opensl_io.c: +Android OpenSL input/output module +Copyright (c) 2012, Victor Lazzarini +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <limits.h> +#include "opensl_io.h" +#define CONV16BIT 32768 +#define CONVMYFLT (1./32768.) + +#include <android/log.h> +#define LOG_TAG "SDL_android" + +static void* createThreadLock(void); +static int waitThreadLock(void *lock); +static void notifyThreadLock(void *lock); +static void destroyThreadLock(void *lock); +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context); +static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context); + +// creates the OpenSL ES audio engine +static SLresult openSLCreateEngine(OPENSL_STREAM *p) +{ + SLresult result; + // create engine + result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); + if(result != SL_RESULT_SUCCESS) goto engine_end; + + // realize the engine + result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); + if(result != SL_RESULT_SUCCESS) goto engine_end; + + // get the engine interface, which is needed in order to create other objects + result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine)); + if(result != SL_RESULT_SUCCESS) goto engine_end; + + engine_end: + return result; +} + +// opens the OpenSL ES device for output +static SLresult openSLPlayOpen(OPENSL_STREAM *p) +{ + SLresult result; + SLuint32 sr = p->sr; + SLuint32 channels = p->outchannels; + + if(channels){ + // configure audio source + SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; + + switch(sr){ + + case 8000: + sr = SL_SAMPLINGRATE_8; + break; + case 11025: + sr = SL_SAMPLINGRATE_11_025; + break; + case 16000: + sr = SL_SAMPLINGRATE_16; + break; + case 22050: + sr = SL_SAMPLINGRATE_22_05; + break; + case 24000: + sr = SL_SAMPLINGRATE_24; + break; + case 32000: + sr = SL_SAMPLINGRATE_32; + break; + case 44100: + sr = SL_SAMPLINGRATE_44_1; + break; + case 48000: + sr = SL_SAMPLINGRATE_48; + break; + case 64000: + sr = SL_SAMPLINGRATE_64; + break; + case 88200: + sr = SL_SAMPLINGRATE_88_2; + break; + case 96000: + sr = SL_SAMPLINGRATE_96; + break; + case 192000: + sr = SL_SAMPLINGRATE_192; + break; + default: + return -1; + } + + const SLInterfaceID ids[] = {SL_IID_VOLUME}; + const SLboolean req[] = {SL_BOOLEAN_FALSE}; + result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req); + if(result != SL_RESULT_SUCCESS) goto end_openaudio; + + // realize the output mix + result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); + + int speakers; + if(channels > 1) + speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + else speakers = SL_SPEAKER_FRONT_CENTER; + SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,channels, sr, + SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, + speakers, SL_BYTEORDER_LITTLEENDIAN}; + + SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + + // configure audio sink + SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject}; + SLDataSink audioSnk = {&loc_outmix, NULL}; + + // create audio player + const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; + const SLboolean req1[] = {SL_BOOLEAN_TRUE}; + result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine, &(p->bqPlayerObject), &audioSrc, &audioSnk, + 1, ids1, req1); + if(result != SL_RESULT_SUCCESS) goto end_openaudio; + + // realize the player + result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE); + if(result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the play interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay)); + if(result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the buffer queue interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &(p->bqPlayerBufferQueue)); + if(result != SL_RESULT_SUCCESS) goto end_openaudio; + + // register callback on the buffer queue + result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p); + if(result != SL_RESULT_SUCCESS) goto end_openaudio; + + // set the player's state to playing + result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING); + + end_openaudio: + return result; + } + return SL_RESULT_SUCCESS; +} + +// Open the OpenSL ES device for input +static SLresult openSLRecOpen(OPENSL_STREAM *p){ + + SLresult result; + SLuint32 sr = p->sr; + SLuint32 channels = p->inchannels; + + if(channels){ + + switch(sr){ + + case 8000: + sr = SL_SAMPLINGRATE_8; + break; + case 11025: + sr = SL_SAMPLINGRATE_11_025; + break; + case 16000: + sr = SL_SAMPLINGRATE_16; + break; + case 22050: + sr = SL_SAMPLINGRATE_22_05; + break; + case 24000: + sr = SL_SAMPLINGRATE_24; + break; + case 32000: + sr = SL_SAMPLINGRATE_32; + break; + case 44100: + sr = SL_SAMPLINGRATE_44_1; + break; + case 48000: + sr = SL_SAMPLINGRATE_48; + break; + case 64000: + sr = SL_SAMPLINGRATE_64; + break; + case 88200: + sr = SL_SAMPLINGRATE_88_2; + break; + case 96000: + sr = SL_SAMPLINGRATE_96; + break; + case 192000: + sr = SL_SAMPLINGRATE_192; + break; + default: + return -1; + } + + // configure audio source + SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, + SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; + SLDataSource audioSrc = {&loc_dev, NULL}; + + // configure audio sink + int speakers; + if(channels > 1) + speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + else speakers = SL_SPEAKER_FRONT_CENTER; + SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; + SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channels, sr, + SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, + speakers, SL_BYTEORDER_LITTLEENDIAN}; + SLDataSink audioSnk = {&loc_bq, &format_pcm}; + + // create audio recorder + // (requires the RECORD_AUDIO permission) + const SLInterfaceID id[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; + const SLboolean req[1] = {SL_BOOLEAN_TRUE}; + result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine, &(p->recorderObject), &audioSrc, + &audioSnk, 1, id, req); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // realize the audio recorder + result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // get the record interface + result = (*p->recorderObject)->GetInterface(p->recorderObject, SL_IID_RECORD, &(p->recorderRecord)); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // get the buffer queue interface + result = (*p->recorderObject)->GetInterface(p->recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &(p->recorderBufferQueue)); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // register callback on the buffer queue + result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue, bqRecorderCallback, + p); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + result = (*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING); + + end_recopen: + return result; + } + else return SL_RESULT_SUCCESS; + + +} + +// close the OpenSL IO and destroy the audio engine +static void openSLDestroyEngine(OPENSL_STREAM *p){ + + // destroy buffer queue audio player object, and invalidate all associated interfaces + if (p->bqPlayerObject != NULL) { + (*p->bqPlayerObject)->Destroy(p->bqPlayerObject); + p->bqPlayerObject = NULL; + p->bqPlayerPlay = NULL; + p->bqPlayerBufferQueue = NULL; + p->bqPlayerEffectSend = NULL; + } + + // destroy audio recorder object, and invalidate all associated interfaces + if (p->recorderObject != NULL) { + (*p->recorderObject)->Destroy(p->recorderObject); + p->recorderObject = NULL; + p->recorderRecord = NULL; + p->recorderBufferQueue = NULL; + } + + // destroy output mix object, and invalidate all associated interfaces + if (p->outputMixObject != NULL) { + (*p->outputMixObject)->Destroy(p->outputMixObject); + p->outputMixObject = NULL; + } + + // destroy engine object, and invalidate all associated interfaces + if (p->engineObject != NULL) { + (*p->engineObject)->Destroy(p->engineObject); + p->engineObject = NULL; + p->engineEngine = NULL; + } + +} + + +// open the android audio device for input and/or output +OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, int bufferframes){ + + OPENSL_STREAM *p; + p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM),1); + + p->inchannels = inchannels; + p->outchannels = outchannels; + p->sr = sr; + p->inlock = createThreadLock(); + p->outlock = createThreadLock(); + + if((p->outBufSamples = bufferframes*outchannels) != 0) { + if((p->outputBuffer[0] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL || + (p->outputBuffer[1] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL) { + android_CloseAudioDevice(p); + return NULL; + } + __android_log_print(ANDROID_LOG_INFO, "OPENSL", "android_OpenAudioDevice: outBufSamples(%d), %x, %x", p->outBufSamples, (int) p->outputBuffer[0], (int) p->outputBuffer[1]); + } + + if((p->inBufSamples = bufferframes*inchannels) != 0){ + if((p->inputBuffer[0] = (short *) calloc(p->inBufSamples, sizeof(short))) == NULL || + (p->inputBuffer[1] = (short *) calloc(p->inBufSamples, sizeof(short))) == NULL){ + android_CloseAudioDevice(p); + return NULL; + } + __android_log_print(ANDROID_LOG_INFO, "OPENSL", "android_OpenAudioDevice: inBufSamples(%d)", p->inBufSamples); + } + + p->currentInputIndex = 0; + p->currentOutputBuffer = 0; + p->currentInputIndex = p->inBufSamples; + p->currentInputBuffer = 0; + + if(openSLCreateEngine(p) != SL_RESULT_SUCCESS) { + android_CloseAudioDevice(p); + return NULL; + } +// __android_log_print(ANDROID_LOG_INFO, "OPENSL", "android_OpenAudioDevice: openSLCreateEngine"); +#if 1 + if(openSLRecOpen(p) != SL_RESULT_SUCCESS) { +// android_CloseAudioDevice(p); +// return NULL; + } +// __android_log_print(ANDROID_LOG_INFO, "OPENSL", "android_OpenAudioDevice: openSLRecOpen"); +#endif + if(openSLPlayOpen(p) != SL_RESULT_SUCCESS) { + android_CloseAudioDevice(p); + return NULL; + } +// __android_log_print(ANDROID_LOG_INFO, "OPENSL", "android_OpenAudioDevice: openSLPlayOpen"); + + notifyThreadLock(p->outlock); + notifyThreadLock(p->inlock); + + p->time = 0.; + return p; +} + +// close the android audio device +void android_CloseAudioDevice(OPENSL_STREAM *p){ + + if (p == NULL) + return; + + openSLDestroyEngine(p); + + if (p->inlock != NULL) { + notifyThreadLock(p->inlock); + destroyThreadLock(p->inlock); + p->inlock = NULL; + } + + if (p->outlock != NULL) { + notifyThreadLock(p->outlock); + destroyThreadLock(p->outlock); + p->inlock = NULL; + } + + if (p->outputBuffer[0] != NULL) { + free(p->outputBuffer[0]); + p->outputBuffer[0] = NULL; + } + + if (p->outputBuffer[1] != NULL) { + free(p->outputBuffer[1]); + p->outputBuffer[1] = NULL; + } + + if (p->inputBuffer[0] != NULL) { + free(p->inputBuffer[0]); + p->inputBuffer[0] = NULL; + } + + if (p->inputBuffer[1] != NULL) { + free(p->inputBuffer[1]); + p->inputBuffer[1] = NULL; + } + + free(p); +} + +// returns timestamp of the processed stream +double android_GetTimestamp(OPENSL_STREAM *p){ + return p->time; +} + + +// this callback handler is called every time a buffer finishes recording +void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +{ + OPENSL_STREAM *p = (OPENSL_STREAM *) context; + notifyThreadLock(p->inlock); +} + +// gets a buffer of size samples from the device +int android_AudioIn(OPENSL_STREAM *p,float *buffer,int size){ + short *inBuffer; + int i, bufsamps = p->inBufSamples, index = p->currentInputIndex; + if(p == NULL || bufsamps == 0) return 0; + + inBuffer = p->inputBuffer[p->currentInputBuffer]; + for(i=0; i < size; i++){ + if (index >= bufsamps) { + waitThreadLock(p->inlock); + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + inBuffer,bufsamps*sizeof(short)); + p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1); + index = 0; + inBuffer = p->inputBuffer[p->currentInputBuffer]; + } + buffer[i] = (float) inBuffer[index++]*CONVMYFLT; + } + p->currentInputIndex = index; + if(p->outchannels == 0) p->time += (double) size/(p->sr*p->inchannels); + return i; +} + +// this callback handler is called every time a buffer finishes playing +void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +{ + OPENSL_STREAM *p = (OPENSL_STREAM *) context; + notifyThreadLock(p->outlock); +} + +unsigned char *android_GetDeviceBuffer(OPENSL_STREAM *p) +{ + p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1); + waitThreadLock(p->outlock); +// __android_log_print(ANDROID_LOG_INFO, "OPENSL", "android_GetDeviceBuffer: buf[%d]=%x", p->currentOutputBuffer, (int) p->outputBuffer[p->currentOutputBuffer]); + return (unsigned char *)p->outputBuffer[p->currentOutputBuffer]; +} + +void android_AudioOut2(OPENSL_STREAM *p) +{ + short *outBuffer = p->outputBuffer[p->currentOutputBuffer]; + int bufsamps = p->outBufSamples; + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, outBuffer, bufsamps*sizeof(short)); +} +// puts a buffer of size samples to the device +int android_AudioOut(OPENSL_STREAM *p, float *buffer, int size){ + + short *outBuffer; + int i, bufsamps = p->outBufSamples, index = p->currentOutputIndex; + if(p == NULL || bufsamps == 0) return 0; + outBuffer = p->outputBuffer[p->currentOutputBuffer]; + + for (i=0; i < size; i++) { + + // clean conversion from float to short int + float x = buffer[i]; + if (x>1.0) { x=1.0; } else if (x<-1.0) { x=-1.0; }; + outBuffer[index++] = (short)( x * 32767.0 ); + + if (index >= p->outBufSamples) { + waitThreadLock(p->outlock); + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, + outBuffer,bufsamps*sizeof(short)); + p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1); + index = 0; + outBuffer = p->outputBuffer[p->currentOutputBuffer]; + } + } + p->currentOutputIndex = index; + p->time += (double) size/(p->sr*p->outchannels); + return i; +} + +//---------------------------------------------------------------------- +// thread Locks +// to ensure synchronisation between callbacks and processing code +void* createThreadLock(void) +{ + threadLock *p; + p = (threadLock*) malloc(sizeof(threadLock)); + if (p == NULL) + return NULL; + memset(p, 0, sizeof(threadLock)); + if (pthread_mutex_init(&(p->m), (pthread_mutexattr_t*) NULL) != 0) { + free((void*) p); + return NULL; + } + if (pthread_cond_init(&(p->c), (pthread_condattr_t*) NULL) != 0) { + pthread_mutex_destroy(&(p->m)); + free((void*) p); + return NULL; + } + p->s = (unsigned char) 1; + + return p; +} + +int waitThreadLock(void *lock) +{ + threadLock *p; + p = (threadLock*) lock; + pthread_mutex_lock(&(p->m)); + while (!p->s) { + pthread_cond_wait(&(p->c), &(p->m)); + } + p->s = (unsigned char) 0; + pthread_mutex_unlock(&(p->m)); + return 0; +} + +void notifyThreadLock(void *lock) +{ + threadLock *p; + p = (threadLock*) lock; + pthread_mutex_lock(&(p->m)); + p->s = (unsigned char) 1; + pthread_cond_signal(&(p->c)); + pthread_mutex_unlock(&(p->m)); +} + +void destroyThreadLock(void *lock) +{ + threadLock *p; + p = (threadLock*) lock; + if (p == NULL) + return; + notifyThreadLock(p); + pthread_cond_destroy(&(p->c)); + pthread_mutex_destroy(&(p->m)); + free(p); +}
\ No newline at end of file diff --git a/3rdparty/SDL2/src/audio/android/opensl_io.h b/3rdparty/SDL2/src/audio/android/opensl_io.h new file mode 100644 index 00000000000..5c04cd2fdd7 --- /dev/null +++ b/3rdparty/SDL2/src/audio/android/opensl_io.h @@ -0,0 +1,129 @@ +/* +opensl_io.c: +Android OpenSL input/output module header +Copyright (c) 2012, Victor Lazzarini +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef OPENSL_IO +#define OPENSL_IO + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> +#include <pthread.h> +#include <stdlib.h> + +typedef struct threadLock_{ + pthread_mutex_t m; + pthread_cond_t c; + unsigned char s; +} threadLock; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct opensl_stream { + + // engine interfaces + SLObjectItf engineObject; + SLEngineItf engineEngine; + + // output mix interfaces + SLObjectItf outputMixObject; + + // buffer queue player interfaces + SLObjectItf bqPlayerObject; + SLPlayItf bqPlayerPlay; + SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; + SLEffectSendItf bqPlayerEffectSend; + + // recorder interfaces + SLObjectItf recorderObject; + SLRecordItf recorderRecord; + SLAndroidSimpleBufferQueueItf recorderBufferQueue; + + // buffer indexes + int currentInputIndex; + int currentOutputIndex; + + // current buffer half (0, 1) + int currentOutputBuffer; + int currentInputBuffer; + + // buffers + short *outputBuffer[2]; + short *inputBuffer[2]; + + // size of buffers + int outBufSamples; + int inBufSamples; + + // locks + void* inlock; + void* outlock; + + double time; + int inchannels; + int outchannels; + int sr; + +} OPENSL_STREAM; + + /* + Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size + in frames. Returns a handle to the OpenSL stream + */ + OPENSL_STREAM* android_OpenAudioDevice(int sr, int inchannels, int outchannels, int bufferframes); + /* + Close the audio device + */ + void android_CloseAudioDevice(OPENSL_STREAM *p); + /* + Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read. + */ + int android_AudioIn(OPENSL_STREAM *p, float *buffer,int size); + /* + Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written. + */ + int android_AudioOut(OPENSL_STREAM *p, float *buffer,int size); + /* + Get the current IO block time in seconds + */ + double android_GetTimestamp(OPENSL_STREAM *p); + /* + Android SDL interface for playing + */ + void android_AudioOut2(OPENSL_STREAM *p); + /* + Android SDL interface for getBuffer + */ + unsigned char *android_GetDeviceBuffer(OPENSL_STREAM *p); + +#ifdef __cplusplus +}; +#endif + +#endif // #ifndef OPENSL_IO
\ No newline at end of file |