summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Lantinga <slouken@libsdl.org>2019-01-12 12:18:44 -0800
committerSam Lantinga <slouken@libsdl.org>2019-01-12 12:18:44 -0800
commit4fe3595c18ca288be44b7761af519b4cfc62a1c8 (patch)
tree59c45799db499d3ec1c58f3f94de1fdfc481dfc3
parent73bf18142bf102a514c520102c6a8b073293fcaa (diff)
downloadsdl-4fe3595c18ca288be44b7761af519b4cfc62a1c8.tar.gz
Initial Android OpenSL ES implementation, contributed by ANTA
-rwxr-xr-xAndroid.mk3
-rw-r--r--include/SDL_config_android.h1
-rw-r--r--src/audio/SDL_audio.c3
-rw-r--r--src/audio/SDL_sysaudio.h1
-rw-r--r--src/audio/openslES/SDL_openslES.c573
-rw-r--r--src/audio/openslES/SDL_openslES.h42
6 files changed, 622 insertions, 1 deletions
diff --git a/Android.mk b/Android.mk
index 2aee63652..0b506320f 100755
--- a/Android.mk
+++ b/Android.mk
@@ -20,6 +20,7 @@ LOCAL_SRC_FILES := \
$(wildcard $(LOCAL_PATH)/src/audio/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \
+ $(wildcard $(LOCAL_PATH)/src/audio/openslES/*.c) \
$(LOCAL_PATH)/src/atomic/SDL_atomic.c.arm \
$(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \
$(wildcard $(LOCAL_PATH)/src/core/android/*.c) \
@@ -69,7 +70,7 @@ LOCAL_CFLAGS += \
LOCAL_CFLAGS += -Wno-unused-parameter -Wno-sign-compare
-LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
+LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
ifeq ($(NDK_DEBUG),1)
cmd-strip :=
diff --git a/include/SDL_config_android.h b/include/SDL_config_android.h
index 9b80f1522..8f5348605 100644
--- a/include/SDL_config_android.h
+++ b/include/SDL_config_android.h
@@ -130,6 +130,7 @@
/* Enable various audio drivers */
#define SDL_AUDIO_DRIVER_ANDROID 1
+#define SDL_AUDIO_DRIVER_OPENSLES 1
#define SDL_AUDIO_DRIVER_DUMMY 1
/* Enable various input drivers */
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 0343052a1..83d3673a0 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -92,6 +92,9 @@ static const AudioBootStrap *const bootstrap[] = {
#if SDL_AUDIO_DRIVER_ANDROID
&ANDROIDAUDIO_bootstrap,
#endif
+#if SDL_AUDIO_DRIVER_OPENSLES
+ &openslES_bootstrap,
+#endif
#if SDL_AUDIO_DRIVER_PSP
&PSPAUDIO_bootstrap,
#endif
diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h
index a001efe05..09a77c967 100644
--- a/src/audio/SDL_sysaudio.h
+++ b/src/audio/SDL_sysaudio.h
@@ -205,6 +205,7 @@ extern AudioBootStrap DISKAUDIO_bootstrap;
extern AudioBootStrap DUMMYAUDIO_bootstrap;
extern AudioBootStrap FUSIONSOUND_bootstrap;
extern AudioBootStrap ANDROIDAUDIO_bootstrap;
+extern AudioBootStrap openslES_bootstrap;
extern AudioBootStrap PSPAUDIO_bootstrap;
extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap;
diff --git a/src/audio/openslES/SDL_openslES.c b/src/audio/openslES/SDL_openslES.c
new file mode 100644
index 000000000..db9f85c21
--- /dev/null
+++ b/src/audio/openslES/SDL_openslES.c
@@ -0,0 +1,573 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_AUDIO_DRIVER_OPENSLES
+
+#include "SDL_audio.h"
+#include "../SDL_audio_c.h"
+#include "SDL_openslES.h"
+
+// for native audio
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+#include <android/log.h>
+
+#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(...)
+#define LOGE(...)
+
+// engine interfaces
+static SLObjectItf engineObject = NULL;
+static SLEngineItf engineEngine;
+
+// output mix interfaces
+static SLObjectItf outputMixObject = 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;
+
+// buffer queue player interfaces
+static SLObjectItf bqPlayerObject = NULL;
+static SLPlayItf bqPlayerPlay;
+static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
+//static SLEffectSendItf bqPlayerEffectSend;
+static SLMuteSoloItf bqPlayerMuteSolo;
+static SLVolumeItf bqPlayerVolume;
+
+// recorder interfaces TODO
+static SLObjectItf recorderObject = NULL;
+static SLRecordItf recorderRecord;
+static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
+
+// pointer and size of the next player buffer to enqueue, and number of remaining buffers
+static short *nextBuffer;
+static unsigned nextSize;
+static int nextCount;
+
+static const char *sldevaudiorecorderstr = "SLES Audio Recorder";
+static const char *sldevaudioplayerstr = "SLES Audio Player";
+
+#define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr
+#define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr
+
+#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, *recsem = NULL;
+
+//static SDL_AudioDevice* audioDevice = NULL;
+
+#if 0
+static void openslES_DetectDevices( int iscapture )
+{
+ LOGI( "openSLES_DetectDevices()" );
+ if ( iscapture )
+ addfn( SLES_DEV_AUDIO_RECORDER );
+ else
+ addfn( SLES_DEV_AUDIO_PLAYER );
+ return;
+}
+#endif
+
+static void openslES_DestroyEngine( void );
+
+static int openslES_CreateEngine( void )
+{
+ SLresult result;
+
+ LOGI( "openSLES_CreateEngine()" );
+
+ // create engine
+ result = slCreateEngine( &engineObject, 0, NULL, 0, NULL, NULL );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "slCreateEngine failed" );
+ goto error;
+ }
+
+ LOGI( "slCreateEngine OK" );
+
+ // realize the engine
+ result = (*engineObject)->Realize( engineObject, SL_BOOLEAN_FALSE );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "RealizeEngine failed" );
+ goto error;
+ }
+
+ LOGI( "RealizeEngine OK" );
+
+ // 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" );
+ goto error;
+ }
+
+ 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 };
+
+ const SLInterfaceID ids[1] = { SL_IID_VOLUME };
+ const SLboolean req[1] = { SL_BOOLEAN_FALSE };
+ result = (*engineEngine)->CreateOutputMix( engineEngine, &outputMixObject, 1, ids, req );
+
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "CreateOutputMix failed" );
+ goto error;
+ }
+ LOGI( "CreateOutputMix OK" );
+
+ // realize the output mix
+ result = (*outputMixObject)->Realize( outputMixObject, SL_BOOLEAN_FALSE );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "RealizeOutputMix failed" );
+ goto error;
+ }
+
+ return 1;
+
+error:;
+ openslES_DestroyEngine( );
+ return 0;
+}
+
+static void openslES_DestroyPCMPlayer( void );
+static void openslES_DestroyPCMRecorder( void );
+
+static void openslES_DestroyEngine( void )
+{
+ LOGI( "openslES_DestroyEngine()" );
+
+ openslES_DestroyPCMPlayer( );
+ openslES_DestroyPCMRecorder( );
+
+ // destroy output mix object, and invalidate all associated interfaces
+ if ( outputMixObject != NULL ) {
+
+ (*outputMixObject)->Destroy( outputMixObject );
+ outputMixObject = NULL;
+// outputMixEnvironmentalReverb = NULL;
+ }
+
+ // destroy engine object, and invalidate all associated interfaces
+ if (engineObject != NULL) {
+
+ (*engineObject)->Destroy( engineObject );
+ engineObject = NULL;
+ engineEngine = NULL;
+ }
+
+ return;
+}
+
+// this callback handler is called every time a buffer finishes playing
+static void bqPlayerCallback( SLAndroidSimpleBufferQueueItf bq, void *context )
+{
+ static int t = 0;
+// assert(bq == bqPlayerBufferQueue);
+// assert(NULL == context);
+
+ // 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
+ 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
+ assert(SL_RESULT_SUCCESS == result);
+ (void)result;
+ }
+#endif
+
+ LOGI( "SLES: Playback Callmeback %u", t++ );
+
+ SDL_SemPost( playsem );
+
+ return;
+}
+
+static int openslES_CreatePCMRecorder( _THIS )
+{
+ LOGE( "openslES_CreatePCMRecorder not implimented yet!" );
+ return SDL_SetError( "openslES_CreatePCMRecorder not implimented yet!" );
+}
+
+static void openslES_DestroyPCMRecorder( void )
+{
+ return;
+}
+
+static int openslES_CreatePCMPlayer( _THIS )
+{
+ SLDataFormat_PCM format_pcm;
+ SDL_AudioFormat test_format;
+ SLresult result;
+ int i;
+
+/*
+ test_format = SDL_FirstAudioFormat( this->spec.format );
+
+ while ( test_format != 0 ) {
+
+ if ( SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format ) ) break;
+ test_format = SDL_NextAudioFormat( );
+ }
+
+ if ( test_format == 0 ) {
+
+ // Didn't find a compatible format :(
+ LOGI( "No compatible audio format!" );
+ return SDL_SetError("No compatible audio format!");
+ }
+
+ this->spec.format = test_format;
+*/
+
+ // 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
+ SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
+// 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.bitsPerSample = SDL_AUDIO_BITSIZE( this->spec.format );
+ format_pcm.containerSize = SDL_AUDIO_BITSIZE( this->spec.format );
+
+ if ( SDL_AUDIO_ISBIGENDIAN( this->spec.format ) )
+ format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
+ else
+ format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+
+/*
+#define SL_SPEAKER_FRONT_LEFT ((SLuint32) 0x00000001)
+#define SL_SPEAKER_FRONT_RIGHT ((SLuint32) 0x00000002)
+#define SL_SPEAKER_FRONT_CENTER ((SLuint32) 0x00000004)
+#define SL_SPEAKER_LOW_FREQUENCY ((SLuint32) 0x00000008)
+#define SL_SPEAKER_BACK_LEFT ((SLuint32) 0x00000010)
+#define SL_SPEAKER_BACK_RIGHT ((SLuint32) 0x00000020)
+#define SL_SPEAKER_FRONT_LEFT_OF_CENTER ((SLuint32) 0x00000040)
+#define SL_SPEAKER_FRONT_RIGHT_OF_CENTER ((SLuint32) 0x00000080)
+#define SL_SPEAKER_BACK_CENTER ((SLuint32) 0x00000100)
+#define SL_SPEAKER_SIDE_LEFT ((SLuint32) 0x00000200)
+#define SL_SPEAKER_SIDE_RIGHT ((SLuint32) 0x00000400)
+#define SL_SPEAKER_TOP_CENTER ((SLuint32) 0x00000800)
+#define SL_SPEAKER_TOP_FRONT_LEFT ((SLuint32) 0x00001000)
+#define SL_SPEAKER_TOP_FRONT_CENTER ((SLuint32) 0x00002000)
+#define SL_SPEAKER_TOP_FRONT_RIGHT ((SLuint32) 0x00004000)
+#define SL_SPEAKER_TOP_BACK_LEFT ((SLuint32) 0x00008000)
+#define SL_SPEAKER_TOP_BACK_CENTER ((SLuint32) 0x00010000)
+#define SL_SPEAKER_TOP_BACK_RIGHT ((SLuint32) 0x00020000)
+*/
+
+ if ( this->spec.channels == 1 )
+ format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
+ else if ( this->spec.channels == 2 )
+ format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+ else if ( this->spec.channels == 3 )
+ format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER;
+ else if ( this->spec.channels == 4 )
+ format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
+ SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT;
+ else
+ format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
+ SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT |
+ SL_SPEAKER_FRONT_CENTER;
+
+ SLDataSource audioSrc = { &loc_bufq, &format_pcm };
+
+ // configure audio sink
+ SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
+ SLDataSink audioSnk = { &loc_outmix, NULL };
+
+ // create audio player
+ const SLInterfaceID ids[2] = {
+ SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+ SL_IID_VOLUME
+ };
+
+ const SLboolean req[2] = {
+ SL_BOOLEAN_TRUE,
+ SL_BOOLEAN_FALSE,
+ };
+
+ result = (*engineEngine)->CreateAudioPlayer( engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
+ 2, ids, req );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "CreateAudioPlayer failed" );
+ goto failed;
+ }
+
+ // realize the player
+ result = (*bqPlayerObject)->Realize( bqPlayerObject, SL_BOOLEAN_FALSE );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "RealizeAudioPlayer failed" );
+ goto failed;
+ }
+
+ // 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
+ 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 );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "RegisterCallback failed" );
+ goto failed;
+ }
+
+#if 0
+ // get the effect send interface
+ result = (*bqPlayerObject)->GetInterface( bqPlayerObject, SL_IID_EFFECTSEND, &bqPlayerEffectSend );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "SL_IID_EFFECTSEND interface get failed" );
+ goto failed;
+ }
+#endif
+
+#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
+ result = (*bqPlayerObject)->GetInterface( bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "SL_IID_VOLUME interface get failed" );
+// goto failed;
+ }
+
+ // set the player's state to playing
+ result = (*bqPlayerPlay)->SetPlayState( bqPlayerPlay, SL_PLAYSTATE_PLAYING );
+ if ( SL_RESULT_SUCCESS != result ) {
+
+ LOGE( "Play set state failed" );
+ goto failed;
+ }
+
+ /* Create the audio buffer semaphore */
+ playsem = SDL_CreateSemaphore( NUM_BUFFERS - 1 );
+ if ( !playsem ) {
+
+ LOGE( "cannot create Semaphore!" );
+ goto failed;
+ }
+
+ /* Create the sound buffers */
+ mixbuff = (Uint8 *) SDL_malloc( NUM_BUFFERS * this->spec.size );
+ if ( mixbuff == NULL) {
+
+ LOGE( "mixbuffer allocate - out of memory" );
+ goto failed;
+ }
+
+ for ( i = 0; i < NUM_BUFFERS; i ++ )
+ pmixbuff[i] = mixbuff + i * this->spec.size;
+
+ return 0;
+
+failed:;
+
+ openslES_DestroyPCMPlayer( );
+
+ return SDL_SetError( "Open device failed!" );
+}
+
+static void openslES_DestroyPCMPlayer( void )
+{
+ // destroy buffer queue audio player object, and invalidate all associated interfaces
+ if ( bqPlayerObject != NULL ) {
+
+ (*bqPlayerObject)->Destroy( bqPlayerObject );
+
+ bqPlayerObject = NULL;
+ bqPlayerPlay = NULL;
+ bqPlayerBufferQueue = NULL;
+// bqPlayerEffectSend = NULL;
+ bqPlayerMuteSolo = NULL;
+ bqPlayerVolume = NULL;
+ }
+
+ if ( playsem ) {
+
+ SDL_DestroySemaphore( playsem );
+ playsem = NULL;
+ }
+
+ if ( mixbuff )
+ SDL_free( mixbuff );
+
+ return;
+}
+
+static int openslES_OpenDevice( _THIS, void *handle, const char *devname, int iscapture )
+{
+ if ( iscapture ) {
+ LOGI( "openslES_OpenDevice( ) %s for capture", devname );
+ return openslES_CreatePCMRecorder( this );
+ }
+
+ LOGI( "openslES_OpenDevice( ) %s for playing", devname );
+
+ return openslES_CreatePCMPlayer( this );
+}
+
+static void openslES_CloseDevice( _THIS )
+{
+ if ( this->iscapture ) {
+ LOGI( "openslES_CloseDevice( ) for capture" );
+ return openslES_DestroyPCMRecorder( );
+ }
+
+ LOGI( "openslES_CloseDevice( ) for playing" );
+ openslES_DestroyPCMPlayer( );
+
+ return;
+}
+
+static void openslES_WaitDevice( _THIS )
+{
+ LOGI( "openslES_WaitDevice( )" );
+
+ /* Wait for an audio chunk to finish */
+// WaitForSingleObject(this->hidden->audio_sem, INFINITE);
+ SDL_SemWait( 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..
+
+
+static Uint8 *openslES_GetDeviceBuf( _THIS )
+{
+ LOGI( "openslES_GetDeviceBuf( )" );
+
+ return pmixbuff[next_buffer];
+}
+
+static void openslES_PlayDevice( _THIS )
+{
+ SLresult result;
+
+ LOGI( "======openslES_PlayDevice( )======" );
+ /* Queue it up */
+
+ result = (*bqPlayerBufferQueue)->Enqueue( bqPlayerBufferQueue, pmixbuff[next_buffer], this->spec.size );
+ if ( SL_RESULT_SUCCESS != result ) {
+ // just puk here
+ // next !
+ }
+
+ next_buffer ++;
+ if ( next_buffer >= NUM_BUFFERS ) next_buffer = 0;
+
+ return;
+}
+
+static int openslES_Init( SDL_AudioDriverImpl * impl )
+{
+ LOGI( "openslES_Init() called" );
+
+ if ( !openslES_CreateEngine() ) return 0;
+
+ LOGI( "openslES_Init() - set pointers" );
+
+ /* Set the function pointers */
+// impl->DetectDevices = openslES_DetectDevices;
+ impl->OpenDevice = openslES_OpenDevice;
+ impl->PlayDevice = openslES_PlayDevice;
+ impl->GetDeviceBuf = openslES_GetDeviceBuf;
+ impl->Deinitialize = openslES_DestroyEngine;
+ impl->WaitDevice = openslES_WaitDevice;
+
+ /* and the capabilities */
+ impl->HasCaptureSupport = 0; /* TODO */
+ impl->OnlyHasDefaultOutputDevice = 1;
+// impl->OnlyHasDefaultInputDevice = 1;
+
+ LOGI( "openslES_Init() - succes" );
+
+ return 1; /* this audio target is available. */
+}
+
+AudioBootStrap openslES_bootstrap = {
+ "openslES", "opensl ES audio driver", openslES_Init, 0
+};
+
+#endif /* SDL_AUDIO_DRIVER_OPENSLES */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/audio/openslES/SDL_openslES.h b/src/audio/openslES/SDL_openslES.h
new file mode 100644
index 000000000..c8f27623f
--- /dev/null
+++ b/src/audio/openslES/SDL_openslES.h
@@ -0,0 +1,42 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef _SDL_openslesaudio_h
+#define _SDL_openslesaudio_h
+
+#include "../SDL_sysaudio.h"
+
+/* Hidden "this" pointer for the audio functions */
+#define _THIS SDL_AudioDevice *this
+
+struct SDL_PrivateAudioData
+{
+ /* The file descriptor for the audio device */
+ Uint8 *mixbuf;
+ Uint32 mixlen;
+ Uint32 write_delay;
+ Uint32 initial_calls;
+};
+
+#endif /* _SDL_openslesaudio_h */
+
+/* vi: set ts=4 sw=4 expandtab: */