Initial Android OpenSL ES implementation, contributed by ANTA
diff --git a/Android.mk b/Android.mk
index 2aee636..0b50632 100755
--- a/Android.mk
+++ b/Android.mk
@@ -20,6 +20,7 @@
 	$(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 += -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 9b80f15..8f53486 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 0343052..83d3673 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -92,6 +92,9 @@
 #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 a001efe..09a77c9 100644
--- a/src/audio/SDL_sysaudio.h
+++ b/src/audio/SDL_sysaudio.h
@@ -205,6 +205,7 @@
 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 0000000..db9f85c
--- /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 0000000..c8f2762
--- /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: */