From 59c8c7b684467a8180bff4a1ec21ba51a5986145 Mon Sep 17 00:00:00 2001 From: Sylvain Becker Date: Mon, 14 Jan 2019 10:58:57 +0100 Subject: [PATCH] Android/openslES: move a few static variables to SDL_PrivateAudioData structure --- src/audio/openslES/SDL_openslES.c | 230 +++++++++++++++--------------- src/audio/openslES/SDL_openslES.h | 13 +- 2 files changed, 127 insertions(+), 116 deletions(-) diff --git a/src/audio/openslES/SDL_openslES.c b/src/audio/openslES/SDL_openslES.c index d3b0e39ab..02efe1ab9 100644 --- a/src/audio/openslES/SDL_openslES.c +++ b/src/audio/openslES/SDL_openslES.c @@ -26,7 +26,7 @@ #include "../SDL_audio_c.h" #include "SDL_openslES.h" -// for native audio +/* for native audio */ #include #include @@ -34,58 +34,47 @@ #define LOG_TAG "SDL_openslES" -//#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) -//#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) -//#define LOGI(...) do {} while (0) -//#define LOGE(...) do {} while (0) +/*#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) */ +/*#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) */ +/*#define LOGI(...) do {} while (0) */ +/*#define LOGE(...) do {} while (0) */ #define LOGI(...) #define LOGE(...) -// engine interfaces +/* engine interfaces */ static SLObjectItf engineObject = NULL; static SLEngineItf engineEngine; -// output mix interfaces +/* output mix interfaces */ static SLObjectItf outputMixObject = NULL; -//static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL; +// static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL; -// aux effect on the output mix, used by the buffer queue player -// static const SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR; +/* aux effect on the output mix, used by the buffer queue player */ +/* static const SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR; */ -// buffer queue player interfaces +/* buffer queue player interfaces */ static SLObjectItf bqPlayerObject = NULL; static SLPlayItf bqPlayerPlay; static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; -//static SLEffectSendItf bqPlayerEffectSend; +/*static SLEffectSendItf bqPlayerEffectSend; */ static SLMuteSoloItf bqPlayerMuteSolo; static SLVolumeItf bqPlayerVolume; #if 0 -// recorder interfaces TODO +/* recorder interfaces TODO */ static SLObjectItf recorderObject = NULL; static SLRecordItf recorderRecord; static SLAndroidSimpleBufferQueueItf recorderBufferQueue; #endif -// pointer and size of the next player buffer to enqueue, and number of remaining buffers +/* pointer and size of the next player buffer to enqueue, and number of remaining buffers */ #if 0 static short *nextBuffer; static unsigned nextSize; static int nextCount; #endif -#define NUM_BUFFERS 2 /* -- Don't lower this! */ - -static Uint8 *mixbuff = NULL; -static int next_buffer = 0; -static Uint8 *pmixbuff[NUM_BUFFERS]; - -static SDL_sem *playsem = NULL; -#if 0 -static SDL_sem *recsem = NULL; -#endif - -//static SDL_AudioDevice* audioDevice = NULL; +// static SDL_AudioDevice* audioDevice = NULL; #if 0 static const char *sldevaudiorecorderstr = "SLES Audio Recorder"; @@ -104,16 +93,16 @@ static void openslES_DetectDevices( int iscapture ) } #endif -static void openslES_DestroyEngine(void); +static void openslES_DestroyEngine(); static int -openslES_CreateEngine(void) +openslES_CreateEngine() { SLresult result; LOGI("openSLES_CreateEngine()"); - // create engine + /* create engine */ result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); if (SL_RESULT_SUCCESS != result) { LOGE("slCreateEngine failed"); @@ -122,7 +111,7 @@ openslES_CreateEngine(void) LOGI("slCreateEngine OK"); - // realize the engine + /* realize the engine */ result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { LOGE("RealizeEngine failed"); @@ -131,7 +120,7 @@ openslES_CreateEngine(void) LOGI("RealizeEngine OK"); - // get the engine interface, which is needed in order to create other objects + /* get the engine interface, which is needed in order to create other objects */ result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); if (SL_RESULT_SUCCESS != result) { LOGE("EngineGetInterface failed"); @@ -140,9 +129,9 @@ openslES_CreateEngine(void) LOGI("EngineGetInterface OK"); - // create output mix, with environmental reverb specified as a non-required interface - // const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB }; - // const SLboolean req[1] = { SL_BOOLEAN_FALSE }; + /* create output mix, with environmental reverb specified as a non-required interface */ + /* const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB }; */ + /* const SLboolean req[1] = { SL_BOOLEAN_FALSE }; */ const SLInterfaceID ids[1] = { SL_IID_VOLUME }; const SLboolean req[1] = { SL_BOOLEAN_FALSE }; @@ -154,7 +143,7 @@ openslES_CreateEngine(void) } LOGI("CreateOutputMix OK"); - // realize the output mix + /* realize the output mix */ result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { LOGE("RealizeOutputMix failed"); @@ -167,23 +156,24 @@ error: return 0; } -static void openslES_DestroyPCMPlayer(void); -static void openslES_DestroyPCMRecorder(void); +static void openslES_DestroyPCMPlayer(_THIS); +static void openslES_DestroyPCMRecorder(_THIS); -static void openslES_DestroyEngine(void) +static void openslES_DestroyEngine() { LOGI("openslES_DestroyEngine()"); - openslES_DestroyPCMPlayer(); - openslES_DestroyPCMRecorder(); + +// openslES_DestroyPCMPlayer(this); +// openslES_DestroyPCMRecorder(this); - // destroy output mix object, and invalidate all associated interfaces + /* destroy output mix object, and invalidate all associated interfaces */ if (outputMixObject != NULL) { (*outputMixObject)->Destroy(outputMixObject); outputMixObject = NULL; - // outputMixEnvironmentalReverb = NULL; + /* outputMixEnvironmentalReverb = NULL; */ } - // destroy engine object, and invalidate all associated interfaces + /* destroy engine object, and invalidate all associated interfaces */ if (engineObject != NULL) { (*engineObject)->Destroy(engineObject); engineObject = NULL; @@ -193,56 +183,63 @@ static void openslES_DestroyEngine(void) return; } -// this callback handler is called every time a buffer finishes playing +/* this callback handler is called every time a buffer finishes playing */ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) context; static int t = 0; - // assert(bq == bqPlayerBufferQueue); - // assert(NULL == context); + /* assert(bq == bqPlayerBufferQueue); */ + /* assert(NULL == context); */ - // for streaming playback, replace this test by logic to find and fill the next buffer + /* for streaming playback, replace this test by logic to find and fill the next buffer */ #if 0 if (--nextCount > 0 && NULL != nextBuffer && 0 != nextSize) { SLresult result; - // enqueue another buffer + /* enqueue another buffer */ result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize); - // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, - // which for this code example would indicate a programming error + /* the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, */ + /* which for this code example would indicate a programming error */ assert(SL_RESULT_SUCCESS == result); (void) result; } #endif LOGI("SLES: Playback Callmeback %u", t++); - SDL_SemPost(playsem); + SDL_SemPost(audiodata->playsem); return; } static int openslES_CreatePCMRecorder(_THIS) { +/* struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; */ + LOGE("openslES_CreatePCMRecorder not implimented yet!"); return SDL_SetError("openslES_CreatePCMRecorder not implimented yet!"); } static void -openslES_DestroyPCMRecorder(void) +openslES_DestroyPCMRecorder(_THIS) { +/* struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; */ + return; } static int openslES_CreatePCMPlayer(_THIS) { + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; + SLDataFormat_PCM format_pcm; SLresult result; int i; - /* +#if 0 SDL_AudioFormat test_format; test_format = SDL_FirstAudioFormat( this->spec.format ); @@ -255,28 +252,28 @@ openslES_CreatePCMPlayer(_THIS) } if ( test_format == 0 ) { - // Didn't find a compatible format : + /* Didn't find a compatible format : */ LOGI( "No compatible audio format!" ); return SDL_SetError("No compatible audio format!"); } this->spec.format = test_format; - */ +#endif - // Update the fragment size as size in bytes + /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); LOGI("Try to open %u hz %u bit chan %u %s samples %u", this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format), this->spec.channels, (test_format & 0x1000) ? "BE" : "LE", this->spec.samples); - // configure audio source + /* configure audio source */ SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 }; - // SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, OPENSLES_BUFFERS }; + /* SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, OPENSLES_BUFFERS }; */ format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = this->spec.channels; - format_pcm.samplesPerSec = this->spec.freq * 1000; // / kilo Hz to milli Hz + format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */ format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format); @@ -323,11 +320,11 @@ openslES_CreatePCMPlayer(_THIS) SLDataSource audioSrc = { &loc_bufq, &format_pcm }; - // configure audio sink + /* configure audio sink */ SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject }; SLDataSink audioSnk = { &loc_outmix, NULL }; - // create audio player + /* create audio player */ const SLInterfaceID ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME @@ -344,36 +341,37 @@ openslES_CreatePCMPlayer(_THIS) goto failed; } - // realize the player + /* realize the player */ result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { LOGE("RealizeAudioPlayer failed"); goto failed; } - // get the play interface + /* get the play interface */ result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_PLAY interface get failed"); goto failed; } - // get the buffer queue interface + /* get the buffer queue interface */ result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bqPlayerBufferQueue); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_BUFFERQUEUE interface get failed"); goto failed; } - // register callback on the buffer queue - result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL); + /* register callback on the buffer queue */ + /* context is '(SDL_PrivateAudioData *)this->hidden' */ + result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, this->hidden); if (SL_RESULT_SUCCESS != result) { LOGE("RegisterCallback failed"); goto failed; } #if 0 - // get the effect send interface + /* get the effect send interface */ result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND, &bqPlayerEffectSend); if (SL_RESULT_SUCCESS != result) { @@ -383,21 +381,21 @@ openslES_CreatePCMPlayer(_THIS) } #endif -#if 0 // mute/solo is not supported for sources that are known to be mono, as this is - // get the mute/solo interface +#if 0 /* mute/solo is not supported for sources that are known to be mono, as this is */ + /* get the mute/solo interface */ result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo); assert(SL_RESULT_SUCCESS == result); (void) result; #endif - // get the volume interface + /* get the volume interface */ result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume); if (SL_RESULT_SUCCESS != result) { LOGE("SL_IID_VOLUME interface get failed"); - // goto failed; + /* goto failed; */ } - // set the player's state to playing + /* set the player's state to playing */ result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); if (SL_RESULT_SUCCESS != result) { LOGE("Play set state failed"); @@ -405,36 +403,38 @@ openslES_CreatePCMPlayer(_THIS) } /* Create the audio buffer semaphore */ - playsem = SDL_CreateSemaphore(NUM_BUFFERS - 1); - if (!playsem) { + audiodata->playsem = SDL_CreateSemaphore(NUM_BUFFERS - 1); + if (!audiodata->playsem) { LOGE("cannot create Semaphore!"); goto failed; } /* Create the sound buffers */ - mixbuff = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); - if (mixbuff == NULL) { + audiodata->mixbuff = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); + if (audiodata->mixbuff == NULL) { LOGE("mixbuffer allocate - out of memory"); goto failed; } for (i = 0; i < NUM_BUFFERS; i++) { - pmixbuff[i] = mixbuff + i * this->spec.size; + audiodata->pmixbuff[i] = audiodata->mixbuff + i * this->spec.size; } return 0; failed: - openslES_DestroyPCMPlayer(); + openslES_DestroyPCMPlayer(this); return SDL_SetError("Open device failed!"); } static void -openslES_DestroyPCMPlayer(void) +openslES_DestroyPCMPlayer(_THIS) { - // destroy buffer queue audio player object, and invalidate all associated interfaces + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; + + /* destroy buffer queue audio player object, and invalidate all associated interfaces */ if (bqPlayerObject != NULL) { (*bqPlayerObject)->Destroy(bqPlayerObject); @@ -442,18 +442,18 @@ openslES_DestroyPCMPlayer(void) bqPlayerObject = NULL; bqPlayerPlay = NULL; bqPlayerBufferQueue = NULL; - // bqPlayerEffectSend = NULL; + /* bqPlayerEffectSend = NULL; */ bqPlayerMuteSolo = NULL; bqPlayerVolume = NULL; } - if (playsem) { - SDL_DestroySemaphore(playsem); - playsem = NULL; + if (audiodata->playsem) { + SDL_DestroySemaphore(audiodata->playsem); + audiodata->playsem = NULL; } - if (mixbuff) { - SDL_free(mixbuff); + if (audiodata->mixbuff) { + SDL_free(audiodata->mixbuff); } return; @@ -479,15 +479,16 @@ openslES_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) static void openslES_CloseDevice(_THIS) { + /* struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; */ + if (this->iscapture) { LOGI("openslES_CloseDevice( ) for capture"); - openslES_DestroyPCMRecorder(); + openslES_DestroyPCMRecorder(this); } else { LOGI("openslES_CloseDevice( ) for playing"); - SDL_Log("openslES_CloseDevice( ) for playing"); - openslES_DestroyPCMPlayer(); + openslES_DestroyPCMPlayer(this); } - + SDL_free(this->hidden); return; @@ -496,51 +497,56 @@ openslES_CloseDevice(_THIS) static void openslES_WaitDevice(_THIS) { + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; + LOGI("openslES_WaitDevice( )"); /* Wait for an audio chunk to finish */ - // WaitForSingleObject(this->hidden->audio_sem, INFINITE); - SDL_SemWait(playsem); + /* WaitForSingleObject(this->hidden->audio_sem, INFINITE); */ + SDL_SemWait(audiodata->playsem); return; } -/// n playn sem -// getbuf 0 - 1 -// fill buff 0 - 1 -// play 0 - 0 1 -// wait 1 0 0 -// getbuf 1 0 0 -// fill buff 1 0 0 -// play 0 0 0 -// wait -// -// okay.. +/*/ n playn sem */ +/* getbuf 0 - 1 */ +/* fill buff 0 - 1 */ +/* play 0 - 0 1 */ +/* wait 1 0 0 */ +/* getbuf 1 0 0 */ +/* fill buff 1 0 0 */ +/* play 0 0 0 */ +/* wait */ +/* */ +/* okay.. */ static Uint8 * openslES_GetDeviceBuf(_THIS) { + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; + LOGI("openslES_GetDeviceBuf( )"); - return pmixbuff[next_buffer]; + return audiodata->pmixbuff[audiodata->next_buffer]; } static void openslES_PlayDevice(_THIS) { + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) this->hidden; SLresult result; LOGI("======openslES_PlayDevice( )======"); /* Queue it up */ - result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, pmixbuff[next_buffer], this->spec.size); + result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], this->spec.size); if (SL_RESULT_SUCCESS != result) { - // just puk here - // next ! + /* just puk here */ + /* next ! */ } - next_buffer++; - if (next_buffer >= NUM_BUFFERS) { - next_buffer = 0; + audiodata->next_buffer++; + if (audiodata->next_buffer >= NUM_BUFFERS) { + audiodata->next_buffer = 0; } return; @@ -558,7 +564,7 @@ openslES_Init(SDL_AudioDriverImpl * impl) LOGI("openslES_Init() - set pointers"); /* Set the function pointers */ - // impl->DetectDevices = openslES_DetectDevices; + /* impl->DetectDevices = openslES_DetectDevices; */ impl->OpenDevice = openslES_OpenDevice; impl->CloseDevice = openslES_CloseDevice; impl->PlayDevice = openslES_PlayDevice; @@ -569,7 +575,7 @@ openslES_Init(SDL_AudioDriverImpl * impl) /* and the capabilities */ impl->HasCaptureSupport = 0; /* TODO */ impl->OnlyHasDefaultOutputDevice = 1; - // impl->OnlyHasDefaultInputDevice = 1; + /* impl->OnlyHasDefaultInputDevice = 1; */ LOGI("openslES_Init() - succes"); diff --git a/src/audio/openslES/SDL_openslES.h b/src/audio/openslES/SDL_openslES.h index c8f27623f..8ed2804a3 100644 --- a/src/audio/openslES/SDL_openslES.h +++ b/src/audio/openslES/SDL_openslES.h @@ -28,13 +28,18 @@ /* Hidden "this" pointer for the audio functions */ #define _THIS SDL_AudioDevice *this +#define NUM_BUFFERS 2 /* -- Don't lower this! */ + struct SDL_PrivateAudioData { /* The file descriptor for the audio device */ - Uint8 *mixbuf; - Uint32 mixlen; - Uint32 write_delay; - Uint32 initial_calls; + Uint8 *mixbuff; + int next_buffer; + Uint8 *pmixbuff[NUM_BUFFERS]; + SDL_sem *playsem; +#if 0 + SDL_sem *recsem; +#endif }; #endif /* _SDL_openslesaudio_h */